欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

php安全配置記錄和常見錯(cuò)誤梳理(總結(jié))

 更新時(shí)間:2017年03月28日 10:28:05   投稿:jingxian  
下面小編就為大家?guī)硪黄猵hp安全配置記錄和常見錯(cuò)誤梳理(總結(jié))。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

通常部署完php環(huán)境后會(huì)進(jìn)行一些安全設(shè)置,除了熟悉各種php漏洞外,還可以通過配置php.ini來加固PHP的運(yùn)行環(huán)境,PHP官方也曾經(jīng)多次修改php.ini的默認(rèn)設(shè)置。

下面對php.ini中一些安全相關(guān)參數(shù)的配置進(jìn)行說明

register_globals 
當(dāng)register_globals = ON時(shí),PHP不知道變量從何而來,也容易出現(xiàn)一些變量覆蓋的問題。因此從最佳實(shí)踐的角度,強(qiáng)烈建議設(shè)置 register_globals = OFF,這也是PHP新版本中的默認(rèn)設(shè)置。 
 
open_basediropen_basedir 
可以限制PHP只能操作指定目錄下的文件。這在對抗文件包含、目錄遍歷等攻擊時(shí)非常有用,應(yīng)該為此選項(xiàng)設(shè)置一個(gè)值。 
需要注意的是,如果設(shè)置的值是一個(gè)指定的目錄,則需要在目錄最后加上一個(gè)“/”,否則會(huì)被認(rèn)為是目錄的前綴。 
open_basedir = /home/web/html/
 
allow_url_include = Off 
為了對抗遠(yuǎn)程文件包含,請關(guān)閉此選項(xiàng),一般應(yīng)用也用不到此選項(xiàng)。同時(shí)推薦關(guān)閉的還有allow_url_fopen。 
 
display_errors = Off 
錯(cuò)誤回顯,一般常用于開發(fā)模式,但是很多應(yīng)用在正式環(huán)境中也忘記了關(guān)閉此選項(xiàng)。錯(cuò)誤回顯可以暴露出非常多的敏感信息,為攻擊者下一步攻擊提供便利。推薦關(guān)閉此選項(xiàng)。 
 
log_errors = On 
在正式環(huán)境下用這個(gè)就行了,把錯(cuò)誤信息記錄在日志里。正好可以關(guān)閉錯(cuò)誤回顯。 
 
magic_quotes_gpc = Off 
推薦關(guān)閉,它并不值得依賴(請參考“注入攻擊”一章),已知已經(jīng)有若干種方法可以繞過它,甚至由于它的存在反而衍生出一些新的安全問題。XSS、SQL注入等漏洞,都應(yīng)該由應(yīng)用在正確的地方解決。同時(shí)關(guān)閉它還能提高性能。 
 
cgi.fix_pathinfo = 0 
若PHP以CGI的方式安裝,則需要關(guān)閉此項(xiàng),以避免出現(xiàn)文件解析問題(請參考“文件上傳漏洞”一章)。 
 
session.cookie_httponly = 1 開啟HttpOnly 
 
session.cookie_secure = 1 
若是全站HTTPS則請開啟此項(xiàng)。 
 
sql.safe_mode = Off 
PHP的安全模式是否應(yīng)該開啟的爭議一直比較大。一方面,它會(huì)影響很多函數(shù);另一方面,它又不停地被黑客們繞過,因此很難取舍。如果是共享環(huán)境(比如App Engine),則建議開啟safe_mode,可以和disable_functions配合使用; 
如果是單獨(dú)的應(yīng)用環(huán)境,則可以考慮關(guān)閉它,更多地依賴于disable_functions控制運(yùn)行環(huán)境安全。 
 
