源码编译安装php

原文:https://klionsec.github.io/2017/11/23/phpsec/#menuphp

my compile configuration:html

./configure \
--with-fpm \
--with-libevent=shared,/usr/lib \
--with-mcrypt \
--with-zlib \
--with-curl  \
--enable-mbstring \
--with-openssl \
--with-mysql \
--with-mysql-sock \
--with-gd \
--with-jpeg-dir=/usr/lib \
--enable-gd-native-ttf \
--without-sqlite

phpinfo page output seems like below前端

Configuration File (php.ini) Path: /usr/local/lib
Loaded Configuration File:         none

And there is no php.ini in /usr/local/lib.mysql

My Environment: Ubuntu 9.10 64bit, nginx 0.8.32nginx

1 Answer

up vote 10down voteaccepted

From the INSTALL file in php-5.3.1.tar.gz:git

13. Setup your php.ini file:

PHP will use the built-in default values if no php.ini file was
placed in the configuration directory. The default location is
/usr/local/lib, if you prefer your php.ini in another location, use 
--with-config-file-path=/some/path in step 10.

The PHP distribution provides two sample php.ini files, you can use them
by
  cp php.ini-development /usr/local/lib/php.ini
or
  cp php.ini-production  /usr/local/lib/php.ini

If you choose one of these php.ini files be certain to read the list
of changes within, as they affect how PHP behaves.

You need to create the php.ini file. This can be done by copying one of the sample files.程序员

-------------------------------------------------------------

php-fpm.conf & php.ini 安全优化实践

0x01 关于 phpgithub

1
2
3
4
5
其历史相对已经比较久远了,这里也就不废话了,属弱类型中一种解释型语言
除了web开发以及写些简单的exp,暂未发现其它牛逼用途,暂以中小型web站点开发为主
另外,低版本的php自身漏洞就比较多,建议,从如今开始就在新项目中使用php 5.6.x 日后的版本
好在官方维护的一直比较勤奋,主次版本都迭代的比较快,最新版已经到 7.2.0
哼哼……是, '最好的语言'... :)

 

0x02 这次演示环境web

1
2
CentOS6.8 x86_64 最小化,带基础库安装 eth0: 192.168.3.42 eth1: 192.168.4.14 eth2: 192.168.5.14
php-5.6.32.tar.gz 官方提供的源码包

 

0x03 下载 php-5.6.32.tar.gz,并安装好php所需的各类依赖库sql

1
2
3
4
5
6
7
8
9
# yum install epel-release -y
# yum install -y zlib-devel libxml2-devel freetype-devel
# yum install -y libjpeg-devel libpng-devel gd-devel curl-devel libxslt-devel
# yum install openssl openssl-devel libmcrypt libmcrypt-devel mcrypt mhash mhash-devel -y
# tar xf libiconv-1.15.tar.gz
# cd libiconv-1.15
# ./configure --prefix=/usr/local/libiconv-1.15 && make && make install
# ln -s /usr/local/libiconv-1.15/ /usr/local/libiconv
# ll /usr/local/libiconv/

 

0x04 开始编译安装php5.6.32,要带的编译参数比较多,你们下去之后,能够仔细了解下这些参数都是干什么用的,其实,都是一些php内置功能模块,这里默认就已经启用了一些比较经常使用的模块,如,pdo,mysqli,关于下面的模块,并不用所有都装,根据你本身实际的开发业务需求,用什么装什么便可,切记,不要一上来无论用不用就先装一大堆,你不用,极可能就会被别人利用

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
# wget http://au1.php.net/distributions/php-5.6.32.tar.gz
# tar xf php-5.6.32.tar.gz
# cd php-5.6.32
# ./configure --help
# ./configure \
- -prefix=/usr/local/php-5.6.32 \
- -with-config-file-path=/usr/local/php-5.6.32/etc \
- -with-mysql=/usr/local/mysql \
- -with-mysqli=/usr/local/mysql/bin/mysql_config \
- -with-pdo-mysql=/usr/local/mysql \
- -with-iconv-dir=/usr/local/libiconv \
- -with-freetype-dir \
- -with-jpeg-dir \
- -with-png-dir \
- -with-zlib \
- -with-libxml-dir=/usr \
- -with-curl \
- -with-mcrypt \
- -with-gd \
- -with-openssl \
- -with-mhash \
- -with-xmlrpc \
- -with-xsl \
- -with-fpm-user=nginx \
- -with-fpm-group=nginx \
- -enable-xml \
- -disable-rpath \
- -enable-bcmath \
- -enable-shmop \
- -enable-sysvsem \
- -enable-inline-optimization \
- -enable-mbregex \
- -enable-fpm \
- -enable-mbstring \
- -enable-gd-native-ttf \
- -enable-pcntl \
- -enable-sockets \
- -enable-soap \
- -enable-short-tags \
- -enable-static \
- -enable-ftp \
- -enable-opcache=no

 

