注:以下所有操作均在CentOS 6.5 x86_64位系统下完成。
#准备工作#
前段时间PHP官方发布了一个重要的安全升级公告,修复了两个unserialize函数的严重漏洞,目前受影响的版本有:
- <5.4.36
- <5.5.20
- <5.6.4
这里我们直接下载5.6.4的版本进行安装配置,并且在这之前需要先把MySQL和Apache已经安装好,最好Nginx也先安装好,具体见:《CentOS安装MySQL-5.6.10+安全配置》、《CentOS安装Apache-2.4.10+安全配置》。
#PHP的安装#
开始下载PHP并进行编译安装:
# wget http://cn2.php.net/distributions/php-5.6.4.tar.gz
# tar zxf php-5.6..tar.gz
# cd php-5.6.
# export LD_LIBRARY_PATH=/usr/local/mysql/lib
# ./configure --prefix=/usr/local/php-5.6. --with-config-file-path=/usr/local/php-5.6./etc --with-mysql=/usr/local/mysql --with-pdo-mysql=/usr/local/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config --with-apxs2=/usr/local/apache/bin/apxs --enable-fpm --enable-shared --enable-zip --with-bz2 --enable-ftp --with-jpeg-dir --with-png-dir --with-freetype-dir --with-libxml-dir --with-xmlrpc --with-zlib-dir --with-gd --with-gmp --enable-gd-native-ttf --with-curl --with-regex=php --with-pic --with-xsl --enable-wddx --with-iconv --with-gettext --with-pear --enable-ctype --enable-calendar --enable-mbstring --enable-bcmath --enable-sockets --enable-exif --disable-rpath --with-mcrypt --with-mhash --with-openssl --enable-sysvsem --enable-sigchild --enable-sysvshm --enable-soap --enable-fileinfo --enable-opcache=no
...
Thank you for using PHP. config.status: creating php5.spec
config.status: creating main/build-defs.h
config.status: creating scripts/phpize
config.status: creating scripts/man1/phpize.
config.status: creating scripts/php-config
config.status: creating scripts/man1/php-config.
config.status: creating sapi/cli/php.
config.status: creating sapi/fpm/php-fpm.conf
config.status: creating sapi/fpm/init.d.php-fpm
config.status: creating sapi/fpm/php-fpm.service
config.status: creating sapi/fpm/php-fpm.
config.status: creating sapi/fpm/status.html
config.status: creating sapi/cgi/php-cgi.
config.status: creating ext/phar/phar.
config.status: creating ext/phar/phar.phar.
config.status: creating main/php_config.h
config.status: executing default commands # make
...
Build complete.
Don't forget to run 'make test'. # make install
...
Installing PHP SAPI module: apache2handler
/usr/local/apache-2.4./build/instdso.sh SH_LIBTOOL='/usr/local/apr/build-1/libtool' libphp5.la /usr/local/apache-2.4./modules
/usr/local/apr/build-/libtool --mode=install install libphp5.la /usr/local/apache-2.4./modules/
install .libs/libphp5.so /usr/local/apache-2.4./modules/libphp5.so
install .libs/libphp5.lai /usr/local/apache-2.4./modules/libphp5.la
libtool: install: warning: remember to run `libtool --finish /usr/local/src/php-5.6./libs'
chmod /usr/local/apache-2.4./modules/libphp5.so
[activating module `php5' in /usr/local/apache-2.4.10/conf/httpd.conf]
Installing PHP CLI binary: /usr/local/php-5.6./bin/
Installing PHP CLI man page: /usr/local/php-5.6./php/man/man1/
Installing PHP FPM binary: /usr/local/php-5.6./sbin/
Installing PHP FPM config: /usr/local/php-5.6./etc/
Installing PHP FPM man page: /usr/local/php-5.6./php/man/man8/
Installing PHP FPM status page: /usr/local/php-5.6./php/fpm/
Installing PHP CGI binary: /usr/local/php-5.6./bin/
Installing PHP CGI man page: /usr/local/php-5.6./php/man/man1/
Installing build environment: /usr/local/php-5.6./lib/php/build/
Installing header files: /usr/local/php-5.6./include/php/
Installing helper programs: /usr/local/php-5.6./bin/
program: phpize
program: php-config
Installing man pages: /usr/local/php-5.6./php/man/man1/
page: phpize.
page: php-config.
Installing PEAR environment: /usr/local/php-5.6./lib/php/
[PEAR] Archive_Tar - installed: 1.3.
[PEAR] Console_Getopt - installed: 1.3.
[PEAR] Structures_Graph- installed: 1.0.
[PEAR] XML_Util - installed: 1.2.
[PEAR] PEAR - installed: 1.9.
Wrote PEAR system config file at: /usr/local/php-5.6./etc/pear.conf
You may want to add: /usr/local/php-5.6./lib/php to your php.ini include_path
/usr/local/src/php-5.6./build/shtool install -c ext/phar/phar.phar /usr/local/php-5.6./bin
ln -s -f /usr/local/php-5.6./bin/phar.phar /usr/local/php-5.6./bin/phar
Installing PDO headers: /usr/local/php-5.6./include/php/ext/pdo/ # ln -s /usr/local/php-5.6./ /usr/local/php
给PHP的upload和session添加目录支持:
# mkdir -p /data/php/session
# mkdir -p /data/php/log
# mkdir -p /data/php/upload_tmp
# chmod /data/php/upload_tmp
至此,PHP已经安装完毕。
#PHP-FPM的启动/关闭/重启#
自PHP-5.3.3开始,php源码中包含了php-fpm,不需要再单独通过布丁的方式来安装php-fpm,在编译的时候加入参数--enable-fpm即可。
FPM(FastCGI Process Manager)用于替换PHP FastCGI的大部分附加功能,对于高负载网站非常有用。
首先将bin/php-fpm加入到系统PATH中:
# vim /etc/profile export PHP_HOME=/usr/local/php
export PATH=$PATH:$PHP_HOME/bin:$PHP_HOME/sbin $ source /etc/profile $ php -version
PHP 5.6. (cli) (built: Jan ::)
Copyright (c) - The PHP Group
Zend Engine v2.6.0, Copyright (c) - Zend Technologies
然后复制默认的配置文件:
# cp /usr/local/src/php-5.6./php.ini-production /usr/local/php-5.6./etc/php.ini
# cp /usr/local/php-5.6./etc/php-fpm.conf.default /usr/local/php-5.6./etc/php-fpm.conf
接下来修改默认配置文件:
# vim /usr/local/php/etc/php.ini date.timezone = Asia/Shanghai # vim /usr/local/php/etc/php-fpm.conf [global]
pid = /usr/local/php-5.6./var/run/php-fpm.pid
error_log = /usr/local/php-5.6./var/log/php-fpm.log
log_level = error [www]
user = www
group = www
listen = 127.0.0.1:
listen.owner = www
listen.group = www
listen.mode =
添加启动脚本,之后可以使用service来启动php-fpm程序,并且设置开机自启动:
# cp /usr/local/src/php-5.6./sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
# chmod +x /etc/init.d/php-fpm
# service php-fpm
Usage: /etc/init.d/php-fpm {start|stop|force-quit|restart|reload|status}
# chkconfig php-fpm on
启动php-fpm:
# service php-fpm start
Starting php-fpm done
如果启动的时候出现错误(实际操作中发现存在该情况):
Starting php-fpm /usr/local/php-5.6./sbin/php-fpm: error while loading shared libraries: libmysqlclient.so.: cannot open shared object file: No such file or directory
failed
则将MySQL的so库文件copy到系统下:
# cp /usr/local/mysql/lib/libmysqlclient.so. /usr/lib64/
再来重新启动PHP,这次启动成功。
#PHP+Nginx#
现在来编辑nginx.conf以支持php解析,查看当前php环境是否可以正常运行:
# vim /usr/local/nginx/conf/nginx.conf http {
server {
listen ;
server_name localhost;
root html;
index index.html index.php;
location ~ \.php$ {
try_files $uri = ;
include fastcgi.conf;
fastcgi_pass 127.0.0.1:;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
}
然后编写一个简单的php文件,用来显示当前PHP环境信息:
# vim /usr/local/nginx-1.6./html/phpinfo.php <?php
phpinfo();
?> # chown -R www:www /usr/local/nginx-1.6.
启动Nginx,并打开浏览器访问地址http://youripaddress/phpinfo.php应该可以看到:
至此,Nginx与PHP已经可以正常协同工作。
#PHP的扩展安装#
很多时候我们还需要给PHP安装各种扩展支持,比如memcache、redis、mongodb等,下面用几个例子来说明下。
1、安装pcntl扩展:
# cd /usr/local/src/php-5.6./ext/pcntl
# /usr/local/php-5.6./bin/phpize
# ./configure --with-php-config=/usr/local/php-5.6./bin/php-config
# make && make install
Installing shared extensions: /usr/local/php-5.6./lib/php/extensions/no-debug-zts-/
2、安装memcache扩展:
# wget http://pecl.php.net/get/memcache-2.2.7.tgz
# tar zxf memcache-2.2..tgz
# cd memcache-2.2.
# /usr/local/php-5.6./bin/phpize
# ./configure --with-php-config=/usr/local/php-5.6./bin/php-config
# make && make install
Installing shared extensions: /usr/local/php-5.6./lib/php/extensions/no-debug-zts-/
3、安装memcached扩展(支持SASL):
1)首先使用yum安装SASL环境:
# yum install cyrus-sasl-plain cyrus-sasl cyrus-sasl-devel cyrus-sasl-lib
2)然后下载并安装libmemecached:
# wget https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz
# tar zxf libmemcached-1.0..tar.gz
# cd libmemcached-1.0.
# ./configure --prefix=/usr/local/libmemcached-1.0. --enable-sasl
# make && make install
3)最后再安装memcached扩展:
# wget http://pecl.php.net/get/memcached-2.2.0.tgz
# tar zxf memcached-2.2..tgz
# cd memcached-2.2.
# /usr/local/php-5.6./bin/phpize
# ./configure --with-php-config=/usr/local/php-5.6./bin/php-config --with-libmemcached-dir=/usr/local/libmemcached-1.0. --enable-memcached-sasl
# make && make install
Installing shared extensions: /usr/local/php-5.6./lib/php/extensions/no-debug-zts-/
注:前面安装的libmemcached必须支持SASL,否则可能出现如下错误:
configure: error: no, libmemcached sasl support is not enabled. Run configure with --disable-memcached-sasl to disable this check
4、安装redis扩展:
# wget http://pecl.php.net/get/redis-2.2.7.tgz
# tar zxf redis-2.2..tgz
# cd redis-2.2.
# /usr/local/php-5.6./bin/phpize
# ./configure --with-php-config=/usr/local/php-5.6./bin/php-config
# make && make install
Installing shared extensions: /usr/local/php-5.6./lib/php/extensions/no-debug-zts-/
5、安装event扩展:
1)首先使用yum安装libtool环境:
# yum install libtool
2)然后下载并安装libevent:
# wget https://github.com/libevent/libevent/releases/download/release-2.1.8-stable/libevent-2.1.8-stable.tar.gz
# tar zxf libevent-2.1.-stable.tar.gz
# cd libevent-2.1.-stable
# ./configure --prefix=/usr/local/libevent-2.1.
# make && make install
3)最后再安装event扩展:
# wget http://pecl.php.net/get/event-2.4.3.tgz
# tar zxf event-2.4..tgz
# cd event-2.4.
# /usr/local/php-5.6./bin/phpize
# ./configure --with-php-config=/usr/local/php-5.6./bin/php-config --with-event-libevent-dir=/usr/local/libevent-2.1./
# make && make install
Installing shared extensions: /usr/local/php-5.6./lib/php/extensions/no-debug-zts-/
扩展安装完之后,还要打开php.ini文件编辑如下:
# vim /usr/local/php-5.6./etc/php.ini
extension=pcntl.so
extension=memcache.so
extension=memcached.so
extension=redis.so
extension=event.so
#PHP的安全配置#
1、控制脚本访问权限。由于PHP默认配置允许PHP脚本程序访问服务器上的任意文件,为避免PHP脚本访问不该访问的文件,需要设置PHP只能访问网站目录或其他必须可访问的目录。比如:
# vim /usr/local/php/etc/php.ini open_basedir=/data/php/upload_tmp:/data/www/proj1:/data/www/proj2
2、禁止使用PHP危险函数,这些函数都是PHP木马常用的,比如:
# vim /usr/local/php/etc/php.ini disable_functions = dl,assert,exec,popen,system,passthru,shell_exec,proc_close,proc_open,pcntl_exec
3、关闭注册全局变量(PHP-5.3.*和PHP-5.4.*中已废除)
register_globals = Off
4、开启magic_quotes_gpc(PHP-5.3.*和PHP-5.4.*中已废除),由于magic_quotes_gpc会把引用的数据中包含单引号'和双引号"以及反斜线 \自动加上反斜线,自动转译符号,确保数据操作的正确运行,magic_quotes_gpc的设定值将会影响通过Get/Post/Cookies获得的数据,可以有效的防止SQL注入漏洞。
magic_quotes_gpc = On
5、关闭错误信息提示,因为这些错误信息可能泄漏服务器的路径信息和数据库信息等。
display_errors = Off
6、开启错误日志记录,可以考虑跟Web服务器的日志放在一起,比如:
log_errors = On
error_log = /data/logs/php/php_error.log
7、禁止访问远程文件,因为访问URL远程资源使得PHP应用程序的漏洞变得更加容易被利用,关闭之,如果要访问远程服务器建议采用其他方式比如libcurl库。
allow_url_fopen = Off
allow_url_include = Off
8、开启PHP安全模式(PHP-5.3.*和PHP-5.4.*中已废除)
safe_mode = On
9、补上Nginx文件解析漏洞。
cgi.fix_pathinfo =
10、确保PHP(FastCGI)以非root权限启动。如果是php-cgi进程,需要su道普通用户再启动;php-fpm进程默认已是非root用户进行,配置中配置即可,不能修改为root运行。比如这里:
root 0.0 1.1 ? Ss : : php-fpm: master process (/usr/local/php-5.6./etc/php-fpm.conf)
www 0.0 1.0 ? S : : php-fpm: pool www
www 0.0 1.0 ? S : : php-fpm: pool www
root 0.0 0.1 pts/ S+ : : grep php-fpm
注:这里只有master是root用户权限,其他两个pool中的进程都是www用户,这是正确的。
#PHP的性能配置#
性能配置主要是为了让PHP能够运行得更好,这里很多时候需要根据业务的需求和当前系统的配置来设置,以下的配置只作为参考作用。
1、配置上传文件大小限制(一般不超过2MB)
# vim /usr/local/php/etc/php.ini file_uploads = On
upload_tmp_dir = /data/php/upload
upload_max_filesize = 5M
post_max_size = 8M max_execution_time =
max_input_time =
memory_limit = 32M
2、使用阿里云的OCS(memcache)来代替文件作为session的存储(这里需要前面安装memcached的扩展库,并且支持SASL),比如:
# vim /usr/local/php/etc/php.ini ;session.save_handler = files
;session.save_path = "/tmp"
;session.save_path = "/data/php/session"
;session.gc_maxlifetime = session.save_handler = memcached
session.save_path = "something.m.cnszalist3pub001.ocs.aliyuncs.com:11211"
session.gc_maxlifetime = [memcached]
memcached.use_sasl = On
memcached.sess_binary = On
memcached.sess_sasl_username = "yourusername"
memcached.sess_sasl_password = "yourpassword"
memcached.sess_locking = Off
memcached.sess_prefix = "memc.sess.key."
注:使用其他的诸如memcache或redis缓存也是类似上面的配置。
阿里云的OCS是分布式集群统一对外提供服务,实现了负载均衡且无单点故障。对比自建Memcached最大的区别就是“账号密码鉴权”。因为OCS是对外提供服务的,所以需要有白名单、流控、账号密码鉴权等安全机制。
由于OCS实现了标准的memcached协议,采用SASL鉴权流程,这也是为什么前面我们在添加memcached扩展的时候需要引入SASL支持。
之后可以编写一个简单的OCS的php代码来进行测试,比如:
# vim ocs.php <?php
$mem = new Memcached('ocs');
$mem->setOption(Memcached::OPT_COMPRESSION, false);
$mem->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
$mem->addServer("something.m.cnszalist3pub001.ocs.aliyuncs.com", );
$mem->setSaslAuthData("yourusername", "yourpassword"); $key = 'key';
$mem->set($key, 'ocs cache value');
$cache = $mem->get($key);
if (empty($cache)) {
echo 'Oh, No!';
} else {
echo "Thanks God, the cache value is '{$cache}'";
}
?>