disable_functions = 
能夠在PHP中禁用函數(shù)(如上默認(rèn)=號后面什么都不配置)。這是把雙刃劍,禁用函數(shù)可能會(huì)為開發(fā)帶來不便,但禁用的函數(shù)太少又可能增加開發(fā)寫出不安全代碼的幾率,同時(shí)為黑客獲取webshell提供便利。 
一般來說,如果是獨(dú)立的應(yīng)用環(huán)境,則推薦禁用以下函數(shù): 
disable_functions = escapeshellarg, escapeshellcmd, exec,passthru, proc_close, proc_get_status, proc_open, proc_nice,proc_terminate, shell_exec, system, ini_restore, popen, dl,disk_free_space, diskfreespace, set_time_limit, tmpfile, fopen,readfile, fpassthru, fsockopen, mail, ini_alter, highlight_file,openlog, show_source, symlink, apache_child_terminate,apache_get_modules, apache_get_version, apache_getenv,apache_note, apache_setenv, parse_ini_file

php 上傳大文件主要涉及配置upload_max_filesize和post_max_size兩個(gè)選項(xiàng)

曾經(jīng)遇到的問題: 
在網(wǎng)站后臺上傳圖片的時(shí)候出現(xiàn)一個(gè)非常怪的問題,有時(shí)候表單提交可以獲取到值,有時(shí)候就獲取不到了,連普通的字段都獲取不到了,苦思冥想還沒解決,最后問了師傅, 
師傅看了說挺奇怪的,然后問我 upload_max_filesize的值改了嗎,我說改了啊,師傅也解決不了了。過了一會(huì)師傅問 post_max_size改了嗎,我說那個(gè)和上傳沒關(guān)系吧, 
師傅沒理我,我還是照著自己的想法繼續(xù)測試,弄了半天還是不行,最后試了師傅提的意見,成功了,原來上傳是和 post_max_size有關(guān)系的。 
  
問題總結(jié) : 
php.ini配置文件中的默認(rèn)文件上傳大小為 2M,默認(rèn)upload_max_filesize = 2M ,即文件上傳的大小為 2M,如果你想上傳超過8M的文件,比如 20M, 
  
必須設(shè)定 upload_max_filesize = 20M。但是光設(shè)置upload_max_filesize = 20M還是無法實(shí)現(xiàn)大文件的上傳功能,你必須修改 php.ini配置文件中的post_max_size選項(xiàng), 
其代表允許 POST的數(shù)據(jù)最大字節(jié)長度,默認(rèn)為 8M。如果POST 數(shù)據(jù)超出限制,那么 $_POST和$_FILES 將會(huì)為空。要上傳大文件, 
你必須設(shè)定該選項(xiàng)值大于 upload_max_filesize指令的值,我一般設(shè)定upload_max_filesize和 post_max_size值相等。 
另外如果啟用了內(nèi)存限制,那么該值應(yīng)當(dāng)小于 memory_limit選項(xiàng)的值。 
  
文件上傳的其他注意事項(xiàng) : 
在上傳大文件時(shí),你會(huì)有上傳速度慢的感覺,當(dāng)超過一定的時(shí)間,會(huì)報(bào)腳本執(zhí)行超過 30秒的錯(cuò)誤,這是因?yàn)樵趐hp.ini配置文件中 max_execution_time 配置選項(xiàng)在作怪, 
其表示每個(gè)腳本最大允許執(zhí)行時(shí)間 (秒) ,0 表示沒有限制。你可以適當(dāng)調(diào)整 max_execution_time的值,不推薦設(shè)定為0。 
******************************************************************************************************** 
解釋: 
具體可查看 PHP手冊 中的 〔php.ini 核心配置選項(xiàng)說明〕 
upload_max_filesize 所上傳的文件的最大大小。 
post_max_size    設(shè)定 POST 數(shù)據(jù)所允許的最大大小。 
memory_limit    設(shè)定了一個(gè)腳本所能夠申請到的最大內(nèi)存字節(jié)數(shù)。 
 
一般來說:memory_limit > post_max_size > upload_max_filesize 
  
upload_max_filesize是限制本次上傳的最大值 
post_max_size是post數(shù)據(jù)的最大值, 通過POST提交數(shù)據(jù)的最大值 
一般我們在php中用的是POST方式上傳

php.ini中記錄PHP錯(cuò)誤日志的參數(shù):display_errors與log_errors的區(qū)別

1)display_errors 
錯(cuò)誤回顯,一般常用語開發(fā)模式,但是很多應(yīng)用在正式環(huán)境中也忘記了關(guān)閉此選項(xiàng)。錯(cuò)誤回顯可以暴露出非常多的敏感信息,為攻擊者下一步攻擊提供便利。推薦關(guān)閉此選項(xiàng)。 
 