1
2
3
# make && make install
# ln -s /usr/local/php-5.6.32/ /usr/local/php
# cp php.ini-production /usr/local/php/etc/php.ini 建立php解释器的配置文件

0x05 编辑,配置并优化php-fpm.conf,即 fastcgi 的服务端,以下

让php进程以一个系统伪用户的身份起来,在能知足实际业务需求的状况下,最大程度上下降php进程权限

1
2
3
4
5
# useradd -s /sbin/nologin -M phpfpm
# cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf
# vi /usr/local/php/etc/php-fpm.conf
# mkdir /usr/local/php/logs
# egrep -v "^$|;" /usr/local/php/etc/php-fpm.conf 简化php-fpm配置文件

 

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
# php-fpm 的全局配置模块
[global]
 
# 指定php-fpm的进程id号文件存放位置
pid = /usr/local/php/logs/php-fpm.pid
 
# 指定php-fpm进程自身的错误日志存放位置
error_log = /usr/local/php/logs/php-fpm.log
 
# 指定要记录的php-fpm日志级别
log_level = error
rlimit_files = 32768
events.mechanism = epoll
 
# php-fpm web配置模块
[www]
 
# 最好把web服务用户和php-fpm进程用户的权限分开,分别用两个彻底不一样的系统伪用户来跑对应的服务,防止意外的越权行为
# 其实,你也能够不分开,特定条件下,关系也并非很是大,不过,我的建议,最好仍是分开
user = phpfpm
group = phpfpm
 
# 务必要监听在127.0.0.1的9000端口,另外,该端口严禁对外开放,防止别人经过fastcgi进行包含
listen = 127.0.0.1:9000
listen.owner = phpfpm
listen.group = phpfpm
 
pm = dynamic
pm.max_children = 1024
pm.start_servers = 16
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 2048
slowlog = /usr/local/php/logs/ $pool.log.slow
request_slowlog_timeout = 10
php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f klion@protonmail.com
 
# 只让为php的后缀执行,通常这里还有`.php3 .php4 .php5`,把那些默认给的可执行后缀通通去掉,只留`.php`便可
# 通常会配合php.ini文件中的cgi.fix_pathinfo参数一块儿使用,避免入侵者构造利用解析漏洞进行上传
security.limit_extensions = .php
1
2
3
4
5
# /usr/local/php/sbin/php-fpm 启动php-fpm
# ps -le | grep "php-fpm"
# netstat -tulnp | grep ":9000"
# echo "/usr/local/php/sbin/php-fpm" >> /etc/rc.local && cat /etc/rc.local
# killall php-fpm 若是想关闭php-fpm,直接把它进程kill掉便可

尝试让php与mysql,nginx 进行联动,看看php能不能被正常解析

1
# vi connect.php

 

1
2
3
4
5
6
7
8
<?php
$link = mysql_connect( "localhost","root","admin") or die(mysql_error());
if($link){
echo "yeah , mysql connect succeed!";
} else{
echo mysql_error();
}
?>

0x06 最后,咱们就来好好关注下php解析器自身的安全,php解析器的设置所有依靠php.ini文件来实现,因此,下面就来详细说明一下针对php.ini的安全配置

1
# vi /usr/local/php/etc/php.ini

 

