1. 程式人生 > >apache2.4限定某個目錄禁止解析PHP、限制user_agent、PHP相關配置

apache2.4限定某個目錄禁止解析PHP、限制user_agent、PHP相關配置

Linux

限定某個目錄禁止解析PHP

對於使用PHP語言編寫的網站,有一些目錄是有需求上傳文件的,比如服務器可以上傳圖片,並且沒有做防盜鏈,所以就會被人家當成了一個圖片存儲服務器,並且盜用帶寬流量。如果網站代碼有漏洞,讓黑客上傳了一個用PHP代碼寫的木馬,由於網站可以執行PHP程序,最終會讓黑客拿到服務器權限,為了避免這種情況發生,我們需要把能上傳文件的目錄直接禁止解析PHP代碼(不用擔心會影響網站訪問,若這種目錄也需要解析PHP,那說明程序員不合格)


1. 修改虛擬主機配置文件

[root@gary-tao ~]# vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf


核心配置文件內容:


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

php_admin_flag engine off //這一段就可以禁止解析PHP代碼

<FilesMatch (.*)\.php(.*)> //這一段就是讓php的文件訪問受到限制,防止php文件的源代碼被查看

Order allow,deny

Deny from all

</FilesMatch>

</Directory>


[root@gary-tao 111.com]# /usr/local/apache2.4/bin/apachectl -t

Syntax OK //測試語法

[root@gary-tao 111.com]# /usr/local/apache2.4/bin/apachectl graceful //加載配置

[root@gary-tao 111.com]# mkdir upload //創建一個upload目錄

[root@gary-tao 111.com]# ls

123.php admin index.php qq.png upload

[root@gary-tao 111.com]# cp 123.php upload/


修改後示例圖

技術分享圖片


2. 使用curl測試時返回403

[root@gary-tao 111.com]# curl -x172.16.111.100:80 'http://111.com/upload/123.php' -I //直接不給訪問權限

HTTP/1.1 403 Forbidden

Date: Tue, 26 Dec 2017 06:19:17 GMT

Server: Apache/2.4.29 (Unix) PHP/7.1.6

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


測試需要把下面配置先禁止掉:


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

Order allow,deny

Deny from all

</FilesMatch>


[root@gary-tao 111.com]# /usr/local/apache2.4/bin/apachectl -t

Syntax OK

[root@gary-tao 111.com]# /usr/local/apache2.4/bin/apachectl graceful


修改後示例圖:

技術分享圖片


禁止掉後使用curl後的測試結果:

[root@gary-tao 111.com]# curl -x127.0.0.1:80 'http://111.com/upload/123.php' //下例信息說明123.php不能正常解析

<?php

echo "123.php";

?>



限制user_agent

user_agent可以理解為瀏覽器標識,針對user_agent來限制一些訪問,比如可以限制一些不太友好的搜索引擎“爬蟲”,你之所以能在百度搜到一些論壇,就是因為百度會派一些“蜘蛛爬蟲”過來抓取網站數據。“蜘蛛爬蟲”抓取數據類似於用戶用瀏覽器訪問網站,當“蜘蛛爬蟲”太多或者訪問太頻繁,就會浪費服務器資源。另外,也可以限制惡意請求,這種惡意請求我們通常稱作cc攻擊,他的原理很簡單,就是用很多用戶的電腦同時訪問同一個站點,當訪問量或者頻率達到一定層次,會耗盡服務器資源,從而使之不能正常提供服務。這種cc攻擊其實有很明顯的規律,其中這些惡意請求的user_agent相同或者相似,那我們就可以通過限制user_agent發揮防攻擊的作用。


1. 針對user_agent來做訪問限制的核心配置文件內容

[root@gary-tao 111.com]# vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf


核心配置文件內容

<IfModule mod_rewrite.c>

RewriteEngine on

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

</IfModule>


[root@gary-tao 111.com]# /usr/local/apache2.4/bin/apachectl -t

Syntax OK

[root@gary-tao 111.com]# /usr/local/apache2.4/bin/apachectl graceful


修改配置示例如下圖:

技術分享圖片


2.使用curl測試如下:

[root@gary-tao 111.com]# curl -x127.0.0.1:80 'http://111.com/upload/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 /upload/123.php

on this server.<br />

</p>

</body></html>

[root@gary-tao 111.com]# curl -x127.0.0.1:80 'http://111.com/upload/123.php' -I

HTTP/1.1 403 Forbidden

Date: Tue, 26 Dec 2017 07:03:42 GMT

Server: Apache/2.4.29 (Unix) PHP/7.1.6

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


3.指定user_agent,如果不指定user_agent,那麽curl作為user_agent會被限制訪問,從上面測試可以看出。

示例如下:

[root@gary-tao 111.com]# curl -A "xietao xietao" -x127.0.0.1:80 'http://111.com/upload/123.php' -I

HTTP/1.1 200 OK

Date: Tue, 26 Dec 2017 07:08:20 GMT

Server: Apache/2.4.29 (Unix) PHP/7.1.6

Last-Modified: Tue, 26 Dec 2017 06:16:53 GMT

ETag: "19-561383aa99f09"

Accept-Ranges: bytes

Content-Length: 25

Cache-Control: max-age=0

Expires: Tue, 26 Dec 2017 07:08:20 GMT

Content-Type: application/x-httpd-php


[root@gary-tao 111.com]# tail /usr/local/apache2.4/logs/111.com-access_20171226.log //查看日誌

127.0.0.1 - - [26/Dec/2017:14:25:40 +0800] "HEAD http://111.com/upload/123.php HTTP/1.1" 200 - "-" "curl/7.29.0"

127.0.0.1 - - [26/Dec/2017:14:26:52 +0800] "GET http://111.com/upload/123.php HTTP/1.1" 200 25 "-" "curl/7.29.0"

172.16.111.1 - - [26/Dec/2017:14:29:07 +0800] "GET / HTTP/1.1" 200 12 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0"

172.16.111.1 - - [26/Dec/2017:14:29:16 +0800] "GET /123.php HTTP/1.1" 200 7 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0"

172.16.111.1 - - [26/Dec/2017:14:29:31 +0800] "GET /uploab/123.php HTTP/1.1" 404 212 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0"

172.16.111.1 - - [26/Dec/2017:14:29:43 +0800] "GET /upload/123.php HTTP/1.1" 200 25 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0"

172.16.111.1 - - [26/Dec/2017:14:29:44 +0800] "GET /upload/123.php HTTP/1.1" 200 25 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0"

127.0.0.1 - - [26/Dec/2017:15:03:15 +0800] "GET http://111.com/upload/123.php HTTP/1.1" 403 223 "-" "curl/7.29.0"

127.0.0.1 - - [26/Dec/2017:15:03:42 +0800] "HEAD http://111.com/upload/123.php HTTP/1.1" 403 - "-" "curl/7.29.0"

127.0.0.1 - - [26/Dec/2017:15:08:20 +0800] "HEAD http://111.com/upload/123.php HTTP/1.1" 200 - "-" "xietao xietao"


解釋說明:

常用配置選項:

使用參數 -A 指定了它的user_agent後就可以訪問。

使用參數 -e 指定referer

使用參數 -x 相對省略本地綁定hosts

使用參數 -I 查看狀態碼



php相關配置

雖然PHP是以httpd一個模塊的形式存在,但是PHP本身也有自己的配置文件。


1. 查看PHP配置文件位置

[root@gary-tao 111.com]# ls

123.php admin index.php qq.png upload

[root@gary-tao 111.com]# vi index.php //編輯index文件,輸入以下內容,保存退出。


<?php

phpinfo();

?>


瀏覽器訪問:http://111.com/index.php

技術分享圖片



復制源碼包裏開發配置文件

[root@gary-tao 111.com]# cd /usr/local/src/php-7.1.6

[root@gary-tao php-7.1.6]# cp php.ini-development /usr/local/php7/etc/php.ini

[root@gary-tao php-7.1.6]# /usr/local/apache2.4/bin/apachectl graceful //重新加載配置


結果如下圖:

技術分享圖片


解釋說明:

php.ini為PHP的配置文件,可以看出其在/usr/local/php7/etc/php.ini。