display_errors = On 
開啟狀態(tài)下,若出現(xiàn)錯(cuò)誤,則報(bào)錯(cuò),出現(xiàn)錯(cuò)誤提示。即顯示所有錯(cuò)誤信息。 
 
dispaly_errors = Off 
關(guān)閉狀態(tài)下,若出現(xiàn)錯(cuò)誤,則提示:服務(wù)器錯(cuò)誤,但是不會(huì)出現(xiàn)錯(cuò)誤提示。即關(guān)閉所有錯(cuò)誤信息 
 
2)log_errors 
在正式環(huán)境下用這個(gè)就行了,把錯(cuò)誤信息記錄在日志里。正好可以關(guān)閉錯(cuò)誤回顯。 
 
log_errors = On  //注意,log_errors設(shè)置為On后,那么dispaly_errors就要設(shè)置為Off,這兩個(gè)不能同時(shí)打開。 
 
error_log = /Data/logs/php/error.log  //注意,log_errors設(shè)置為On時(shí),必須要設(shè)置error_log的日志文件路徑,并且這個(gè)日志文件要能有權(quán)限正常寫入。 
 
也就是說log_errors = On時(shí),必須指定error_log文件,如果沒指定或者指定的文件沒有權(quán)限寫入,那么照樣會(huì)輸出到正常的輸出渠道,那么也就使得display_errors 這個(gè)指定的Off失效,錯(cuò)誤信息還是打印了出來。 
 
對于PHP開發(fā)人員來說,一旦項(xiàng)目上線后,第一件事就是應(yīng)該將display_errors選項(xiàng)關(guān)閉,以免因?yàn)檫@些錯(cuò)誤所透露的路徑、數(shù)據(jù)庫連接、數(shù)據(jù)表等信息而遭到黑客攻擊。 
 
--------------------------------------------------- 
一般說來: 
 
測試環(huán)境下的php.ini中的錯(cuò)誤日志設(shè)置:        
error_reporting = E_ALL  
display_errors = On  
html_errors = On  
log_errors = Off  
 
正式環(huán)境下的php.ini中的錯(cuò)誤日志設(shè)置: 
error_reporting = E_ALL &~ E_NOTICE &~ E_WARNING    //注意這個(gè)設(shè)置,記得有一次因?yàn)檫@個(gè)設(shè)置有誤,導(dǎo)致了線上一個(gè)業(yè)務(wù)訪問出現(xiàn)了nginx 500報(bào)錯(cuò)!這個(gè)導(dǎo)致了php框架報(bào)錯(cuò)!  
display_errors = Off  
log_errors = On  
html_errors = Off  
error_log = /Data/logs/php/error.log 
ignore_repeated_errors = On  
ignore_repeated_source = On  
 
簡單講解下各個(gè)配置的意義: 
error_reporting :設(shè)置報(bào)告哪些錯(cuò)誤  
display_errors :設(shè)置錯(cuò)誤是否作為輸出的一部分顯示  
html_errors :設(shè)置錯(cuò)誤信息是否采用html格式  
log_errors :設(shè)置是否記錄錯(cuò)誤信息  
error_log :設(shè)置錯(cuò)誤信息記錄的文件  
ignore_repeated_errors :是否在同一行中重復(fù)顯示一樣的錯(cuò)誤信息  
ignore_repeated_source : 是否重復(fù)顯示來自同個(gè)文件同行代碼的錯(cuò)誤

順便記錄下php的頁面老是報(bào)時(shí)區(qū)錯(cuò)誤的處理過程:

Warning: phpinfo(): It is not safe to rely on the system's timezone settings. You are 
*required* to use the date.timezone setting or the date_default_timezone_set() 
function. In case you used any of those methods and you are still getting this 
warning, you most likely misspelled the timezone identifier. We selected the 
timezone 'UTC' for now, but please set date.timezone to select your timezone. in
/usr/local/www/zabbix2/phpinfo.php on line 2 
date/time support enabled 
"Olson" Timezone Database Version 2013.8 
Timezone Database internal 
Default timezone UTC 
 
