open_basedir 是 PHP 核心安全配置,限制腳本只能訪問指定目錄樹下的文件,有效防止目錄遍歷攻擊、敏感文件讀取 (如 /etc/passwd)。本文詳細對比 Nginx FastCGI 參數傳遞、PHP-FPM 池配置、.user.ini 文件三種設置方式的優劣、生效機制、遞歸繼承規則,並給出生產環境推薦配置模板。
[HOST=]、[PATH=] 區塊、.user.ini)# 1. 編輯 Nginx 站點配置 (或公共 fastcgi.conf)
fastcgi_param PHP_VALUE "open_basedir=/home/www/example.com:/tmp/:/proc/";
# 2. 多站點差異化: 在站點 server 塊中覆蓋
server {
listen 80;
server_name site1.com;
root /home/www/site1.com;
location ~ \.php$ {
include fastcgi_params;
fastcgi_param PHP_VALUE "open_basedir=/home/www/site1.com:/tmp/:/proc/";
fastcgi_pass php_backend;
}
}
server {
listen 80;
server_name site2.com;
root /home/www/site2.com;
location ~ \.php$ {
include fastcgi_params;
fastcgi_param PHP_VALUE "open_basedir=/home/www/site2.com:/tmp/:/proc/:/home/www/shared_lib/";
fastcgi_pass php_backend;
}
}
# 3. 重載生效
nginx -t && nginx -s reload
優點:配置集中在 Nginx,版本控制友好,站點隔離清晰。
缺點:需 reload Nginx;若 PHP-FPM 重用進程,舊進程可能殘留舊值 (PHP 7.0+ 已修復此 Bug)。
; /usr/local/php/etc/php-fpm.d/www.conf
[www]
user = www
group = www
listen = /run/php/php8.2-fpm.sock
; 方式 A: php_admin_value (不可被 ini_set 覆蓋, 推薦)
php_admin_value[open_basedir] = /home/www/site1.com:/tmp/:/proc/
; 方式 B: php_value (可被腳本 ini_set 覆蓋, 不推薦安全場景)
; php_value[open_basedir] = /home/www/site1.com:/tmp/:/proc/
; 多站點隔離: 建立多個 pool
[site1]
listen = /run/php/site1.sock
php_admin_value[open_basedir] = /home/www/site1.com:/tmp/:/proc/
[site2]
listen = /run/php/site2.sock
php_admin_value[open_basedir] = /home/www/site2.com:/tmp/:/proc/:/home/www/shared_lib/
優點:進程級隔離,配合多池實現硬隔離。
缺點:需重啟 PHP-FPM (systemctl reload php-fpm);池過多消耗內存。
# 1. 在網站根目錄創建
echo 'open_basedir = /home/www/example.com:/tmp/:/proc/' > /home/www/example.com/.user.ini
# 2. 子目錄可覆蓋/擴展 (遞歸向上查找最近的 .user.ini)
# /home/www/example.com/api/.user.ini
open_basedir = /home/www/example.com:/tmp/:/proc/:/home/www/api_lib/
# 3. 設置不可寫屬性防篡改 (關鍵安全步驟)
chattr +i /home/www/example.com/.user.ini
# 取消: chattr -i /home/www/example.com/.user.ini
生效機制:PHP 處理請求時,從腳本所在目錄向上遞歸查找 .user.ini,合併解析 (類似 .htaccess)。
掃描間隔:由 user_ini.filename (默認 .user.ini) 和 user_ini.cache_ttl (默認 300 秒) 控制。修改後最多 5 分鐘生效,或重啟 PHP-FPM 立即生效。
| 維度 | Nginx FastCGI_PARAM | PHP-FPM Pool php_admin_value | .user.ini |
|---|---|---|---|
| 生效速度 | Nginx reload (秒級) | PHP-FPM reload (秒級) | ≤ user_ini.cache_ttl (默認 300s) |
| 隔離粒度 | 站點級 (server 塊) | 進程池級 (pool) | 目錄級 (遞歸) |
| 版本控制 | 優 (Nginx 配置文件) | 中 (FPM 配置文件) | 優 (隨代碼部署) |
| 運維便利性 | 集中管理 | 需管理多池 | 開發自主可控 |
| 安全性 (防繞過) | 中 (進程複用風險) | 高 (php_admin_value 不可覆蓋) | 高 (chattr +i 防篡改) |
| 推薦場景 | 標準化部署、統一運維團隊 | 高安全隔離要求、多租戶 | 開發主導、頻繁調整、CI/CD 部署 |
# 1. Nginx 統一基礎安全參數 (fastcgi_params 或 fastcgi.conf)
fastcgi_param PHP_VALUE "open_basedir=\$document_root:/tmp/:/proc/";
fastcgi_param PHP_ADMIN_VALUE "disable_functions=exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,pcntl_exec,pcntl_fork,pcntl_signal,pcntl_waitpid,pcntl_wexitstatus,pcntl_wifexited,pcntl_wifsignaled,pcntl_wifstopped,pcntl_wtermsig,ld,dl,pfsockopen,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,fsockopen,chdir,chroot,chgrp,chown,ini_alter,ini_restore";
# 2. 關鍵站點單獨 .user.ini 精細控制 (開發團隊維護)
# /home/www/payment/.user.ini
open_basedir = /home/www/payment:/tmp/:/proc/:/home/www/payment_lib/
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,...
# 3. 關鍵站點獨立 PHP-FPM Pool (運維團隊維護)
# /usr/local/php/etc/php-fpm.d/payment.conf
[payment]
listen = /run/php/payment.sock
user = www_payment
group = www_payment
php_admin_value[open_basedir] = /home/www/payment:/tmp/:/proc/:/home/www/payment_lib/
php_admin_value[disable_functions] = exec,passthru,shell_exec,system,proc_open,popen,...
php_admin_value[memory_limit] = 128M
pm.max_children = 50
配合 open_basedir 形成纵深防御:
disable_functions =
pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,
eval,assert,
passthru,exec,system,shell_exec,proc_open,proc_get_status,proc_close,proc_nice,proc_terminate,
popen,pclose,
pcntl_fork,pcntl_waitpid,
ld,dl,
pfsockopen,fsockopen,stream_socket_server,stream_socket_client,
openlog,syslog,
readlink,symlink,link,unlink,
chroot,chdir,chgrp,chown,chmod,
ini_alter,ini_restore,ini_set,
putenv,getenv,
apache_setenv,apache_getenv,
header,headers_list,headers_sent,
set_time_limit,max_execution_time,
gc_enable,gc_disable,gc_collect_cycles
通過「Nginx 統一基線 + .user.ini 目錄級微調 + 關鍵業務獨立池」三層聯動,構建纵深防御體系,將 PHP 應用安全風險降至最低。