PHP配置文件优化实践

PHP配置文件优化实践


以下配置有参考到 php.ini-配置文件详解 ,以及 php-fpm.conf & php.ini 安全优化实践


部署服务

前提工作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 前提工作
$ php -v #更新前查看当前PHP版本避免重复更新
$ yum list installed | grep php #检查当前PHP的安装包
$ yum remove php* #卸载当前PHP安装包

# PHP软件源
# CentOS 6.x
$ rpm -Uvh http://mirror.webtatic.com/yum/el6/latest.rpm
# CentOS 7.x
$ rpm -Uvh https://mirror.webtatic.com/yum/el7/epel-release.rpm
$ rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
# 如果安装报错error: Failed dependencies:epel-release >= 7 is needed by webtatic-release-7-3.noarch
# 则需要安装epel-release
$ yum install epel-release -y #yum安装epel-release
$ rpm -ivh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm #rpm安装epel-release
# 安装完成在重新安装php软件源
安装PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#查看yum源是否有php72w安装包
$ yum list php72w

# 安装php及相关插件
# 安装php7.0
$ yum install -y php70w.x86_64 php70w-cli.x86_64 php70w-common.x86_64 php70w-gd.x86_64 php70w-ldap.x86_64 php70w-mbstring.x86_64 php70w-mcrypt.x86_64 php70w-mysql.x86_64 php70w-pdo.x86_64 php70w-fpm

# 安装php7.1
$ yum install -y php71w-fpm php71w-opcache php71w-cli php71w-gd php71w-imap php71w-mysqlnd php71w-mbstring php71w-mcrypt php71w-pdo php71w-pecl-apcu php71w-pecl-mongodb php71w-pecl-redis php71w-pgsql php71w-xml php71w-xmlrpc php71w-devel mod_php71w

# 安装php7.2
$ yum install -y php72w-fpm php72w-opcache php72w-cli php72w-gd php72w-imap php72w-mysqlnd php72w-mbstring php72w-pdo php72w-pecl-apcu php72w-pecl-mongodb php72w-pecl-redis php72w-pgsql php72w-xml php72w-xmlrpc php72w-devel mod_php72w

# 查看当前php版本
$ php -v

# 开启php-fpm服务
$ systemctl enable php-fpm
$ systemctl start php-fpm

配置服务

php-fpm.conf
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
# php-fpm的全局配置模块
[global]

# 指定php-fpm的进程id文件存放位置
pid = /var/run/php-fpm/php-fpm.pid

# 指定php-fpm进程自身错误日志存放位置
error_log = /var/log/php-fpm/error.log

# 指定记录php-fpm的日志等级
log_level = error

# 后台进程启动
daemonize = yes

# 打开文件描述符限制
rlimit_files = 65535

# 使用处理event事件机制
events.mechanism = epoll
# select (any POSIX os)
# poll (any POSIX os)
# epoll (linux >= 2.5.44)
# kqueue (FreeBSD >= 4.1, OpenBSD >= 2.9, NetBSD >= 2.0)