修改php.ini 文件 
# vim /usr/local/php/etc/php.ini 
........ 
[Date] 
; Defines the default timezone used by the date functions 
; http://php.net/date.timezone 
date.timezone = Asia/Shanghai
 
注意必須把要 php.ini 復(fù)制一份到/usr/local/php/lib/下,否則 php 服務(wù)默認(rèn)會(huì)到這個(gè) lib 目錄下讀取 php.ini 文件,沒有的話,就是默認(rèn)時(shí)區(qū)UTC,這個(gè)時(shí)區(qū)和北京時(shí)間相差8小時(shí)。 
[root@i-gxcmjlge lib]# pwd 
/usr/local/php/lib
[root@i-gxcmjlge lib]# ll 
total 72 
drwxr-xr-x 14 root root 4096 Nov 18 01:11 php 
-rw-r--r-- 1 root root 65681 Nov 18 15:01 php.ini 
 
然后重啟php服務(wù)和nginx/apache服務(wù)

除了php.ini文件,還要注意php-fpm.conf配置,如下:

[root@i-v5lmgh7y etc]# cat php-fpm.conf|grep -v "^;"|grep -v "^$"
[global] 
pid = run/php-fpm.pid  //pid 設(shè)置,默認(rèn)在安裝目錄中的 var/run/php-fpm.pid,建議開啟 
error_log = log/php-fpm.log  //錯(cuò)誤日志,默認(rèn)在安裝目錄中的 var/log/php-fpm.log 
log_level = notice   //錯(cuò)誤級別. 可用級別為: alert(必須立即處理), error(錯(cuò)誤情況), warning(警告情況), notice(一般重要信息), debug(調(diào)試信息). 默認(rèn): notice. 
emergency_restart_threshold = 60 
emergency_restart_interval = 60s //表示在emergency_restart_interval所設(shè)值內(nèi)出現(xiàn)SIGSEGV或者SIGBUS錯(cuò)誤的php-cgi進(jìn)程數(shù)如果超過 emergency_restart_threshold個(gè),php-fpm就會(huì)優(yōu)雅重啟。這兩個(gè)選項(xiàng)一般保持默認(rèn)值。 
process_control_timeout = 0 //設(shè)置子進(jìn)程接受主進(jìn)程復(fù)用信號的超時(shí)時(shí)間. 可用單位: s(秒), m(分), h(小時(shí)), 或者 d(天) 默認(rèn)單位: s(秒). 默認(rèn)值: 0. 
daemonize = yes  //后臺執(zhí)行fpm,默認(rèn)值為yes,如果為了調(diào)試可以改為no。在FPM中,可以使用不同的設(shè)置來運(yùn)行多個(gè)進(jìn)程池。 這些設(shè)置可以針對每個(gè)進(jìn)程池單獨(dú)設(shè)置。 
 
[www] 
user = nobody   //啟動(dòng)進(jìn)程的帳戶 
group = nobody  //啟動(dòng)進(jìn)程的組 
listen = 127.0.0.1:9000  //fpm監(jiān)聽端口,即nginx中php處理的地址,一般默認(rèn)值即可??捎酶袷綖? 'ip:port', 'port', '/path/to/unix/socket'. 每個(gè)進(jìn)程池都需要設(shè)置. 
listen.backlog = 1024  //backlog數(shù),,由操作系統(tǒng)決定,-1表示無限制。也可以注釋掉此行。 
listen.allowed_clients = 127.0.0.1 //(可以不設(shè)置此行)允許訪問FastCGI進(jìn)程的IP,如果沒有設(shè)置或者為空,則允許任何服務(wù)器請求連接。設(shè)置any為不限制IP,如果要設(shè)置其他主機(jī)的nginx也能訪問這臺FPM進(jìn)程,listen處要設(shè)置成本地可被訪問的IP。默認(rèn)值是any。每個(gè)地址是用逗號分隔. 
 
