|
|
VSFTP.conf
加入- chroot_local_user=YES
- allow_writeable_chroot=YES
複製代碼
這兩行後,檔案無法寫入了
在安全機制下,chroot 監獄的「根目錄」本身是絕對不能有寫入權限的。如果你加入了 allow_writeable_chroot=YES 卻仍然無法寫入,通常是因為 AlmaLinux 9 嚴格的 SELinux 安全政策 或者是目錄本身的擁有者權限(Permission) 在阻擋。
請依照以下標準步驟進行排查與修正,就能順利寫入:
第一步:檢查與調整目錄權限(標準做法)
雖然 allow_writeable_chroot=YES 允許了可寫入的 chroot,但最佳且最穩定的實作方式,是在使用者的家目錄底下另外建立一個子目錄來專門儲存上傳的檔案。
假設你的 FTP 使用者叫做 ftpuser,家目錄是 /home/ftpuser:
- # 1. 將家目錄(根目錄)本身改為不可寫入(安全規範)
- sudo chmod a-w /home/ftpuser
- # 2. 在家目錄底下建立一個專門上傳的子目錄(例如 www 或 upload)
- sudo mkdir /home/ftpuser/upload# 3. 將這個子目錄的權限完全交給該 FTP 使用者
- sudo chown ftpuser:ftpuser /home/ftpuser/upload
- sudo chmod 755 /home/ftpuser/upload
複製代碼
這樣做之後,使用者連線進來會看到 /upload 資料夾,並可以自由在 /upload 裡面上傳、下載與寫入檔案。
第二步:設定 AlmaLinux 9 的 SELinux 權限(最常遺漏的核心原因)
AlmaLinux 9 預設開啟了極為嚴格的 SELinux 保護機制。如果 SELinux 沒有允許 FTP 寫入,即使你設定檔怎麼改、chmod 777 設得再開,系統依然會直接拒絕寫入。
請在終端機執行以下指令,放行 FTP 的寫入權限:
- # 1. 允許 VSFTPD 讀寫使用者的家目錄
- sudo setsebool -P ftp_home_dir 1
- # 2. 允許 FTP 進行全域寫入
- sudo setsebool -P ftpd_full_access 1
複製代碼
第三步:確認 /etc/vsftpd/vsftpd.conf 的核心寫入開關
請確保你的 vsftpd.conf 設定檔中,除了那兩行之外,全域的寫入功能是有被打開的:
- # 確保這兩行沒有被 # 註解掉
- local_enable=YES
- write_enable=YES
- # 你的兩行
- chroot_local_user=YES
- allow_writeable_chroot=YES
複製代碼
修改完成後,請務必重啟 VSFTPD 服務:
- sudo systemctl restart vsftpd
複製代碼
檢查網頁目錄的「擁有者(Owner)」是誰
很多時候,Discuz! 的網頁目錄(例如 /var/www/html)擁有者被設成了 apache,但你登入 FTP 的帳號(例如 ftpuser)跟 apache 是不同的使用者,因此被系統拒絕寫入。
請執行以下指令,查看你的網頁目錄擁有者:
(請將路徑換成你實際的網頁根目錄)
- 如果看到的是 drwxr-xr-x 1 root root 或 apache apache:
這代表你的 FTP 帳號(ftpuser)根本沒有這個目錄的寫入權限! - 黃金解決方案(將 FTP 帳號加入 Apache 同一個群組):
假設你的 FTP 帳號叫 ftpuser,我們可以把目錄擁有者改為 FTP 帳號,群組改為 Apache,並讓兩者都能讀寫:bash
- # 1. 變更目錄擁有者為你的 FTP 帳號
- sudo chown -R ftpuser:apache /var/www/html
- # 2. 賦予適當的權限(擁有者可讀寫,群組可讀寫)
- sudo chmod -R 775 /var/www/html
複製代碼
第一步:檢查你目前登入的「路徑」與「權限」
請在 PuTTY 中輸入以下指令(請將 ftpuser 替換為你的 FTP 帳號名稱):
# 查看該 FTP 使用者的家目錄路徑是什麼eval echo "~ftpuser"# 查看這個目錄的擁有者是誰,以及權限是什麼(請把路徑換成上面查到的路徑,例如 /home/ftpuser)
第一步:修正網頁目錄的擁有者(Owner)
我們必須把 web 資料夾及其底下的所有檔案、子目錄的擁有者,通通改回你的 FTP 帳號 www,並且群組交給網頁伺服器(通常是 apache 或 www)。
請在 PuTTY 執行以下指令:
- # 將 /home/www/web/ 底下所有檔案的擁有者改為 www,群組改為 apache (或 www)
- sudo chown -R www:apache /home/www/web/
- # 如果你的網頁伺服器群組是 www,也可以改用這行:
- # sudo chown -R www:www /home/home/www/web/
複製代碼
第二步:賦予正確的讀寫權限
確保 www 帳號對該網頁目錄擁有完整的讀寫權限:
- # 賦予目錄 775 權限(擁有者和群組皆可讀寫)
- sudo chmod -R 775 /home/www/web/
複製代碼
第三步:修正 AlmaLinux 9 的 SELinux 標籤(保險起見)
因為這個目錄搬到了 /home/www/web/,我們必須告訴 AlmaLinux 9 的安全系統,這個目錄同時允許網頁讀取與 FTP 讀寫
- # 修正該目錄的 SELinux 標籤,允許 FTP 與網頁處理
- sudo chcon -R -t public_content_rw_t /home/www/web/
- sudo semanage fcontext -a -t public_content_rw_t "/home/www/web(/.*)?" 2>/dev/null
- # 讓網頁伺服器也能正常讀寫(Discuz! 上傳附件需要)
- sudo setsebool -P httpd_builtin_scripting 1 2>/dev/null
- sudo setsebool -P ftp_home_dir 1
複製代碼
🧪 重新測試
做完上述三個步驟後,完全不需要重啟 VSFTPD。請直接回到 FileZilla:
- 點進去 web 資料夾。
- 再次嘗試上傳 XXX.txt。
- 這次絕對就能順利上傳成功了
要讓 FTP 既能上傳,Apache(Discuz! 論壇)也能上傳,我們必須利用 Linux 的群組機制將兩者綁在一起。請在 PuTTY 依序執行以下 4 個步驟修正:
🛠️ 1. 將 apache 使用者加入 www 群組
我們要讓網頁伺服器(apache)繼承 www 群組的權限:
- sudo usermod -a -G www apache
複製代碼
🔓 2. 設定「群組共享」讀寫權限(775)
我們要告訴系統,這個目錄除了擁有者 www 以外,只要是同群組的人(現在包含了 apache)也通通允許讀寫。
- # 讓目錄與底下所有檔案,擁有者和群組都能讀寫
- sudo chmod -R 775 /home/www/web/
- # 設定「SGID 特殊權限」,確保未來不論是 FTP 還是 Apache 新建的檔案,都會自動繼承 www 群組
- sudo chmod -R g+s /home/www/web/
複製代碼
⚙️ 3. 調整 VSFTPD 的 local_umask 設定
預設情況下,透過 FTP 上傳新檔案時,VSFTPD 會把檔案權限鎖死,導致 Apache 看得到卻不能動。我們要修改 VSFTPD 的遮罩,讓 FTP 上傳的檔案預設就允許群組讀寫。
打開 vsftpd.conf:bash
- sudo nano /etc/vsftpd/vsftpd.conf
複製代碼
搜尋 local_umask,將它改為 002(如果前面有 # 請刪除):ini
儲存離開(Ctrl+O -> Enter -> Ctrl+X)並重啟 FTP:bash
- sudo systemctl restart vsftpd
複製代碼
🛡️ 4. 開啟 SELinux 的網頁寫入開關(AlmaLinux 9 必做)
AlmaLinux 9 的安全機制極其嚴格,除了 Linux 檔案權限外,必須手動放行 Apache 對家目錄(/home)檔案的寫入權,否則會被直接丟包。
- sudo setsebool -P httpd_enable_homedirs 1
- sudo setsebool -P httpd_unified 1
複製代碼
|
|