11.28 限定某个目录禁止解析php
对于使用PHP语言编写的网站,有一些目录是有需求上传文件的,比如服务器可以上传图片,并且没有做防盗链,所以就会被人家当成了一个图片存储服务器,并且盗用带宽流量。如果网站代码有漏洞,让***上传了一个用PHP代码写的***,由于网站可以执行PHP程序,最终会让***拿到服务器权限,为了避免这种情况发生,我们需要把能上传文件的目录直接禁止解析PHP代码(不用担心会影响网站访问,若这种目录也需要解析PHP,那说明程序员不合格)
1. 修改虚拟主机配置文件
vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf
添加核心配置如下:
<Directory /data/wwwroot/abc.com/upload>
php_admin_flag engine off
<FilesMatch (.*)\.php(.*)>
Order allow,deny
Deny from all
</FilesMatch>
</Directory>
最终保存配置:
说明:
php_admin_flag engine off //这一段就可以禁止解析PHP代码 <FilesMatch (.*)\.php(.*)> //这一段就是让php的文件访问受到限制,防止php文件的源代码被查看
2.再检查语法加载配置和创建upload目录、php文件
/usr/local/apache2.4/bin/apachectl -t //小技巧(快捷键 ctrl+R 再输入 -t )
/usr/local/apache2.4/bin/apachectl graceful
mkdir /data/wwwroot/abc.com/upload
vim /data/wwwroot/abc.com/upload/123.php
3. 使用curl测试
curl -x127.0.0.1:80 abc.com/upload/123.php -I
返回403,直接限制访问
3.1 只让 php_admin_flag engine off 生效
能访问但是不能正常解析php
11.29 限制user_agent
user_agent可以理解为浏览器标识,针对user_agent来限制一些访问,比如可以限制一些不太友好的搜索引擎“爬虫”,你之所以能在百度搜到一些论坛,就是因为百度会派一些“蜘蛛爬虫”过来抓取网站数据。“蜘蛛爬虫”抓取数据类似于用户用浏览器访问网站,当“蜘蛛爬虫”太多或者访问太频繁,就会浪费服务器资源。另外,也可以限制恶意请求,这种恶意请求我们通常称作cc***,他的原理很简单,就是用很多用户的电脑同时访问同一个站点,当访问量或者频率达到一定层次,会耗尽服务器资源,从而使之不能正常提供服务。这种cc***其实有很明显的规律,其中这些恶意请求的user_agent相同或者相似,那我们就可以通过限制user_agent发挥防***的作用。
1. 修改虚拟主机配置文件
vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf
添加核心配置如下:
<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} .*curl.* [NC,OR] //OR是或者的意思, user_agent匹配curl或者匹配baidu.com RewriteCond %{HTTP_USER_AGENT} .*baidu.com.* [NC] //NC是忽略大小写 RewriteRule .* - [F] //F是Forbidden
2.再检查语法和加载配置
/usr/local/apache2.4/bin/apachectl -t
/usr/local/apache2.4/bin/apachectl graceful
3.使用curl测试如下:
curl -x127.0.0.1:80 abc.com/upload/123.php -I //返回403直接禁止访问
4.指定user_agent,如果不指定user_agent,那么curl作为user_agent会被限制访问,从上面测试可以看出
curl -A "cfk cfk" -x127.0.0.1:80 abc.com/upload/123.php -I
5.查看一下日志
tail /usr/local/apache2.4/logs/abc.com-access_20180602.log
curl 说明:
使用参数 -A 指定了它的user_agent后就可以访问。
使用参数 -e 指定referer
使用参数 -x 相对省略本地绑定hosts
使用参数 -I 查看状态码
11.30-11.31 php相关配置
虽然PHP是以httpd一个模块的形式存在,但是PHP本身也有自己的配置文件。
1.1 网页访问:http://47.97.163.117/index.php
php.ini为PHP的配置文件,可以看出其在/usr/local/php7/etc/php.ini。
1.2 php配置文件己经加载Loaded Configuration File 如果没有加载做以下配置:
cp php.ini-development /usr/local/php7/etc/php.ini
/usr/local/apache2.4/bin/apachectl graceful
PHP有诸多的内置的函数,有一些函数(比如exec)会直接调取linux的系统命令,如果开放将会非常危险,因此,基于安全考虑应该把一些存在安全风险的函数禁掉。
2.1编辑php.inin配置文件,搜索disable_functions,添加配置
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
/usr/local/apache2.4/bin/apachectl graceful
2.2测试加上了phpinfo函数,所以访问index.php时结果无内容显示:
(测试后重新进php.ini配置文件将 phpinfo去掉,访问正常)
3.PHP配置文件定义date.timezone,如果不定义会导致有告警信息
vim /usr/local/php7/etc/php.ini // 搜索date.timezone 输入以下配置
/usr/local/apache2.4/bin/apachectl graceful
PHP的日志对于程序员来讲非常重要,它是排查问题的重要手段。
如果加上了phpinfo函数后,浏览器上访问http://abccom/index.php 就会有信息输出,这样也暴露的地址目录,相对来说也不安全,我们需要把报错信息也隐藏掉,操作如下:
vim /usr/local/php7/etc/php.ini // 搜索display_errors 输入以下配置
/usr/local/apache2.4/bin/apachectl graceful
总结:配置了display_errors = Off后,浏览器访问没有任何输出信息,一片空白,使用curl输出也是一样,这样我们就无法判断是否有问题,所以需要配置错误日志。
vim /usr/local/php7/etc/php.ini
定义如下: //搜索log_errors 改为 log_errors =On //搜索error_log 改为 /tmp/php_errors.log //搜索error_reporting 改为 error_reporting = E_ALL //搜索display_errors 改为 display_errors = Off
开启日志后还要定义对应的保存路径:error_log,我们设置在/tmp下
定义完路径后,我们还要对它进行一个级别设置:error_reporting,E_ALL是最不严谨的级别:
一个服务器上跑很多网站,小公司为节省成本采用的做法,这样操作是会有一些弊端:多个网站跑在同一个服务器上,如果其中一个网站被黑,很有可能会连累到其他站点,为了避免这种尴尬的事情发生,我们应当作一些预防手段。
PHP有一个概念叫作open_basedir,它的作用是将网站限定在指定目录里,就算该站点被黑了,***只能在该目录下面有所作为,而不能左右其他目录。如果你的服务器上只有一个站点,那可以直接在php.ini中设置open_basedir参数。但如果服务器上跑的站点比较多,那在php.ini中设置就不合适了,因为在php.ini中只能定义一次,也就是说所有站点都一起定义限定的目录,那这样似乎起不到隔离多个站点的目的。
5.1我们先来创建一个2.php,输入内容保存后再来做实验:
vim /data/wwwroot/abc.com/2.php
vim /usr/local/php7/etc/php.ini //定义open_basedir
open_basedir =/data/wwwroot/abc.com:/tmp
curl -A "cfk" -x127.0.0.1:80 abc.com/2.php -I
5.3 如果我们定义open_basedir = /data/wwwroot/abcd.com:/tmp 时,我们再来实验一下:
vim /usr/local/php7/etc/php.ini //定义open_basedir
open_basedir =/data/wwwroot/abcd.com:/tmp
/usr/local/apache2.4/bin/apachectl graceful
curl -A "c" -x127.0.0.1:80 abc.com/2.php -I