pm = static  //對于專用服務(wù)器,pm可以設(shè)置為static,如何控制子進(jìn)程,選項(xiàng)有static和dynamic。如果選擇static,則由pm.max_children指定固定的子進(jìn)程數(shù)。如果選擇dynamic,則由下開參數(shù)決定: 
pm.max_children = 512  //子進(jìn)程最大數(shù) 
pm.start_servers = 387 //啟動(dòng)時(shí)的進(jìn)程數(shù) 
pm.min_spare_servers = 32 //保證空閑進(jìn)程數(shù)最小值,如果空閑進(jìn)程小于此值,則創(chuàng)建新的子進(jìn)程 
pm.max_spare_servers = 387 //保證空閑進(jìn)程數(shù)最大值,如果空閑進(jìn)程大于此值,此進(jìn)行清理 
pm.max_requests = 1024 //設(shè)置每個(gè)子進(jìn)程重生之前服務(wù)的請求數(shù). 對于可能存在內(nèi)存泄漏的第三方模塊來說是非常有用的. 如果設(shè)置為 '0' 則一直接受請求. 等同于 PHP_FCGI_MAX_REQUESTS 環(huán)境變量. 默認(rèn)值: 0 
pm.status_path = /status  //fpm狀態(tài)頁面的網(wǎng)址. 如果沒有設(shè)置, 則無法訪問狀態(tài)頁面. 默認(rèn)值: none. munin監(jiān)控會(huì)使用到 
 
ping.path = /ping  //fpm監(jiān)控頁面的ping網(wǎng)址. 如果沒有設(shè)置, 則無法訪問ping頁面. 該頁面用于外部檢測FPM是否存活并且可以響應(yīng)請求. 請注意必須以斜線開頭 (/)。可以不設(shè)置此行。 
ping.response = pong //用于定義ping請求的返回相應(yīng). 返回為HTTP 200的text/plain 格式文本. 默認(rèn)值: pong??梢圆辉O(shè)置此行。 
  
slowlog = var/log/slow.log  //慢請求的記錄日志,配合request_slowlog_timeout使用 
request_slowlog_timeout = 0 //設(shè)置單個(gè)請求的超時(shí)中止時(shí)間. 該選項(xiàng)可能會(huì)對php.ini設(shè)置中的'max_execution_time'因?yàn)槟承┨厥庠驔]有中止運(yùn)行的腳本有用. 設(shè)置為 '0' 表示 'Off'.當(dāng)經(jīng)常出現(xiàn)502錯(cuò)誤時(shí)可以嘗試更改此選項(xiàng)。 
request_terminate_timeout = 10s //當(dāng)一個(gè)請求該設(shè)置的超時(shí)時(shí)間后,就會(huì)將對應(yīng)的PHP調(diào)用堆棧信息完整寫入到慢日志中. 設(shè)置為 '0' 表示 'Off'。可以不設(shè)置此行。 
rlimit_files = 65535  //設(shè)置文件打開描述符的rlimit限制. 默認(rèn)值: 系統(tǒng)定義值默認(rèn)可打開句柄是1024,可使用 ulimit -n查看,ulimit -n 2048修改。 
rlimit_core = 0  //設(shè)置核心rlimit最大限制值. 可用值: 'unlimited' 、0或者正整數(shù). 默認(rèn)值: 系統(tǒng)定義值. 
catch_workers_output = yes //重定向運(yùn)行過程中的stdout和stderr到主要的錯(cuò)誤日志文件中. 如果沒有設(shè)置, stdout 和 stderr 將會(huì)根據(jù)FastCGI的規(guī)則被重定向到 /dev/null . 默認(rèn)值: 空.

------------------------Nginx+Php中限制站點(diǎn)目錄防止跨站的配置方案記錄(使用open_basedir)-------------------

方法1)在Nginx配置文件中加入:

fastcgi_param PHP_VALUE "open_basedir=$document_root:/tmp/:/proc/"; 

通常nginx的站點(diǎn)配置文件里用了include fastcgi.conf;,這樣的,把這行加在fastcgi.conf里就OK了。

如果某個(gè)站點(diǎn)需要單獨(dú)設(shè)置額外的目錄,把上面的代碼寫在include fastcgi.conf;這行下面就OK了,會(huì)把fastcgi.conf中的設(shè)置覆蓋掉。

