This article mainly introduces PHP security configuration records and common errors. Interested friends can refer to it. I hope it will be helpful to everyone.
Usually after deploying the PHP environment, some security settings will be made. In addition to being familiar with various PHP vulnerabilities, you can also strengthen the PHP operating environment by configuring php.ini. PHP officials have also modified php.ini many times. default settings.
The following describes the configuration of some security-related parameters in php.ini
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 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
|
Copy after login
php Uploading large files mainly involves configuring the two options upload_max_filesize and post_max_size
##
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 曾经遇到的问题:
在网站后台上传图片的时候出现一个非常怪的问题,有时候表单提交可以获取到值,有时候就获取不到了,连普通的字段都获取不到了,苦思冥想还没解决,最后问了师傅,
师傅看了说挺奇怪的,然后问我 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方式上传
|
Copy after login
php Parameters for recording PHP error logs in .ini: The difference between display_errors and log_errors
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | 1)display_errors
错误回显,一般常用语开发模式,但是很多应用在正式环境中也忘记了关闭此选项。错误回显可以暴露出非常多的敏感信息,为攻击者下一步攻击提供便利。推荐关闭此选项。
display_errors = On
开启状态下,若出现错误,则报错,出现错误提示。即显示所有错误信息。
dispaly_errors = Off
关闭状态下,若出现错误,则提示:服务器错误,但是不会出现错误提示。即关闭所有错误信息
2)log_errors
在正式环境下用这个就行了,把错误信息记录在日志里。正好可以关闭错误回显。
log_errors = On
error_log = /Data/logs/php/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
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 : 是否重复显示来自同个文件同行代码的错误
|
Copy after login
By the way, record the processing process of the time zone error always reported on the php page:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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:
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服务
|
Copy after login
In addition to the php.ini file, also pay attention to the php-fpm.conf configuration, as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | [root@i-v5lmgh7y etc]# cat php-fpm.conf|grep -v "^;" |grep -v "^$"
[ global ]
pid = run/php-fpm.pid
error_log = log/php-fpm.log
log_level = notice
emergency_restart_threshold = 60
emergency_restart_interval = 60s
process_control_timeout = 0
daemonize = yes
[www]
user = nobody
group = nobody
listen = 127.0.0.1:9000
listen.backlog = 1024
listen.allowed_clients = 127.0.0.1
pm = static
pm.max_children = 512
pm.start_servers = 387
pm.min_spare_servers = 32
pm.max_spare_servers = 387
pm.max_requests = 1024
pm.status_path = /status
ping.path = /ping
ping.response = pong
slowlog = var /log/slow.log
request_slowlog_timeout = 0
request_terminate_timeout = 10s
rlimit_files = 65535
rlimit_core = 0
catch_workers_output = yes
|
Copy after login
------------------------Nginx Php restricts the site directory to prevent cross-site configuration scheme Logging (using open_basedir) -------------------
Method 1) In the Nginx configuration file Add:
1 | fastcgi_param PHP_VALUE "open_basedir=$document_root:/tmp/:/proc/" ;
|
Copy after login
Usually include fastcgi.conf; is used in the nginx site configuration file. In this case, add this line to It's OK in fastcgi.conf.
If a site needs to set up additional directories separately, write the above code in include fastcgi.conf; this line will be OK, and the settings in fastcgi.conf will be overwritten.
The settings in this way need to be restarted to take effect after nginx is restarted.
Method 2) Add
1 2 3 4 | [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/
|
Copy after login
in php.ini. The settings need to be restarted to take effect after php-fpm is restarted.
Method 3) Create a .user.ini file in the root directory of the website and write the following information in the file:
1 | open_basedir=/home/www/www.wangshibo.com:/tmp/:/proc/
|
Copy after login
This method does not require restarting the nginx or php-fpm service. For security reasons, write permissions on the .user.ini file should be removed.
The recommended functions in php.ini are as follows:
1 | 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
|
Copy after login
------------ ----------------------------------After php is started, port 9000 is not up? --------------------------------------------------
Problem description:
After the php service is installed, start php-fpm, and no error is reported when starting. Then ps -ef|grep php did not find that the process was up, and lsof -i:9000 found that the port was not up either.
Check the log and find that the number of files allowed to be opened by the system exceeds the predetermined setting.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | [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
|
Copy after login
--------------------------- Here are some common problems caused by improper PHP configuration--------------------------------
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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设置慢日志的存放位置
|
Copy after login
The above is the entire content of this article, I hope it will be helpful to everyone's study.
Related recommendations:
How to solve the problem that errorerror always pops up when ajax returns for verification
Laravel related query in PHP returns error id solution detailed explanation
How to deal with common errors in JS BUG and Error
The above is the detailed content of Detailed explanation of PHP security configuration records and common errors. For more information, please follow other related articles on the PHP Chinese website!