11.28 限定某个目录禁止解析php

由于网站是可以直接执行php程序的,而因为直接执行php程序这个方便快捷的功能,很多别有用心的人会利用这个功能去做一些恶意的行为,

从而这会导致变成一个漏洞,使其网站奔溃,所以我们搭建网站的时候,有必要把某目录php解析功能给关闭掉。

 核心配置文件内容

    <Directory /data/wwwroot/www.123.com/upload>
        php_admin_flag engine off
    </Directory>

11.28-11.31禁止解析php,user_agent,PHP配置_PHP

检查状态并重新加载。

[root@AliKvn ~]# /usr/local/apache2.4/bin/apachectl -t
Syntax OK
[root@AliKvn ~]# /usr/local/apache2.4/bin/apachectl graceful

curl测试时直接返回了php源代码,并未解析

[root@AliKvn 111.com]# curl -x127.0.0.1:80 111.com/upload/123.php 
<?php
echo "filesmatch";
?>


11.29 限制user_agent

11.28-11.31禁止解析php,user_agent,PHP配置_禁止解析_02

有时候,网站会受到一些cc***,cc***的原理是利用很多肉鸡去同时访问某一个站点,当访问量或者频率达到一定层次,会耗尽服务器资源,从而使之不能正常提供服务。

user agent为什么可以做访问控制?

它的需求背景是,有时候,我们的网站会受到一种***,名叫cc***。这种***的原理就是这个***的人通过一些手段,软件、肉鸡(把别人的服务器,电脑黑了,拿到了相应的权限,可以去控制它),如果想***某网站,它会利用所有肉鸡,全部发动起来,让他们同时去访问某一个站点。可想而知,如果同时让一千台,甚至一万台发出同一个请求去访问站点,无论这些请求是正常的请求还是别的,站点都肯定会崩溃,因为带宽和数据库都会被崩掉。 

但是cc***是有个很明显的规律的,其中这些而已请求的user agent相同或者相似,我们可以通过限制user agent发挥防***的作用。


 user_agent可以理解为浏览器标识

 核心配置文件内容

   <IfModule mod_rewrite.c>
        RewriteEngine on
        RewriteCond %{HTTP_USER_AGENT}  .*curl.* [NC,OR]
        RewriteCond %{HTTP_USER_AGENT}  .*baidu.com.* [NC]
        RewriteRule  .*  -  [F]
    </IfModule>


RewriteCond %{HTTP_USER_AGENT} [NC,OR]定义条件

OR表示or,加了就是表示或者条件,不加就是并且条件。

NC是负略大小写,

RewriteRule  .*  -  [F]

F表示Forbidden


检查状态并重新加载修改。

#apachectl -t
#apachectl graceful

curl测试,可以见到用curl访问111.com的时候,状态码是403,forbidden,规则生效了。

[root@AliKvn ~]# curl -x127.0.0.1:80 111.com/upload/123.php -I
HTTP/1.1 403 Forbidden
Date: Thu, 19 Apr 2018 02:55:31 GMT
Server: Apache/2.4.33 (Unix) PHP/5.6.30
Content-Type: text/html; charset=iso-8859-1

利用curl -A 指定user agent来测试,通过访问

[root@AliKvn ~]# curl -A "123" -x127.0.0.1:80 111.com/123.php -I
HTTP/1.1 200 OK
Date: Thu, 19 Apr 2018 03:00:17 GMT
Server: Apache/2.4.33 (Unix) PHP/5.6.30
X-Powered-By: PHP/5.6.30
Content-Type: text/html; charset=UTF-8

可以查看日志观察访问细节

[root@AliKvn ~]# tail -3  /usr/local/apache2.4/logs/111.com-access_20180419.log 
127.0.0.1 - - [19/Apr/2018:10:55:31 +0800] "HEAD HTTP://111.com/upload/123.php HTTP/1.1" 403 - "-" "curl/7.29.0"
127.0.0.1 - - [19/Apr/2018:10:56:18 +0800] "HEAD HTTP://111.com/123.php HTTP/1.1" 403 - "-" "curl/7.29.0"
127.0.0.1 - - [19/Apr/2018:11:00:17 +0800] "HEAD HTTP://111.com/123.php HTTP/1.1" 200 - "-" "123"


11.30 11.31 PHP相关配置


查看php配置文件位置

可以用php -i 去查找路径(但是这个方法不太精准) 

 /usr/local/php/bin/php -i|grep -i "loaded configuration file"

也可以利用php.info去查找php配置文件php.ini的准确路径(比较准确,建议)

先建立php.info的网页

[root@AliKvn 111.com]# vim index.php 
<?php
phpinfo();

通过web浏览器去查看phpinfo的信息。

11.28-11.31禁止解析php,user_agent,PHP配置_配置_03

其中Loaded Configuration File就是php的配置文件路径信息了。

把php.ini其中一个版本复制到 php的对应目录上

[root@AliKvn 111.com]# cd /usr/local/src/php-7.1.6/
[root@AliKvn php-7.1.6]# cp php.ini-development /usr/local/php7/etc/php.ini