這種方式的設(shè)置需要重啟nginx后生效。

方法2)在php.ini中加入

[HOST=www.wangshibo.com] 
open_basedir=/home/www/www.wangshibo.com:/tmp/:/proc/
[PATH=/home/www/www.wangshibo.com] 
open_basedir=/home/www/www.wangshibo.com:/tmp/:/proc/ 

這種方式的設(shè)置需要重啟php-fpm后生效。

方法3)在網(wǎng)站根目錄下創(chuàng)建.user.ini文件,并在該文件中寫入下面信息:

open_basedir=/home/www/www.wangshibo.com:/tmp/:/proc/ 

這種方式不需要重啟nginx或php-fpm服務(wù)。安全起見應(yīng)當(dāng)取消掉.user.ini文件的寫權(quán)限。

php.ini中建議禁止的函數(shù)如下:

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, popen, passthru, exec, system, shell_exec, proc_open, proc_get_status, chroot, chgrp, chown, ini_alter, ini_restore, dl, pfsockopen, openlog, syslog, readlink, symlink, popepassthru, stream_socket_server, fsocket, chdir

----------------------------------------------php啟動(dòng)后,9000端口沒有起來?--------------------------------------------

問題描述:

php服務(wù)安裝后,啟動(dòng)php-fpm,啟動(dòng)的時(shí)候沒有報(bào)錯(cuò)。然后ps -ef|grep php沒有發(fā)現(xiàn)進(jìn)程起來,lsof -i:9000發(fā)現(xiàn)端口也沒有起來。

查看日志,發(fā)現(xiàn)系統(tǒng)所允許打開的文件數(shù)超過了預(yù)定設(shè)置。

[root@i-v5lmgh7y etc]# /usr/local/php/sbin/php-fpm 
[root@i-v5lmgh7y etc]# ps -ef|grep php 
[root@i-v5lmgh7y etc]#lsof -i:9000 
[root@i-v5lmgh7y etc]# 
 
查看錯(cuò)誤日志發(fā)現(xiàn)問題: 
[root@i-v5lmgh7y log]# tail -f php-fpm.log 
[15-Nov-2015 23:53:15] NOTICE: fpm is running, pid 18277 
[15-Nov-2015 23:53:15] ERROR: failed to prepare the stderr pipe: Too many open files (24) 
[15-Nov-2015 23:53:16] NOTICE: exiting, bye-bye! 
[15-Nov-2015 23:53:59] NOTICE: fpm is running, pid 18855 
[15-Nov-2015 23:53:59] ERROR: failed to prepare the stderr pipe: Too many open files (24) 
[15-Nov-2015 23:54:00] NOTICE: exiting, bye-bye! 
 
發(fā)現(xiàn)是系統(tǒng)允許打開的文件數(shù)超了預(yù)定的設(shè)置。需要調(diào)大這個(gè)值: 
[root@i-v5lmgh7y etc]# ulimit -n 
1024 
[root@i-v5lmgh7y etc]# ulimit -n 65535  //臨時(shí)解決辦法 
[root@i-v5lmgh7y etc]# ulimit -n 
65535 
 
 
永久解決辦法: 
在/etc/security/limits.conf文件底部添加下面四行內(nèi)容: 
[root@i-v5lmgh7y etc]# cat /etc/security/limits.conf 
......... 
# End of file 
* soft nproc unlimited 
* hard nproc unlimited 
* soft nofile 65535 
* hard nofile 65535 
 
然后再次啟動(dòng)php-fpm程序,9000端口就能正常啟動(dòng)了 
[root@i-v5lmgh7y etc]# /usr/local/php/sbin/php-fpm 
[root@i-v5lmgh7y etc]# ps -ef|grep php 
root 21055 1 0 00:12 ? 00:00:00 php-fpm: master process 
(/usr/local/php/etc/php-fpm.conf) 
nobody 21056 21055 0 00:12 ? 00:00:00 php-fpm: pool www 
nobody 21057 21055 0 00:12 ? 00:00:00 php-fpm: pool www

----------------------------下面梳理幾個(gè)常見的php不恰當(dāng)配置引發(fā)的問題-----------------------------

