您好,登錄后才能下訂單哦!
這篇文章給大家介紹php安全配置中有哪些常見的錯誤,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
下面對php.ini中一些安全相關參數的配置進行說明
register_globals 當register_globals = ON時,PHP不知道變量從何而來,也容易出現一些變量覆蓋的問題。因此從最佳實踐的角度,強烈建議設置 register_globals = OFF,這也是PHP新版本中的默認設置。 open_basediropen_basedir 可以限制PHP只能操作指定目錄下的文件。這在對抗文件包含、目錄遍歷等攻擊時非常有用,應該為此選項設置一個值。 需要注意的是,如果設置的值是一個指定的目錄,則需要在目錄最后加上一個“/”,否則會被認為是目錄的前綴。 open_basedir = /home/web/html/ allow_url_include = Off 為了對抗遠程文件包含,請關閉此選項,一般應用也用不到此選項。同時推薦關閉的還有allow_url_fopen。 display_errors = Off 錯誤回顯,一般常用于開發模式,但是很多應用在正式環境中也忘記了關閉此選項。錯誤回顯可以暴露出非常多的敏感信息,為攻擊者下一步攻擊提供便利。推薦關閉此選項。 log_errors = On 在正式環境下用這個就行了,把錯誤信息記錄在日志里。正好可以關閉錯誤回顯。 magic_quotes_gpc = Off 推薦關閉,它并不值得依賴(請參考“注入攻擊”一章),已知已經有若干種方法可以繞過它,甚至由于它的存在反而衍生出一些新的安全問題。XSS、SQL注入等漏洞,都應該由應用在正確的地方解決。同時關閉它還能提高性能。 cgi.fix_pathinfo = 0 若PHP以CGI的方式安裝,則需要關閉此項,以避免出現文件解析問題(請參考“文件上傳漏洞”一章)。 session.cookie_httponly = 1 開啟HttpOnly session.cookie_secure = 1 若是全站HTTPS則請開啟此項。 sql.safe_mode = Off PHP的安全模式是否應該開啟的爭議一直比較大。一方面,它會影響很多函數;另一方面,它又不停地被黑客們繞過,因此很難取舍。如果是共享環境(比如App Engine),則建議開啟safe_mode,可以和disable_functions配合使用; 如果是單獨的應用環境,則可以考慮關閉它,更多地依賴于disable_functions控制運行環境安全。 disable_functions = 能夠在PHP中禁用函數(如上默認=號后面什么都不配置)。這是把雙刃劍,禁用函數可能會為開發帶來不便,但禁用的函數太少又可能增加開發寫出不安全代碼的幾率,同時為黑客獲取webshell提供便利。 一般來說,如果是獨立的應用環境,則推薦禁用以下函數: 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兩個選項
曾經遇到的問題: 在網站后臺上傳圖片的時候出現一個非常怪的問題,有時候表單提交可以獲取到值,有時候就獲取不到了,連普通的字段都獲取不到了,苦思冥想還沒解決,最后問了師傅, 師傅看了說挺奇怪的,然后問我 upload_max_filesize的值改了嗎,我說改了啊,師傅也解決不了了。過了一會師傅問 post_max_size改了嗎,我說那個和上傳沒關系吧, 師傅沒理我,我還是照著自己的想法繼續測試,弄了半天還是不行,最后試了師傅提的意見,成功了,原來上傳是和 post_max_size有關系的。 問題總結 : php.ini配置文件中的默認文件上傳大小為 2M,默認upload_max_filesize = 2M ,即文件上傳的大小為 2M,如果你想上傳超過8M的文件,比如 20M, 必須設定 upload_max_filesize = 20M。但是光設置upload_max_filesize = 20M還是無法實現大文件的上傳功能,你必須修改 php.ini配置文件中的post_max_size選項, 其代表允許 POST的數據最大字節長度,默認為 8M。如果POST 數據超出限制,那么 $_POST和$_FILES 將會為空。要上傳大文件, 你必須設定該選項值大于 upload_max_filesize指令的值,我一般設定upload_max_filesize和 post_max_size值相等。 另外如果啟用了內存限制,那么該值應當小于 memory_limit選項的值。 文件上傳的其他注意事項 : 在上傳大文件時,你會有上傳速度慢的感覺,當超過一定的時間,會報腳本執行超過 30秒的錯誤,這是因為在php.ini配置文件中 max_execution_time 配置選項在作怪, 其表示每個腳本最大允許執行時間 (秒) ,0 表示沒有限制。你可以適當調整 max_execution_time的值,不推薦設定為0。 ******************************************************************************************************** 解釋: 具體可查看 PHP手冊 中的 〔php.ini 核心配置選項說明〕 upload_max_filesize 所上傳的文件的最大大小。 post_max_size 設定 POST 數據所允許的最大大小。 memory_limit 設定了一個腳本所能夠申請到的最大內存字節數。 一般來說:memory_limit > post_max_size > upload_max_filesize upload_max_filesize是限制本次上傳的最大值 post_max_size是post數據的最大值, 通過POST提交數據的最大值 一般我們在php中用的是POST方式上傳
php.ini中記錄PHP錯誤日志的參數:display_errors與log_errors的區別
1)display_errors 錯誤回顯,一般常用語開發模式,但是很多應用在正式環境中也忘記了關閉此選項。錯誤回顯可以暴露出非常多的敏感信息,為攻擊者下一步攻擊提供便利。推薦關閉此選項。 display_errors = On 開啟狀態下,若出現錯誤,則報錯,出現錯誤提示。即顯示所有錯誤信息。 dispaly_errors = Off 關閉狀態下,若出現錯誤,則提示:服務器錯誤,但是不會出現錯誤提示。即關閉所有錯誤信息 2)log_errors 在正式環境下用這個就行了,把錯誤信息記錄在日志里。正好可以關閉錯誤回顯。 log_errors = On //注意,log_errors設置為On后,那么dispaly_errors就要設置為Off,這兩個不能同時打開。 error_log = /Data/logs/php/error.log //注意,log_errors設置為On時,必須要設置error_log的日志文件路徑,并且這個日志文件要能有權限正常寫入。 也就是說log_errors = On時,必須指定error_log文件,如果沒指定或者指定的文件沒有權限寫入,那么照樣會輸出到正常的輸出渠道,那么也就使得display_errors 這個指定的Off失效,錯誤信息還是打印了出來。 對于PHP開發人員來說,一旦項目上線后,第一件事就是應該將display_errors選項關閉,以免因為這些錯誤所透露的路徑、數據庫連接、數據表等信息而遭到黑客攻擊。 --------------------------------------------------- 一般說來: 測試環境下的php.ini中的錯誤日志設置: error_reporting = E_ALL display_errors = On html_errors = On log_errors = Off 正式環境下的php.ini中的錯誤日志設置: error_reporting = E_ALL &~ E_NOTICE &~ E_WARNING //注意這個設置,記得有一次因為這個設置有誤,導致了線上一個業務訪問出現了nginx 500報錯!這個導致了php框架報錯! display_errors = Off log_errors = On html_errors = Off error_log = /Data/logs/php/error.log ignore_repeated_errors = On ignore_repeated_source = On 簡單講解下各個配置的意義: error_reporting :設置報告哪些錯誤 display_errors :設置錯誤是否作為輸出的一部分顯示 html_errors :設置錯誤信息是否采用html格式 log_errors :設置是否記錄錯誤信息 error_log :設置錯誤信息記錄的文件 ignore_repeated_errors :是否在同一行中重復顯示一樣的錯誤信息 ignore_repeated_source : 是否重復顯示來自同個文件同行代碼的錯誤
順便記錄下php的頁面老是報時區錯誤的處理過程:
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 復制一份到/usr/local/php/lib/下,否則 php 服務默認會到這個 lib 目錄下讀取 php.ini 文件,沒有的話,就是默認時區UTC,這個時區和北京時間相差8小時。 [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服務和nginx/apache服務
除了php.ini文件,還要注意php-fpm.conf配置,如下:
[root@i-v5lmgh7y etc]# cat php-fpm.conf|grep -v "^;"|grep -v "^$" [global] pid = run/php-fpm.pid //pid 設置,默認在安裝目錄中的 var/run/php-fpm.pid,建議開啟 error_log = log/php-fpm.log //錯誤日志,默認在安裝目錄中的 var/log/php-fpm.log log_level = notice //錯誤級別. 可用級別為: alert(必須立即處理), error(錯誤情況), warning(警告情況), notice(一般重要信息), debug(調試信息). 默認: notice. emergency_restart_threshold = 60 emergency_restart_interval = 60s //表示在emergency_restart_interval所設值內出現SIGSEGV或者SIGBUS錯誤的php-cgi進程數如果超過 emergency_restart_threshold個,php-fpm就會優雅重啟。這兩個選項一般保持默認值。 process_control_timeout = 0 //設置子進程接受主進程復用信號的超時時間. 可用單位: s(秒), m(分), h(小時), 或者 d(天) 默認單位: s(秒). 默認值: 0. daemonize = yes //后臺執行fpm,默認值為yes,如果為了調試可以改為no。在FPM中,可以使用不同的設置來運行多個進程池。 這些設置可以針對每個進程池單獨設置。 [www] user = nobody //啟動進程的帳戶 group = nobody //啟動進程的組 listen = 127.0.0.1:9000 //fpm監聽端口,即nginx中php處理的地址,一般默認值即可。可用格式為: 'ip:port', 'port', '/path/to/unix/socket'. 每個進程池都需要設置. listen.backlog = 1024 //backlog數,,由操作系統決定,-1表示無限制。也可以注釋掉此行。 listen.allowed_clients = 127.0.0.1 //(可以不設置此行)允許訪問FastCGI進程的IP,如果沒有設置或者為空,則允許任何服務器請求連接。設置any為不限制IP,如果要設置其他主機的nginx也能訪問這臺FPM進程,listen處要設置成本地可被訪問的IP。默認值是any。每個地址是用逗號分隔. pm = static //對于專用服務器,pm可以設置為static,如何控制子進程,選項有static和dynamic。如果選擇static,則由pm.max_children指定固定的子進程數。如果選擇dynamic,則由下開參數決定: pm.max_children = 512 //子進程最大數 pm.start_servers = 387 //啟動時的進程數 pm.min_spare_servers = 32 //保證空閑進程數最小值,如果空閑進程小于此值,則創建新的子進程 pm.max_spare_servers = 387 //保證空閑進程數最大值,如果空閑進程大于此值,此進行清理 pm.max_requests = 1024 //設置每個子進程重生之前服務的請求數. 對于可能存在內存泄漏的第三方模塊來說是非常有用的. 如果設置為 '0' 則一直接受請求. 等同于 PHP_FCGI_MAX_REQUESTS 環境變量. 默認值: 0 pm.status_path = /status //fpm狀態頁面的網址. 如果沒有設置, 則無法訪問狀態頁面. 默認值: none. munin監控會使用到 ping.path = /ping //fpm監控頁面的ping網址. 如果沒有設置, 則無法訪問ping頁面. 該頁面用于外部檢測FPM是否存活并且可以響應請求. 請注意必須以斜線開頭 (/)。可以不設置此行。 ping.response = pong //用于定義ping請求的返回相應. 返回為HTTP 200的text/plain 格式文本. 默認值: pong。可以不設置此行。 slowlog = var/log/slow.log //慢請求的記錄日志,配合request_slowlog_timeout使用 request_slowlog_timeout = 0 //設置單個請求的超時中止時間. 該選項可能會對php.ini設置中的'max_execution_time'因為某些特殊原因沒有中止運行的腳本有用. 設置為 '0' 表示 'Off'.當經常出現502錯誤時可以嘗試更改此選項。 request_terminate_timeout = 10s //當一個請求該設置的超時時間后,就會將對應的PHP調用堆棧信息完整寫入到慢日志中. 設置為 '0' 表示 'Off'。可以不設置此行。 rlimit_files = 65535 //設置文件打開描述符的rlimit限制. 默認值: 系統定義值默認可打開句柄是1024,可使用 ulimit -n查看,ulimit -n 2048修改。 rlimit_core = 0 //設置核心rlimit最大限制值. 可用值: 'unlimited' 、0或者正整數. 默認值: 系統定義值. catch_workers_output = yes //重定向運行過程中的stdout和stderr到主要的錯誤日志文件中. 如果沒有設置, stdout 和 stderr 將會根據FastCGI的規則被重定向到 /dev/null . 默認值: 空.
------------------------Nginx+Php中限制站點目錄防止跨站的配置方案記錄(使用open_basedir)-------------------
方法1)在Nginx配置文件中加入:
fastcgi_param PHP_VALUE "open_basedir=$document_root:/tmp/:/proc/";
通常nginx的站點配置文件里用了include fastcgi.conf;,這樣的,把這行加在fastcgi.conf里就OK了。
如果某個站點需要單獨設置額外的目錄,把上面的代碼寫在include fastcgi.conf;這行下面就OK了,會把fastcgi.conf中的設置覆蓋掉。
這種方式的設置需要重啟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/
這種方式的設置需要重啟php-fpm后生效。
方法3)在網站根目錄下創建.user.ini文件,并在該文件中寫入下面信息:
open_basedir=/home/www/www.wangshibo.com:/tmp/:/proc/
這種方式不需要重啟nginx或php-fpm服務。安全起見應當取消掉.user.ini文件的寫權限。
php.ini中建議禁止的函數如下:
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啟動后,9000端口沒有起來?--------------------------------------------
問題描述:
php服務安裝后,啟動php-fpm,啟動的時候沒有報錯。然后ps -ef|grep php沒有發現進程起來,lsof -i:9000發現端口也沒有起來。
查看日志,發現系統所允許打開的文件數超過了預定設置。
[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]# 查看錯誤日志發現問題: [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! 發現是系統允許打開的文件數超了預定的設置。需要調大這個值: [root@i-v5lmgh7y etc]# ulimit -n 1024 [root@i-v5lmgh7y etc]# ulimit -n 65535 //臨時解決辦法 [root@i-v5lmgh7y etc]# ulimit -n 65535 永久解決辦法: 在/etc/security/limits.conf文件底部添加下面四行內容: [root@i-v5lmgh7y etc]# cat /etc/security/limits.conf ......... # End of file * soft nproc unlimited * hard nproc unlimited * soft nofile 65535 * hard nofile 65535 然后再次啟動php-fpm程序,9000端口就能正常啟動了 [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
----------------------------下面梳理幾個常見的php不恰當配置引發的問題-----------------------------
1)request_terminate_timeout的值如果設置為0或者過長的時間,可能會引起file_get_contents的資源問題。 如果訪問請求的遠程資源反應過慢,php-cgi進程就會一直卡在那里不會超時。雖然php.ini文件里面max_execution_time可以設置PHP腳本的最大執行時間,但是,在php-cgi(php-fpm) 中該參數不會起效。真正能夠控制PHP腳本最大執行時間的是php-fpm.conf配置文件中的request_terminate_timeout參數。 request_terminate_timeout默認值為0秒,也就是說,PHP腳本會一直執行下去。這樣當所有的php-cgi進程都卡住時,這臺Nginx+PHP的WebServer已經無法再處理新的PHP請求了,Nginx 將給用戶返回“502 Bad Gateway”。 修改該參數,設置一個PHP腳本最大執行時間是必要的,但是治標不治本。例如改成30s,如果發生訪問獲取網頁內容較慢的情況,這就意味著150個php-cgi進程,每秒鐘只能處理5個請求,WebServer同樣很難避免”502 Bad Gateway”。 解決辦法是request_terminate_timeout設置為10s或者一個合理的值。 2)max_requests參數配置不當,可能會引起間歇性502錯誤 設置每個子進程重生之前服務的請求數. 對于可能存在內存泄漏的第三方模塊來說是非常有用的. 如果設置為0,則一直接受請求,等同于php_fcgi_max_requests環境變量。默認值為 0. 比如:pm.max_requests = 1000 這個配置的意思是,當一個 php-cgi 進程處理的請求數累積到500個后,自動重啟該進程。 但是為什么要重啟進程呢? 一般在項目中,多多少少都會用到一些PHP的第三方庫,這些第三方庫經常存在內存泄漏問題,如果不定期重啟php-cgi進程,勢必造成內存使用量不斷增長。因此php-fpm作為php-cgi的管理器,提供了這么一項監控功能,對請求達到指定次數的php-cgi進程進行重啟,保證內存使用量不增長。正是因為這個機制,在高并發的站點中,經常導致502錯誤, 目前解決方法是,把這個值盡量設置大些,盡可能減少php-cgi重新SPAWN的次數,同時也能提高總體性能。在實際的生產環境中發現,內存泄漏如果不明顯,可以將這個值設置得非常大(比如204800)。要根據自己的實際情況設置這個值(比如我們線上設置1024),不能盲目地加大。 話說回來,這套機制目的只為保證php-cgi不過分地占用內存,為何不通過檢測內存的方式來處理呢?通過設置進程的峰值內在占用量來重啟php-cgi進程,會是更好的一個解決方案。 3)php-fpm的慢日志,debug及異常排查神器 request_slowlog_timeout設置一個超時的參數,slowlog設置慢日志的存放位置
關于php安全配置中有哪些常見的錯誤就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。