當下Nginx越發流行,寶塔面板、Oneinstack、LNMP等集成環境大多數都使用Nginx作為WEB服務,Nginx + PHP情況下使用FPM(FastCGI 進程管理器)來執行PHP,這篇教程拋開PHP程序寫法不嚴謹造成的本身漏洞,僅從WEB服務和PHP本身設置來加強PHP程序安全。
禁用危險函數
PHP提供的system()等函數可以直接執行系統命令,如果程序限制不嚴謹或寫法不規范,被駭客利用是非常危險的,禁用此類較為危險的函數非常有必要。需要修改php.ini,添加如下內容:
disable_functions = passthru,exec,system,chroot,chgrp,chown,shell_exec,proc_open,proc_get_status,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,fsocket,popen
防止跨站攻擊
跨站攻擊通常表現為A網站被黑之后,駭客利用腳本再次訪問B網站或其它目錄,最終可能導致所有網站全部淪陷。
open_basedir 參數將php所能打開的文件限制在指定的目錄樹中,包括文件本身。當程序要使用例如fopen()或file_get_contents()打開一個文件時,這個文件的位置將會被檢查。當文件在指定的目錄樹之外,程序將拒絕打開。open_basedir設置的方法比較多,這里列出幾個常用的。
php.ini設置
可以直接修改php.ini直接加入
open_basedir="指定目錄"
從PHP腳本上設置
在程序腳本上限制:
ini_set('open_basedir', '指定目錄');
通過.user.ini 進行設置
先來看看官方具體是如何解釋.user.ini這個文件的:
自 PHP 5.3.0 起,PHP 支持基于每個目錄的 .htaccess 風格的 INI 文件。此類文件僅被 CGI/FastCGI SAPI 處理。此功能使得 PECL 的 htscanner 擴展作廢。如果使用 Apache,則用 .htaccess 文件有同樣效果。
除了主 php.ini 之外,PHP 還會在每個目錄下掃描 INI 文件,從被執行的 PHP 文件所在目錄開始一直上升到 web 根目錄($_SERVER['DOCUMENT_ROOT'] 所指定的)。如果被執行的 PHP 文件在 web 根目錄之外,則只掃描該目錄。
在 .user.ini 風格的 INI 文件中只有具有 PHP_INI_PERDIR 和 PHP_INI_USER 模式的 INI 設置可被識別。
簡而言之,也就是說當PHP以CGI/FastCGI SAPI方式運行時,會去讀取一個.user.ini
的配置,我們可以在這里面設定open_basedir
參數來防止跨站。
在站點根目錄下新建一個.user.ini
,內容如下:
open_basedir=/data/wwwroot/:/tmp/:/proc/
為防止.user.ini
被篡改,可以給這個文件加上隱藏屬性。
chattr +i .user.ini
目前已知的寶塔面板,軍哥LNMP(lnmp.org)默認使用.user.ini
來防止跨站,這個方式非常靈活,可以針對某個網站單獨設置。
禁止部分目錄執行PHP
大多數PHP框架,如CodeIgniter、ThinkPHP都是單一入口,只需要index.php有入口權限程序就能正常運行。上傳目錄、靜態文件目錄完全沒必須要賦予PHP執行權限,否則反而可能被利用。nginx可以通過下面的規則來禁止某個目錄執行PHP:
#uploads|templets|data 這些目錄禁止執行PHP location ~* ^/(uploads|templets|data)/.*.(php|php5)$ { return 444; }
其它說明
以上主要是針對PHP本身設置和Nginx上進行限制,若有不足還請指正。