為什麼要設置專用用戶運行 Web 服務?
安全性:避免以 root 權限運行 Nginx/Apache/PHP-FPM,一旦應用層被攻破(如文件上傳漏洞、RCE),攻擊者僅獲得 www 低權限用戶,無法直接控制系統核心。
隔離性:多站點可分配不同用戶/組,配合 PHP-FPM Pool 實現帳號級隔離。
標準權限設置命令序列
# 1. 創建專用用戶/組 (若不存在)
groupadd www
useradd -g www -s /sbin/nologin -M www
# 2. 修改網站根目錄擁有者 (遞歸)
chown -R www:www /data/wwwroot/
# 3. 設置目錄權限 755 (rwxr-xr-x) - 目錄需執行權限才能進入/遍歷
find /data/wwwroot/ -type d -exec chmod 755 {} \;
# 4. 設置文件權限 644 (rw-r--r--) - 文件無需執行權限
find /data/wwwroot/ -type f -exec chmod 644 {} \;
權限數值含義解析
| 權限 | 二進制 | 擁有者 | 組 | 其他人 | 適用對象 |
| 755 | 111 101 101 | 讀寫執行 | 讀執行 | 讀執行 | 目錄 |
| 644 | 110 100 100 | 讀寫 | 讀 | 讀 | 文件 |
| 600 | 110 000 000 | 讀寫 | 無 | 無 | 敏感配置 (如 .env, config.php) |
| 700 | 111 000 000 | 讀寫執行 | 無 | 無 | 私有腳本/憑證目錄 |
特殊場景處理
1. 用戶上傳目錄 (需寫入權限)
# 僅授予上傳目錄寫權限,其他保持 644/755
chown -R www:www /data/wwwroot/uploads
find /data/wwwroot/uploads -type d -exec chmod 775 {} \;
find /data/wwwroot/uploads -type f -exec chmod 664 {} \;
# 或設置 ACL 精確控制
setfacl -R -m u:www:rwx /data/wwwroot/uploads
setfacl -R -d -m u:www:rwx /data/wwwroot/uploads # 默認 ACL 繼承
2. 緩存/日誌目錄 (PHP-FPM/Nginx 需寫入)
chown -R www:www /data/wwwroot/var/cache /data/wwwroot/var/log
chmod 775 /data/wwwroot/var/cache /data/wwwroot/var/log
3. 禁用腳本執行權限 (防 webshell)
# 上傳目錄、緩存目錄禁止腳本執行
# Nginx 配置:
location /uploads/ {
location ~ \.php$ { deny all; return 403; }
}
location /var/cache/ {
location ~ \.php$ { deny all; return 403; }
}
Nginx 執行 PHP 時的權限流程
- Nginx Master 進程 (root) 讀取配置、綁定端口。
- Nginx Worker 進程 (
www) 接收請求、讀取靜態文件 (需目錄 +x、文件 +r)。
- 請求 .php → Worker 通過 FastCGI 轉發給 PHP-FPM。
- PHP-FPM Master (root) 管理進程池,Worker (
www) 讀取/執行 PHP 腳本 (需文件 +r,目錄 +x)。
- PHP 腳本執行邏輯,可能讀寫上傳/緩存目錄 (需對應目錄 +w)。
- 結果經 FastCGI 返回 Nginx → 發送給客戶端。
全鏈路核心:目錄必須有執行權限 (+x) 才能遍歷進入,文件讀取需 +r,寫入需 +w。
自動化腳本模板 (部署時執行)
#!/bin/bash
WEB_ROOT="/data/wwwroot"
WEB_USER="www"
WEB_GROUP="www"
chown -R ${WEB_USER}:${WEB_GROUP} ${WEB_ROOT}
find ${WEB_ROOT} -type d -exec chmod 755 {} \;
find ${WEB_ROOT} -type f -exec chmod 644 {} \;
# 敏感文件收權
find ${WEB_ROOT} -name ".env" -o -name "config*.php" -o -name "*.pem" -o -name "*.key" | xargs -r chmod 600
echo "權限設置完成: ${WEB_ROOT} -> ${WEB_USER}:${WEB_GROUP} (dir 755, file 644)"