>  기사  >  백엔드 개발  >  PHP 보안 구성 기록 및 일반적인 오류에 대한 자세한 요약

PHP 보안 구성 기록 및 일반적인 오류에 대한 자세한 요약

黄舟
黄舟원래의
2017-03-29 09:44:272340검색

일반적으로 php 환경을 배포한 후 몇 가지 보안 설정이 이루어집니다. 다양한 PHP 취약점에 익숙해지는 것 외에도 PHP를 구성하여 PHP 운영 환경을 강화할 수도 있습니다. .ini. PHP 관계자는 php.ini의 기본 설정도 여러 번 수정했습니다.

다음은 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 오류 로그에 대해 php.ini에 기록된 매개변수: 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) 추가:

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

일반적으로 nginx 사이트 구성 파일에 fastcgi.conf를 포함합니다. 이 경우 fastcgi.conf에 이 줄을 추가해도 됩니다.

사이트에서 별도로 추가 디렉터리를 설정해야 하는 경우에는 include fastcgi.conf에 위 코드를 작성하면 됩니다. 그러면 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 구성으로 인해 발생하는 몇 가지 일반적인 문제입니다.- ----- --------

아아아아

위 내용은 PHP 보안 구성 기록 및 일반적인 오류에 대한 자세한 요약의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.