2.PHP的disable_functions

PHP有諸多的內置的函數,有一些函數(比如exec)會直接調取linux的系統命令,如果開放將會非常危險,因此,基於安全考慮應該把一些存在安全風險的函數禁掉。

示例如下:

[root@gary-tao php-7.1.6]# 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@gary-tao php-7.1.6]# /usr/local/apache2.4/bin/apachectl graceful //重新加載配置


因為加上了phpinfo函數,所以訪問index.php時結果如下:

技術分享圖片

3.定義date.timezone,如果不定義會導致有告警信息

[root@gary-tao php-7.1.6]# vim /usr/local/php7/etc/php.ini //找到date.timezone

定義如下:

date.timezone = Asia/Shangahi(或Chongqing)


示例圖如下:

技術分享圖片


4. 配置 error_log

PHP的日誌對於程序員來講非常重要,它是排查問題的重要手段。

如果加上了phpinfo函數後,瀏覽器上訪問http://111.com/index.php 就會有信息輸出,這樣也暴露的地址目錄,相對來說也不安全,我們需要把報錯信息也隱藏掉,操作如下:

[root@gary-tao php-7.1.6]# vim /usr/local/php7/etc/php.ini //搜索display_errors

定義如下:

display_errors = Off

[root@gary-tao php-7.1.6]# /usr/local/apache2.4/bin/apachectl graceful


修改示意圖

技術分享圖片


瀏覽訪問結果如下:

技術分享圖片


使用curl測試如下:

[root@gary-tao php-7.1.6]# curl -A "xietao xietao" -x127.0.0.1:80 'http://111.com/index.php'

[root@gary-tao php-7.1.6]# curl -A "xietao xietao" -x127.0.0.1:80 'http://111.com/index.php' -I

HTTP/1.1 200 OK

Date: Tue, 26 Dec 2017 09:02:01 GMT

Server: Apache/2.4.29 (Unix) PHP/7.1.6

X-Powered-By: PHP/7.1.6

Cache-Control: max-age=0

Expires: Tue, 26 Dec 2017 09:02:01 GMT

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


總結:配置了display_errors = Off後,瀏覽器訪問沒有任何輸出信息,一片空白,使用curl輸出也是一樣,這樣我們就無法判斷是否有問題,所以需要配置錯誤日誌。


修改配置日誌示例如下:

[root@gary-tao php-7.1.6]# vim /usr/local/php7/etc/php.ini

定義如下:

//搜索log_errors 改為 log_errors =On

//搜索error_log 改為 /tmp/php/php_errors.log

//搜索error_reporting 改為 error_reporting = E_ALL & ~E_NOTICE

//搜索display_errors 改為 display_errors = Off


[root@gary-tao php-7.1.6]# /usr/local/apache2.4/bin/apachectl -t

Syntax OK

[root@gary-tao php-7.1.6]# /usr/local/apache2.4/bin/apachectl graceful

[root@gary-tao php-7.1.6]# curl -A "xietao xietao" -x127.0.0.1:80 'http://111.com/index.php'

[root@gary-tao php-7.1.6]# ls /tmp/

pear php_errors.log systemd-private-c13d62a36c594e09a55010e8f304eb60-vmtoolsd.service-1qgl8W

[root@gary-tao php-7.1.6]# ls -l /tmp/php_errors.log

-rw-r--r-- 1 daemon daemon 290 12月 26 17:13 /tmp/php_errors.log

[root@gary-tao php-7.1.6]# ps aux |grep httpd

root 5358 0.0 1.4 260000 14804 ? Ss 12月19 0:37 /usr/local/apache2.4/bin/httpd -k graceful

daemon 14250 0.0 1.3 546828 13604 ? Sl 17:13 0:00 /usr/local/apache2.4/bin/httpd -k graceful

daemon 14251 0.0 1.1 546828 11580 ? Sl 17:13 0:00 /usr/local/apache2.4/bin/httpd -k graceful

daemon 14252 0.0 1.8 682124 18552 ? Sl 17:13 0:00 /usr/local/apache2.4/bin/httpd -k graceful

