linux 学习笔记-044-访问控制,禁止解析 php,限制 user_agent,php 相关配置

发布于 2018-03-07  483 次阅读


限定某个目录禁止解析 php

假如一个站点有一个目录是可以上传图片的,这时就有可能被某些别有用心的人上传了.php 文件,而.php 文件是可以执行的,php 有一些危险的函数,如果开放了上传权限,有可能会被上传一些恶意木马文件,这将有可能导致系统 root 权限被非法取得

知识扩展:

SQL 注入漏洞:把查询的 SQL 通过特殊的提交,提交到服务器,服务器把 SQL 语句转化为正常的查询,最终获取得一些数据(可以通过在网站提交输入的地方增加验证过滤阻断这个 SQL 注入漏洞)

一句话木马:简单来讲,就是直接获取服务器权限

[root@am-01:~#] vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf

    <Directory /data/wwwroot/111.com/upload>

        php_admin_flag engine off

#禁止解析 php,用这句即可

        <FilesMatch "(.*)\.php(.*)">

        Order allow,deny

        Deny from all

        </FilesMatch>

#加上<FilesMatch></FilesMatch>的内容,如果不加上,访问/data/wwwroot/111.com/upload 目录下的.php 文件时会显示源代码,这样不友好,建议使用<FilesMatch></FilesMatch>返回 403

    </Directory>

[root@am-01:~#] /usr/local/apache2.4/bin/apachectl -t

Syntax OK

[root@am-01:~#] /usr/local/apache2.4/bin/apachectl graceful

#在虚拟主机配置文件中添加以上设置,使/data/wwwroot/111.com/upload 目录下的 php 文件不解析,并且返回 403

#最后测试一下配置文件的正确性和重载一下配置文件

测试 01:

[root@am-01:~#] cd /data/wwwroot/111.com/

[root@am-01:/data/wwwroot/111.com#] mkdir upload

[root@am-01:/data/wwwroot/111.com#] cp 123.php upload/

[root@am-01:/data/wwwroot/111.com#] ls upload/

123.php

[root@am-01:/data/wwwroot/111.com#] curl -x127.0.0.1:80 111.com/upload/123.php -I

HTTP/1.1 403 Forbidden

Date: Wed, 07 Mar 2018 14:58:55 GMT

Server: Apache/2.4.29 (Unix) PHP/7.1.6

Content-Type: text/html; charset=iso-8859-1

#可以见到,设置是成功的,这里的测试是设置了<FilesMatch></FilesMatch>的状态下

测试 02:

[root@am-01:/data/wwwroot/111.com#] vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf

  <Directory /data/wwwroot/111.com/upload>

      php_admin_flag engine off

      #<FilesMatch "(.*)\.php(.*)">

      #Order allow,deny

      #Deny from all

      #</FilesMatch>

  </Directory>

[root@am-01:/data/wwwroot/111.com#] /usr/local/apache2.4/bin/apachectl -t

Syntax OK

[root@am-01:/data/wwwroot/111.com#] /usr/local/apache2.4/bin/apachectl graceful

[root@am-01:/data/wwwroot/111.com#] curl -x127.0.0.1:80 111.com/upload/123.php

<?php

phpinfo();

#可见,如果不设置<FilesMatch></FilesMatch>,则会返回页面的源代码

限制 user_agent

有时候网站会受到 CC 攻击,而这种 CC 攻击,user_agent 一般都是一致的,这时就可以通过限制 user_agent 实现减轻服务器压力

知识扩展:

CC 攻击:攻击的人通过一些手段、软件或肉鸡(把别人服务器或电脑黑了,控制他们的电脑)同时向某个站点发起访问,把网站服务器搞垮

[root@am-01:~#] vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf

  <IfModule mod_rewrite.c>

      RewriteEngine on

#让 rewrite 功能启用

      RewriteCond %{HTTP_USER_AGENT}  .*curl.* [NC,OR]

      RewriteCond %{HTTP_USER_AGENT}  .*baidu.com.* [NC]

#定义条件,OR 是指或的意思,即 USER_AGENT 匹配上一条规则或者下一条规则,NC 表示忽略大小写,用法一般为 .*关键词.*

      RewriteRule  .*  -  [F]

#指定返回 403 状态

  </IfModule>

[root@am-01:~#] /usr/local/apache2.4/bin/apachectl -t

Syntax OK

[root@am-01:~#] /usr/local/apache2.4/bin/apachectl graceful

#在虚拟主机配置文件添加 mod_rewrite 模块配置信息,测试一下配置文件的正确性和重载一下配置文件

测试 01:

[root@am-01:~#] curl -x127.0.0.1:80 111.com/123.php

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">

<html><head>

<title>403 Forbidden</title>

</head><body>

<h1>Forbidden</h1>

<p>You don't have permission to access /123.php

on this server.<br />

</p>

</body></html>

[root@am-01:~#] tail /usr/local/apache2.4/logs/111.com-access_20180307_log

127.0.0.1 - - [07/Mar/2018:23:33:11 +0800] "GET HTTP://111.com/123.php HTTP/1.1" 403 216 "-" "curl/7.29.0"

#可以见到 curl 这个 user_agent 已经被禁止访问站点,并且返回 403

测试 02:

[root@am-01:~#] curl -A"am am" -x127.0.0.1:80 111.com/123.php -I

HTTP/1.1 200 OK

Date: Wed, 07 Mar 2018 15:39:02 GMT

Server: Apache/2.4.29 (Unix) PHP/7.1.6

X-Powered-By: PHP/7.1.6

Content-Type: text/html; charset=UTF-8

[root@am-01:~#] tail /usr/local/apache2.4/logs/111.com-access_20180307_log

127.0.0.1 - - [07/Mar/2018:23:39:02 +0800] "HEAD HTTP://111.com/123.php HTTP/1.1" 200 - "-" "am am"

#可以看出,使用-A 参数指定 user_agent 为“am am”后可以正常访问站点

curl 常用参数:

-x:类似于指定 hosts

-I:查看返回的状态码

-e:指定 referer

-A:指定 user_agent

PHP 相关配置

[root@am-01:~#] /usr/local/php/bin/php -i | grep -i "loaded configuration file"

Loaded Configuration File => /usr/local/php/etc/php.ini

#可以使用以上命令查找 php 的配置文件在哪,但是有可能这里显示的 php 配置文件并不是站点在使用的 php 配置文件,所以建议在当前站点目录下创建一个 php 页面,使用 <?php phpinfo(); ?> 来确定站点使用的 php 配置文件

模拟利用 <?php phpinfo(); ?> 查找站点的 php 配置文件

[root@am-01:~#] vim /data/wwwroot/111.com/index.php

<?php

phpinfo();

?>

#修改 index.php 的内容

使用客户端浏览器测试,可见当前站点的 php 配置文件是/usr/local/php7/etc/php.ini

linux 学习笔记-044-访问控制,禁止解析 php,限制 user_agent,php 相关配置

php 的危险函数:一句话木马用到了 eval 函数

[root@am-01:~#] vim /usr/local/php7/etc/php.ini

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,phpinfo

[root@am-01:~#] /usr/local/apache2.4/bin/apachectl -t

Syntax OK

[root@am-01:~#] /usr/local/apache2.4/bin/apachectl graceful

#一般建议把以上列出的危险函数关闭,同时也建议把 phpinfo 函数也关闭,因为 phpinfo 函数会泄露大量的服务器信息,最后测试一下配置文件的正确性和重载一下配置文件

测试 disable_functions 的效果:可以见到访问调用了 <?php phpinfo(); ?> 的页面返回了一个空白页面(这是因为 php.ini 里面设置了 display_errors = Off)

linux 学习笔记-044-访问控制,禁止解析 php,限制 user_agent,php 相关配置

当 display_errors = On,则会在页面提示错误信息,为了方便之后做实验,做完这个实验后记得把 phpinfo 函数启用

linux 学习笔记-044-访问控制,禁止解析 php,限制 user_agent,php 相关配置

date.timezone 用来定义时区,如果不定义,有时候可能会提示告警信息

[root@am-01:~#] vim /usr/local/php7/etc/php.ini

date.timezone = Asia/Shanghai

[root@am-01:~#] /usr/local/apache2.4/bin/apachectl -t

Syntax OK

[root@am-01:~#] /usr/local/apache2.4/bin/apachectl graceful

display_errors 用来设置是否把错误信息输出到浏览器中,在测试 disable_functions 的效果的时候已经有提到

display_errors 设置为 Off 后,没有了错误输出到页面,这时就需要配置错误日志,以便查看错误信息(这里先把 phpinfo 添加到 disable_functions 中)

[root@am-01:~#] vim /usr/local/php7/etc/php.ini

  log_errors = On

#开启 error 错误日志功能

  error_log = /tmp/php_errors.log

#设置错误日志存放位置

  error_reporting = E_ALL

#设置错误日志的记录级别,这里设置为记录所有,在生产环境中一般设置为 “E_ALL & ~E_NOTICE”

[root@am-01:~#] /usr/local/apache2.4/bin/apachectl -t

Syntax OK

[root@am-01:~#] /usr/local/apache2.4/bin/apachectl graceful

#测试一下配置文件的正确性和重载一下配置文件
[root@am-01:~#] curl -A"am am" -x127.0.0.1:80 111.com/123.php

[root@am-01:~#] ls -l /tmp/php_errors.log

-rw-r--r-- 1 daemon daemon 143 3 月   8 00:49 /tmp/php_errors.log

[root@am-01:~#] ps -aux | grep httpd

root      60820  0.0  1.4 263180 14136 ?        Ss   2 月 28   0:34 /usr/local/apache2.4/bin/httpd

daemon    85706  0.0  1.0 550008 10500 ?        Sl   00:47   0:00 /usr/local/apache2.4/bin/httpd

daemon    85707  0.0  1.4 617656 14948 ?        Sl   00:47   0:00 /usr/local/apache2.4/bin/httpd

daemon    85708  0.0  1.0 550008 10496 ?        Sl   00:47   0:00 /usr/local/apache2.4/bin/httpd

root      85814  0.0  0.0 112676   980 pts/0    S+   00:50   0:00 grep --color=auto httpd

[root@am-01:~#] cat /tmp/php_errors.log

[08-Mar-2018 00:49:05 Asia/Shanghai] PHP Warning:  phpinfo() has been disabled for security reasons in /data/wwwroot/111.com/123.php on line 2

#测试是否有生成 php_errors.log,同时查看所属用户及所属组,如果没有生成 php_errors.log,则需要检查 httpd 的用户是哪个,并且确定 httpd 的用户有权限访问、写入存放 php_errors.log 文件的目录

open_basedir:

一台服务器上跑着多个站点,有可能某个站点漏洞多,被黑,这时继续往里面渗透,就有可能把其他站点也黑了,定义了 open_basedir 参数,即就算一个服务器有多个站点,某个站点被黑,也不用担心波及其他站点

当设置错误的时候:

[root@am-01:~#] vim /usr/local/php7/etc/php.ini

open_basedir = /data/wwwroot/1111.com:tmp

[root@am-01:~#] /usr/local/apache2.4/bin/apachectl -t

Syntax OK

[root@am-01:~#] /usr/local/apache2.4/bin/apachectl graceful

[root@am-01:~#] vim /data/wwwroot/111.com/2.php

[root@am-01:~#] curl -A"am am" -x127.0.0.1:80 111.com/2.php

[root@am-01:~#] cat /tmp/php_errors.log

[08-Mar-2018 00:49:05 Asia/Shanghai] PHP Warning:  phpinfo() has been disabled for security reasons in /data/wwwroot/111.com/123.php on line 2

[08-Mar-2018 01:12:29 Asia/Shanghai] PHP Warning:  Unknown: open_basedir restriction in effect. File(/data/wwwroot/111.com/2.php) is not within the allowed path(s): (/data/wwwroot/1111.com:tmp) in Unknown on line 0

[08-Mar-2018 01:12:29 Asia/Shanghai] PHP Warning:  Unknown: failed to open stream: Operation not permitted in Unknown on line 0

[08-Mar-2018 01:12:29 Asia/Shanghai] PHP Fatal error:  Unknown: Failed opening required '/data/wwwroot/111.com/2.php' (include_path='.:/usr/local/php7/lib/php') in Unknown on line 0

[root@am-01:~#] vim /usr/local/php7/etc/php.ini

#当设置错误的时候可以见到,提示 2.php 并没有在允许的目录下,所以会提示错误,无法访问

当设置正确的时候:

[root@am-01:~#] vim /usr/local/php7/etc/php.ini

open_basedir = /data/wwwroot/111.com:tmp

[root@am-01:~#] /usr/local/apache2.4/bin/apachectl -t

Syntax OK

[root@am-01:~#] /usr/local/apache2.4/bin/apachectl graceful

[root@am-01:~#] curl -A"am am" -x127.0.0.1:80 111.com/2.php -I

HTTP/1.1 200 OK

Date: Wed, 07 Mar 2018 17:15:40 GMT

Server: Apache/2.4.29 (Unix) PHP/7.1.6

X-Powered-By: PHP/7.1.6

Content-Type: text/html; charset=UTF-8

#当设置正确的时候,能正常访问

想限制单个站点的话,使用 php.ini 的 open_basedir 是做不到的,php.ini 的 open_basedir 是针对所有站点的,这时就需要在 apache 的虚拟主机配置文件做修改

[root@am-01:~#] vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf

<VirtualHost *:80>

    DocumentRoot "/data/wwwroot/abc.com"

    ServerName abc.com

    ServerAlias www.abc.com www.123.com

    php_admin_value open_basedir "/data/wwwroot/abc.com:/tmp/"

    ErrorLog "logs/abc.com-error_log"

    CustomLog "logs/abc.com-access_log" common

</VirtualHost>



<VirtualHost *:80>

    DocumentRoot "/data/wwwroot/111.com"

    ServerName 111.com

    ServerAlias www.example.com

    php_admin_value open_basedir "/data/wwwroot/111.com:/tmp/"

    ErrorLog "logs/111.com-error_log"

    SetEnvIf Request_URI ".*\.gif$" img

    SetEnvIf Request_URI ".*\.jpg$" img

    SetEnvIf Request_URI ".*\.png$" img

    SetEnvIf Request_URI ".*\.bmp$" img

    SetEnvIf Request_URI ".*\.swf$" img

    SetEnvIf Request_URI ".*\.js$" img

    SetEnvIf Request_URI ".*\.css$" img

    CustomLog "|/usr/local/apache2.4/bin/rotatelogs -l logs/111.com-access_%Y%m%d_log 86400" combined env=!img

</VirtualHost>

#在每一个站点的配置信息下,添加对应站点的限制目录,这样就可以做到针对单个站点的限制

#/tmp 目录不能缺,例如上传图片的时候会先临时把图片放到/tmp 目录下,然后再放到这图片该在的位置,如果不写/tmp,那么连上传图片都做不了

扩展

apache 开启压缩:

http://ask.apelearn.com/question/5528

apache2.2 到 2.4 配置文件变更:

http://ask.apelearn.com/question/7292

apache options 参数:

http://ask.apelearn.com/question/1051

apache 禁止 trace 或 track 防止 xss:

http://ask.apelearn.com/question/1045

apache 配置 https 支持 ssl:

http://ask.apelearn.com/question/1029