将 register_globals 项设为Off,自己的意思就是注册为全局变量,也就是说,设置为On的时候,从客户端传过来的参数值会被直接注册到php全局变量中,在后端能够直接拿到该变量到脚本中使用,若是为Off,则表示只能到特定的全局数组中才能取到该数据,建议关闭,容易形成变量覆盖问题,不过在php高版本中 如,> 5.6.x,已经去除对此项的设置,官方给的说明是这样的本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除,若是你用的仍是低版本的php就须要注意把此项关闭

1
register_globals = Off

 

1
2
3
4
5
6
7
<?php
if($mark){
echo "login succeed! "; # 此处会直接显示登录成功,因事先没有定义$mark,致使$mark直接被覆盖掉了
} else{
echo "login failed!";
}
?>

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

1
cgi .fix_pathinfo = 0

 

建议同时关闭如下两项,若是实在有业务需求,请在代码中严格限制检查用户传过来的数据

1
2
3
4
5
6
# 为On时,则表示容许,也就是说,此时能够经过file_get_contents(),include(),require()等函数直接从远端获取数据
# 容易形成任意文件读取和包含问题,注意,此项默认就是开启的
allow_url_fopen = Off
 
# 容易形成远程包含,强烈建议关闭此项
allow_url_include = Off

 

禁用各类高危函数,尽量让各类 webshell [ 一句话,大马 ] 没法再靠php内置函数来执行各类系统命令,说实话,禁用这些函数也并不能很好的防住什么,利用各类拆分拼装变形,依然很容易逃逸,下面是一些比较常见的命令和代码执行函数,若是你还发现有其它的一些不经常使用的高危函数,也能够一并加进来,防止被入侵者率先发现并利用,此项默认为空,即关闭,另外,并非下面全部的函数都必定要禁用掉,务必要根据本身实际的开发业务来进行,实在用不到的,也不必让它留着,由于有些函数,开发可能会用,因此也不能盲注的去禁用,那就只能靠在代码中作更为严格的检查,中间的利害还要靠你们本身去定夺,这里仅仅只是个参考

1
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

 

转义开关,主要用来转义各类特殊字符,如,单引号,双引号,反斜线和空字符...我的建议,在这里先把它关闭,由于它并不能很好的防住sql注入,或者说,基本是防不住的,好比,利用宽字节 说到这儿,顺便再补充一句,对付宽字节的最好办法就是全站统一使用 utf-8,这里仍是建议你们采用sql语句预编译和绑定变量的方式来预防sql注入,这也是目前为止比较切实有效的预防手段,对于从客户端过来的各类其它数据,能够单独写个检查类,若是你想安全就不要对这些开关寄予太大的但愿,可能php官方也发现,这个开关实质就是个摆设,因此给出了这样的说明本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除

1
2
magic_quotes_gpc = Off
magic_quotes_runtime = Off

 

关闭php自身的各类错误回显,反正只要记得,在项目上线后,全部的程序错误一概接收到咱们本身事先准备好的地方[通常是日志],一旦被入侵者在前端看到,极易形成敏感信息泄露,高版本的php,默认这些危险项就是处于关闭状态的,另外,有条件的状况下务必把线上环境和测试开发环境隔离,不要把过多但愿寄托于程序员,毕竟,你我都知道,那是根本不靠谱的 ^_^

1
2
3
4
5
6
7
display_errors = Off # 切记千万不让让php错误输出到前端页面上
error_reporting = E_WARING & ERROR # 设置php的错误报告级别,只须要报告警告和错误便可
log_errors = On # 开启php错误日志记录
error_log = /usr/local/php/logs/php_errors.log # 指定php错误日志存放位置
log_errors_max_len = 2048 # 指定php错误日志的最大长度
ignore_repeated_errors = Off # 不要忽略重复的错误
display_startup_errors = Off # 另外,不要把php启动过程当中的错误输出到前端页面上

 

隐藏php的详细版本号,即X-Powered-By中显示的内容,不得再也不次强调,有些漏洞只能针对特定的类型版本,在实际渗透过程当中,若是让入侵者看到详细的版本号,他极可能就会直接去尝试利用该版本所具备的一些漏洞特性再配合着其它漏洞一块儿使用

1
expose_php = Off

 