root 14340 0.0 0.0 112680 972 pts/0 S+ 17:15 0:00 grep --color=auto httpd

[root@gary-tao php-7.1.6]# grep error_log /usr/local/php7/etc/php.ini

; server-specific log, STDERR, or a location specified by the error_log

; Set maximum length of log_errors. In error_log information about the source is

error_log = /tmp/php_errors.log

;error_log = syslog

; OPcache error_log file name. Empty string assumes "stderr".

;opcache.error_log=

[root@gary-tao php-7.1.6]# touch /tmp/php_errors.log ; chmod 777 /tmp/php_errors.log //因為日誌用戶是daemon,日誌是隨著httpd的服務啟動,為了保證PHP的錯誤日誌所在目錄存在,並且有權限為可寫。

[root@gary-tao php-7.1.6]# cat /tmp/php_errors.log

[26-Dec-2017 17:13:35 Asia/Shanghai] PHP Warning: phpinfo() has been disabled for security reasons in /data/wwwroot/111.com/index.php on line 2

[26-Dec-2017 17:13:47 Asia/Shanghai] PHP Warning: phpinfo() has been disabled for security reasons in /data/wwwroot/111.com/index.php on line 2

模擬一個錯誤演示:


[root@gary-tao php-7.1.6]# vim /data/wwwroot/111.com/2.php //編輯如下內容


<?php

echo 1234.php;

adfadgagagag


[root@gary-tao php-7.1.6]# curl -A "xietao xietao" -x127.0.0.1:80 http://111.com/2.php

[root@gary-tao php-7.1.6]# curl -A "xietao xietao" -x127.0.0.1:80 http://111.com/2.php -I

HTTP/1.0 500 Internal Server Error

Date: Tue, 26 Dec 2017 09:32:20 GMT

Server: Apache/2.4.29 (Unix) PHP/7.1.6

X-Powered-By: PHP/7.1.6

Connection: close

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

出現狀態碼500,這說明我們訪問的頁面是存在錯誤的,此時需要查看PHP的錯誤日誌來判定錯誤原因,如下:


[root@gary-tao php-7.1.6]# !cat

cat /tmp/php_errors.log

[26-Dec-2017 17:13:35 Asia/Shanghai] PHP Warning: phpinfo() has been disabled for security reasons in /data/wwwroot/111.com/index.php on line 2

[26-Dec-2017 17:13:47 Asia/Shanghai] PHP Warning: phpinfo() has been disabled for security reasons in /data/wwwroot/111.com/index.php on line 2

[26-Dec-2017 17:32:08 Asia/Shanghai] PHP Parse error: syntax error, unexpected 'php' (T_STRING), expecting ',' or ';' in /data/wwwroot/111.com/2.php on line 2

[26-Dec-2017 17:32:20 Asia/Shanghai] PHP Parse error: syntax error, unexpected 'php' (T_STRING), expecting ',' or ';' in /data/wwwroot/111.com/2.php on line 2


配置open_basedir

前言

一個服務器上跑很多網站,小公司為節省成本采用的做法,這樣操作是會有一些弊端:多個網站跑在同一個服務器上,如果其中一個網站被黑,很有可能會連累到其他站點,為了避免這種尷尬的事情發生,我們應當作一些預防手段。

PHP有一個概念叫作open_basedir,它的作用是將網站限定在指定目錄裏,就算該站點被黑了,黑客只能在該目錄下面有所作為,而不能左右其他目錄。如果你的服務器上只有一個站點,那可以直接在php.ini中設置open_basedir參數。但如果服務器上跑的站點比較多,那在php.ini中設置就不合適了,因為在php.ini中只能定義一次,也就是說所有站點都一起定義限定的目錄,那這樣似乎起不到隔離多個站點的目的。


1.使用php.ini設置open_basedir舉例演示:

條件:把這個open_basedir地址目錄的111.com目錄下改成錯誤的1111.com

得到如下日誌結果,示例如下:


[root@gary-tao php-7.1.6]# vim /usr/local/php7/etc/php.ini //編輯添加open_basedir目錄地址

定義如下

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