1)request_terminate_timeout的值如果設(shè)置為0或者過長的時(shí)間,可能會(huì)引起file_get_contents的資源問題。 
如果訪問請求的遠(yuǎn)程資源反應(yīng)過慢,php-cgi進(jìn)程就會(huì)一直卡在那里不會(huì)超時(shí)。雖然php.ini文件里面max_execution_time可以設(shè)置PHP腳本的最大執(zhí)行時(shí)間,但是,在php-cgi(php-fpm) 中該參數(shù)不會(huì)起效。真正能夠控制PHP腳本最大執(zhí)行時(shí)間的是php-fpm.conf配置文件中的request_terminate_timeout參數(shù)。 
 
request_terminate_timeout默認(rèn)值為0秒,也就是說,PHP腳本會(huì)一直執(zhí)行下去。這樣當(dāng)所有的php-cgi進(jìn)程都卡住時(shí),這臺Nginx+PHP的WebServer已經(jīng)無法再處理新的PHP請求了,Nginx 將給用戶返回“502 Bad Gateway”。 
修改該參數(shù),設(shè)置一個(gè)PHP腳本最大執(zhí)行時(shí)間是必要的,但是治標(biāo)不治本。例如改成30s,如果發(fā)生訪問獲取網(wǎng)頁內(nèi)容較慢的情況,這就意味著150個(gè)php-cgi進(jìn)程,每秒鐘只能處理5個(gè)請求,WebServer同樣很難避免”502 Bad Gateway”。 
 
解決辦法是request_terminate_timeout設(shè)置為10s或者一個(gè)合理的值。 
 
2)max_requests參數(shù)配置不當(dāng),可能會(huì)引起間歇性502錯(cuò)誤 
設(shè)置每個(gè)子進(jìn)程重生之前服務(wù)的請求數(shù). 對于可能存在內(nèi)存泄漏的第三方模塊來說是非常有用的. 
如果設(shè)置為0,則一直接受請求,等同于php_fcgi_max_requests環(huán)境變量。默認(rèn)值為 0. 
比如:pm.max_requests = 1000 這個(gè)配置的意思是,當(dāng)一個(gè) php-cgi 進(jìn)程處理的請求數(shù)累積到500個(gè)后,自動(dòng)重啟該進(jìn)程。 
 
但是為什么要重啟進(jìn)程呢? 
一般在項(xiàng)目中,多多少少都會(huì)用到一些PHP的第三方庫,這些第三方庫經(jīng)常存在內(nèi)存泄漏問題,如果不定期重啟php-cgi進(jìn)程,勢必造成內(nèi)存使用量不斷增長。因此php-fpm作為php-cgi的管理器,提供了這么一項(xiàng)監(jiān)控功能,對請求達(dá)到指定次數(shù)的php-cgi進(jìn)程進(jìn)行重啟,保證內(nèi)存使用量不增長。正是因?yàn)檫@個(gè)機(jī)制,在高并發(fā)的站點(diǎn)中,經(jīng)常導(dǎo)致502錯(cuò)誤, 
目前解決方法是,把這個(gè)值盡量設(shè)置大些,盡可能減少php-cgi重新SPAWN的次數(shù),同時(shí)也能提高總體性能。在實(shí)際的生產(chǎn)環(huán)境中發(fā)現(xiàn),內(nèi)存泄漏如果不明顯,可以將這個(gè)值設(shè)置得非常大(比如204800)。要根據(jù)自己的實(shí)際情況設(shè)置這個(gè)值(比如我們線上設(shè)置1024),不能盲目地加大。 
話說回來,這套機(jī)制目的只為保證php-cgi不過分地占用內(nèi)存,為何不通過檢測內(nèi)存的方式來處理呢?通過設(shè)置進(jìn)程的峰值內(nèi)在占用量來重啟php-cgi進(jìn)程,會(huì)是更好的一個(gè)解決方案。 
 
3)php-fpm的慢日志,debug及異常排查神器 
request_slowlog_timeout設(shè)置一個(gè)超時(shí)的參數(shù),slowlog設(shè)置慢日志的存放位置

以上這篇php安全配置記錄和常見錯(cuò)誤梳理(總結(jié))就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論