限制php对本地文件系统的访问,即把全部的文件操做都限制指定的目录下,让php其实就是限制了像fopen()这类函数的访问范围,通常主要用来防止旁站跨目录,把webshell死死控制在当前站点目录下,此项默认为空,不建议直接写到php.ini中,能够参考前面nginx安所有署中的,直接在每一个站点目录下新建一个.user.ini而后再把下面的配置写进去便可,这样相对比较灵活

1
open_basedir = "/usr/local/nginx/html/bwapp/bWAPP:/usr/local/nginx/html/dvws/"

 

关于对服务端session的一些安全处理方式

隐藏后端使用的真正脚本类型,扰乱入侵者的渗透思路,另外,切记不要把敏感数据直接明文存在session中,有泄露风险

1
session .name = JSESSIONID 表示jsp程序,php的则是PHPSESSID

 

修改session文件存放路径,最好不要直接放在默认的/tmp目录下,实际中多是一台单独的session服务器,好比,memcached

1
2
session .save_handler = memcache
session .save_path = "tcp://192.168.3.42:11211"

 

安全模式可根据实际业务需求选择性开启,安全模式的意思就是操做文件的函数只能操做与php进程UID相同的文件,但php进程的uid并不必定就是web服务用户的uid,这也就形成了麻烦,也就是说,你想避免这种麻烦,可能就须要在最开始配置时就让php进程和web服务使用同一个系统用户身份,但这又正好跟我前面说的相背了,咱们在前面说过,最好把php进程用户和web服务用户分开,这样更容易进行权限控制,另外,高版本的php[ > php5.4 ]已再也不支持安全模式,由于官方可能也以为它并没什么卵用,并且低版本php的安全模式,还可被绕过,因此,若是你用的是低版本的php,请根据自身实际业务作取舍

1
2
safe_mode = On
safe_mode_gid = off

 

限制php单脚本执行时长,防止服务器资源被长期滥用而产生拒绝服务的效果

1
2
3
max_execution_time = 30
max_input_time = 60
memory_limit = 8M

 

关于上传,若是实际的业务根本不涉及到上传,直接把上传功能关掉便可,若是须要上传,再根据需求作出调整便可,对防入侵来说,这里对咱们意义并非很是大

1
2
3
4
file_uploads = On # 开启php上传功能
upload_tmp_dir = # 文件传上来的临时存放目录
upload_max_filesize = 8M # 容许上传文件的文件大小最大为多少
post_max_size = 8M # 经过POST表单给php的所能接收的文件大小最多为多少

 

0x07 利用 chattr 锁定一些不须要常常改动的重要配置文件,如,php-fpm.conf,php.ini,my.cnf…,为了防止chattr工具被别人滥用,你能够把它更名隐藏到系统的某个角落里,用的时候再拿出来

锁定

1
2
3
# chattr +i /usr/local/php/etc/php.ini
# chattr +i /usr/local/php/etc/php-fpm.conf
# chattr +i /etc/my.cnf

 

解锁

1
2
3
# chattr -i /usr/local/php/etc/php.ini
# chattr -i /usr/local/php/etc/php-fpm.conf
# chattr -i /etc/my.cnf

 

0x08 务必勤于关注php官方的高危补丁发布及说明,和其它工具不一样,php 自身bug多,由于关注的人多,搞的人也多,因此暴露出来的各类安全问题也就更多

0x09 最后,告诉你们一个怎么把曾经yum下来的包保留着的办法,在系统断网的状况下也许用的着,只需到yum配置里面去调整下便可,保留的包的路径也在yum配置中定义好了

1
2
# vi /etc/yum.conf
keepcache=1

 



小结:
    至此为止,关于整套LNMP架构的安所有署及优化,也就差很少完成了,咱们关注的点,更多可能仍是集中在防护入侵上,捎带了一点性能优化,这里所给的参数选项基本所有均可直接用于实战部署,但并非全部的参数配置都是必须的,还须要你好好根据本身实际的业务需求作出适当取舍,或者在此基础进行定制改进,有些地方都是基于本身平时实战经验的考量来的,并不必定彻底是对的,若是有性能更好,更安全的方案,也很是欢迎你们一块儿来私信交流 ^_^

相关文章
相关标签/搜索