[root@gary-tao php-7.1.6]# /usr/local/apache2.4/bin/apachectl graceful

[root@gary-tao php-7.1.6]# curl -A "xietao xietao" -x127.0.0.1:80 http://111.com/2.php -I

HTTP/1.0 500 Internal Server Error

Date: Tue, 26 Dec 2017 11:44:40 GMT

Server: Apache/2.4.29 (Unix) PHP/7.1.6

X-Powered-By: PHP/7.1.6

Connection: close

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


[root@gary-tao php-7.1.6]# vi /data/wwwroot/111.com/2.php //編輯定義如下,保存退出


<?php

echo 123;


[root@gary-tao php-7.1.6]# curl -A "xietao xietao" -x127.0.0.1:80 http://111.com/2.php -I

HTTP/1.0 500 Internal Server Error

Date: Tue, 26 Dec 2017 11:47:23 GMT

Server: Apache/2.4.29 (Unix) PHP/7.1.6

X-Powered-By: PHP/7.1.6

Connection: close

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


[root@gary-tao php-7.1.6]# !cat

cat /tmp/php_errors.log

[26-Dec-2017 17:13:35 Asia/Shanghai] PHP Warning: phpinfo() has been disabled for security reasons in /data/wwwroot/111.com/index.php on line 2

[26-Dec-2017 17:13:47 Asia/Shanghai] PHP Warning: phpinfo() has been disabled for security reasons in /data/wwwroot/111.com/index.php on line 2

[26-Dec-2017 17:32:08 Asia/Shanghai] PHP Parse error: syntax error, unexpected 'php' (T_STRING), expecting ',' or ';' in /data/wwwroot/111.com/2.php on line 2

[26-Dec-2017 17:32:20 Asia/Shanghai] PHP Parse error: syntax error, unexpected 'php' (T_STRING), expecting ',' or ';' in /data/wwwroot/111.com/2.php on line 2

[26-Dec-2017 19:44:40 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

[26-Dec-2017 19:44:40 Asia/Shanghai] PHP Warning: Unknown: failed to open stream: Operation not permitted in Unknown on line 0

[26-Dec-2017 19:44:40 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

[26-Dec-2017 19:47:23 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

[26-Dec-2017 19:47:23 Asia/Shanghai] PHP Warning: Unknown: failed to open stream: Operation not permitted in Unknown on line 0

[26-Dec-2017 19:47:23 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

條件:把這個open_basedir地址目錄改成正確的111.com

[root@gary-tao php-7.1.6]# vim /usr/local/php7/etc/php.ini


定義如下

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


[root@gary-tao php-7.1.6]# /usr/local/apache2.4/bin/apachectl graceful

[root@gary-tao php-7.1.6]# curl -A "a" -x127.0.0.1:80 http://111.com/2.php -I

HTTP/1.1 200 OK

Date: Tue, 26 Dec 2017 11:57:59 GMT

Server: Apache/2.4.29 (Unix) PHP/7.1.6

X-Powered-By: PHP/7.1.6

Cache-Control: max-age=0

Expires: Tue, 26 Dec 2017 11:57:59 GMT

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


2.針對不同的虛擬主機去限制不同的open_basedir。

[root@gary-tao ~]# vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf


定義如下:

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


[root@gary-tao ~]# /usr/local/apache2.4/bin/apachectl -t

Syntax OK

[root@gary-tao ~]# /usr/local/apache2.4/bin/apachectl graceful

[root@gary-tao ~]# !curl

curl -A "a" -x127.0.0.1:80 http://111.com/2.php -I

HTTP/1.1 200 OK

Date: Tue, 26 Dec 2017 12:34:57 GMT

Server: Apache/2.4.29 (Unix) PHP/7.1.6

X-Powered-By: PHP/7.1.6

Cache-Control: max-age=0

Expires: Tue, 26 Dec 2017 12:34:57 GMT

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


[root@gary-tao ~]# curl -A "a" -x127.0.0.1:80 http://111.com/2.php

123[root@gary-tao ~]#


修改示例圖:

技術分享圖片

apache2.4限定某個目錄禁止解析PHP、限制user_agent、PHP相關配置