include=/etc/php-fpm.d/*.conf
php-fpm.d/www.conf
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
# php-fpm的web配置模块
[www]

# php-fpm进程用户和组
# 最好把web服务用户和php-fpm进程用户权限分开,分别用两个完全不同的系统伪用户来跑对应服务,防止意外的越权行为
user = php
group = php

# 监听端口
listen = 127.0.0.1:9000
listen.owner = php
listen.group = php
# 允许FastCGI客户端连接的IPv4地址,多个地址用','分隔,为空则允许任何地址发来链接请求
listen.allowed_clients = 127.0.0.1

# 2种方式(Static/Dynamic)静态/动态,选择进程池管理器如何控制子进程的数量
pm = dynamic

# 同一时刻能够存货的最大子进程的数量
pm.max_children = 1024

# 在启动时启动的子进程数量
pm.start_servers = 16

# 处于空闲"idle"状态的最小子进程,如果空闲进程数量小于这个值,那么相应的子进程会被创建
pm.min_spare_servers = 5

# 最大空闲子进程数量,空闲子进程数量超过这个值,那么相应的子进程会被杀掉。
pm.max_spare_servers = 20

# 派生新的子进程前,每一个子进程应该处理的请求数目,在第三方库中解决内存溢出很有用,设置为0则不会限制
pm.max_requests = 2048

# 配置一个URI,以便查看fpm状态页
# 请谨慎打开,打开请设置可访问的权限避免暴露
pm.status_path = /status

# 用于记录慢请求
slowlog = /var/log/php-fpm/www-slow.log

# 慢日志请求超时时间,对一个php程序进行跟踪。
request_slowlog_timeout = 10

# 限制FPM执行解析的扩展名
security.limit_extensions = .php
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
[PHP]

# 是否启用PHP解析引擎
engine = On

# 是否使用简介标志
short_open_tag = Off

# 浮点型数据显示的有效期
precision = 14

# 输出缓冲区大小(字节),建议值为4096~8192
output_buffering = 4096

# 是否开启zlib输出压缩
zlib.output_compression = Off

# 是否要求PHP输出层在每个输出块之后自动刷新数据
implicit_flush = Off

# 将浮点型和双精度型数据序列化存储时的精度(有效位数)。默认值能够确保浮点型数据被解序列化程序解码时不会丢失数据。
serialize_precision = 17

# 限制php对本地文件系统的访问
open_basedir = "/data/servers/webapps:/var/www/"

# 禁用各种高危函数
disable_functions = dl,eval,assert,popen,proc_close,gzinflate,str_rot13,base64_decode,exec,system,ini_alter,readlink,symlink,leak,proc_open,pope,passthru,chroot,scandir,chgrp,chown,escapeshellcmd,escapeshellarg,shell_exec,proc_get_status,max_execution_time,opendir,readdir,chdir,dir,unlink,delete,copy,rename,ini_set,phpinfo,pcntl-fork,create_function

zend.enable_gc = On

# 隐藏php的详细版本号
expose_php = Off

# 限制php单脚本执行时长,防止服务器资源被长期滥用而产生拒绝服务的效果
#每个脚本最大执行秒数
max_execution_time = 30
#每个脚本用来分析请求数据的最大限制时间
max_input_time = 60
#每个脚本执行的内存限制
memory_limit = 8M

# 设置php的错误报告级别,只需要报告警告和错误即可
error_reporting = E_WARING & ERROR

# 切记千万不让让php错误输出到前端页面上
display_errors = Off

# 另外,不要把php启动过程中的错误输出到前端页面上
display_startup_errors = Off

# 开启php错误日志记录
log_errors = On

# 指定php错误日志的最大长度
log_errors_max_len = 2048

# 不要忽略重复的错误
ignore_repeated_errors = Off

# 打开后当记录重复的信息时忽略来源
ignore_repeated_source = Off

# 报告内存泄露,仅在debug编译模式下有效
report_memleaks = On

# 在$php_errormsg中保存最后一次错误/警告消息 (逻辑值).永远不要再生产环境中使用此特性:html_errors 会显示php错误所在的html标
track_errors = Off

# 是否开启静态网页错误提示
html_errors = On

# 指定php错误日志存放位置
error_log = php_errors.log


# 此指令描述了PHP注GET,POST,Cookie,环境和内置变量的顺序(各自使用G,P,C,E和S,一般使用EGPCS或GPC).注册使用从左往右的顺序,新的值会覆盖旧的值.
variables_order = "GPCS"

# 此指令描述的顺序PHP注册GET,POST和COOKIE变量_REQUEST数组。注册是由左到右,新的值将覆盖旧值。如果这个指令没有设置,variables_order中使用$_REQUEST内容。请注意,默认分配的php.ini文件中不包含’C’饼干,出于安全方面的考虑。
request_order = "GP"

# 此指令让PHP确认是否申明 argv&argc 变量 (这些变量会包含GET信息). ;如果你不使用这些变量,为了提升性能应该关闭此选项。
register_argc_argv = Off

# 当打开此项, SERVER ENV 变量将在第一次被使用时而不是脚本一开始时创建(运行时);如果这些变量在脚本中没有被使用过, 打开此项会增加一点性能.;为了使此指令有效,PHP指register_globals, register_long_arrays,;以及 register_argc_argv 必须被关闭.
auto_globals_jit = On

# 通过POST表单给php的所能接收的文件大小最多为多少
post_max_size = 8M

# PHP内建默认为text/html
default_mimetype = "text/html"


default_charset = "UTF-8"

# 是否允许使用dl()函数。dl()函数仅在将PHP作为apache模块安装时才有效。禁用dl()函数主要是出于安全考虑,因为它可以绕过open_basedir指令的限制。在安全模式下始终禁用dl()函数,而不管此处如何设置。
enable_dl = Off

# 默认cgi.fix_pathinfo 项是开启的,即值为1,它会对文件路径自动进行修正,我们要把它改成0,不要让php自动修正文件路径,防止入侵者利用此特性构造解析漏洞来配合上传webshell
cgi.fix_pathinfo = 0

# 开启php上传功能,如果实际业务根本不涉及到上传直接把上传功能关掉即可
file_uploads = On

# 文件传上来的临时存放目录
upload_tmp_dir = /data/servers/webapps/tmp_uploads

# 允许上传文件的文件大小最大为多少
upload_max_filesize = 8M

# 最大同时可以上传20个文件
max_file_uploads = 20

# 是否允许打开远程文件
# 为On时,则表示允许,也就是说,此时可以通过file_get_contents(),include(),require()等函数直接从远端获取数据
# 容易造成任意文件读取和包含问题,注意,此项默认就是开启的
allow_url_fopen = Off

# 是否允许include/require远程文件,容易造成远程包含,强烈建议关闭此项
allow_url_include = Off

# 默认的socket超时时间
default_socket_timeout = 60

[browscap]
# 修改session文件存放路径,最好不要直接放在默认的/tmp目录下,实际中可能是一台单独的session服务器,比如,memcached
[Session]
session.save_handler = memcache
session.save_path = "tcp://192.168.1.101:11211"

#php的是PHPSESSID,jsp的则是JSESSIONID
session.name = PHPSESSID

小结:关于配置方面已经基本介绍完成,服务安全是我们不可去忽略的,我们要多去关注官方的高危补丁,定期升级软件,最后以上全部参数基本都可以用于实战部署,但并不是所有的参数配置都是必须的,具体请根据实际情况来进行调整和定制,有些地方都是根据我实际建议来考量的,并不一定完全是对的,如果你有更好的方案,欢迎投稿。
我是Beytagh Stark,座右铭:唯一不变的就是一直在变