修改安全参数,将比较危险的参数(例如一句话***病毒,就是利用了eval参数,)都禁掉,。如果这些参数被禁掉,那么php也就解析不到这些参数。

disable_functions
eval,assert,popen,passthru,escapeshellarg,escapeshellcmd,passthru,exec,system,chroot,scandir,chgrp,chown,escapeshellcmd,escapeshellarg,shell_exec,proc_get_status,ini_alter,ini_restore,dl,pfsockopen,openlog,syslog,readlink,symlink,leak,popepassthru,stream_socket_server,popen,proc_open,proc_close

11.28-11.31禁止解析php,user_agent,PHP配置_禁止解析_04

除此之外,还可以考虑禁用php.info因为phpinfo有本机相关配置信息 

/usr/local/apache2.4/bin/apachectl -t
Syntax OK
/usr/local/apache2.4/bin/apachectl graceful

通过web访问phpinfo,phpInfo被禁掉访问,变成白页。

11.28-11.31禁止解析php,user_agent,PHP配置_PHP_05


修改以下参数,

定义时区时间,否则会有告警信息

 date.timezone =Asia/Shanghai 或者Asia/Chongqing
display_errors=off

截图

改成off之后,错误信息都将不会输出显示在浏览器页面上,访问页面会变成白页。

截图

curl测试

[root@AliKvn ~]# curl -A "aaa" -x127.0.0.1:80 111.com/index.php

无任何输出,-I查看网页状态

[root@AliKvn ~]# curl -A "aaa" -x127.0.0.1:80 111.com/index.php -I
HTTP/1.1 200 OK
Date: Thu, 19 Apr 2018 08:08:28 GMT
Server: Apache/2.4.33 (Unix) PHP/7.1.6
X-Powered-By: PHP/7.1.6
Content-Type: text/html; charset=UTF-8


log_errors,

定义错误日志是否开启,这里设置为log_errors=on

error_reporting

定义日志级别为  error_reporting = E_ALL & E_NOTICE,

error_log,

定义错误日志路径error_log=/tmp/php_errors.log。定义完这后,还要定义errors的级别.

[root@AliKvn ~]# cat /tmp/php_errors.log

[19-Apr-2018 08:23:14 UTC] PHP Warning:  phpinfo() has been disabled for security reasons in /data/wwwroot/111.com/index.php on line 2

所属主跟所属组都是daemon,其实它跟httpd的所属主组是一样的,所以当php_errors发生错误的时候,可以检查httpd的状态,或者权限。

#ls -l /tmp/php_errors.log
-rw-r--r-- 1 daemon daemon 135 Apr 19 16:23 /tmp/php_errors.log


配置open_basedir

例如一台服务器上跑了好多个站点服务,结果其中一个被黑了。有可能会在其中一个站点获得信息连累到其他站点。

还好PHP有一个概念叫做open_basedir,他的作用是将网站限定在指定目录里,就算该站点被黑了,***只能在该目录下面有所作为,而不能左右其他目录。

编辑php.ini配置文件,添加如下参数

#vim php.ini
open_basedir =/data/wwwroot/111.com:/tmp

curl访问测试

[root@AliKvn 111.com]# curl -A "aaa" -x127.0.0.1:80 111.com/123.php  
filesmatch[root@AliKvn 111.com]# curl -A "aaa" -x127.0.0.1:80 111.com/123.php  -I
HTTP/1.1 200 OK
Date: Thu, 19 Apr 2018 09:03:44 GMT
Server: Apache/2.4.33 (Unix) PHP/7.1.6
X-Powered-By: PHP/7.1.6
Content-Type: text/html; charset=UTF-8

能正常访问,因为111.com在安全目录下。

由上述实验结果可知,在php.ini配置open_basedir只是只能针对一个目录,如果多个站点,况且php.ini是针对所有站点的,然而这是起不到什么作用的,。

所以,可以选择在http-vhost编辑参数php_admin_value open_basedir "/data/wwwroot/111.com:/tmp/"

11.28-11.31禁止解析php,user_agent,PHP配置_配置_06

在普通虚拟主机111.comcurl测试

[root@AliKvn 111.com]# !curl
curl -A "aaa" -x127.0.0.1:80 111.com/123.php  -I
HTTP/1.1 200 OK
Date: Thu, 19 Apr 2018 09:19:50 GMT
Server: Apache/2.4.33 (Unix) PHP/7.1.6
X-Powered-By: PHP/7.1.6
Content-Type: text/html; charset=UTF-8


在默认虚拟主机abc.comcurl测试

[root@AliKvn 111.com]# curl -x127.0.0.1:80 abc.com/index.php
abc.com[root@AliKvn 111.com]# curl -x127.0.0.1:80 abc.com/index.php -I
HTTP/1.1 200 OK
Date: Thu, 19 Apr 2018 09:22:42 GMT
Server: Apache/2.4.33 (Unix) PHP/7.1.6
X-Powered-By: PHP/7.1.6
Content-Type: text/html; charset=UTF-8

由此证明,安全目录open_basedir是可以在httpd-vhost是创建多个安全目录。