天天看點

補充增加nginx 安全政策

ginx發展多年,自身的安全漏洞比較少,發現軟體漏洞,一般利用軟體包管理器更新一下就好了。

本文側重講述的不是nginx自身的安全,而是利用nginx來加強web應用,幹一些應用防火牆(WAF)幹的活。

在做安全加強的時候,我們一定要頭腦清晰,手裡拿着刀,一刀一刀的切,将我們不想要的流量幹掉,除去隐患。

1、屏蔽IP

假設我們的網站隻是一個國内小站,有着公司業務,不是靠廣告生存的那種,那麼可以用geoip子產品封殺掉除中國和美國外的所有IP。這樣可以過濾大部分來自國外的惡意掃描或者無用通路。不用擔心封殺了網絡蜘蛛。主流的網絡蜘蛛(百度/谷歌/必應/搜狗)已經包含在了我們的IP範圍内了。如果是公網的登入背景,更應該屏蔽徹底一點。

[html] view plain copy 

補充增加nginx 安全政策
補充增加nginx 安全政策

  1. if ( $geoip_country_code !~  ^(CN|US)$ ) {  
  2.         return 403;  
  3. }  

(很多人擔心geoip庫不夠準确,誠然,中國城市級别的IP段會有誤差,但是國家級别的IP段一般是沒有問題的,并且geoip庫可以随時線上更新)

2、封殺各種user-agent

user-agent 也即浏覽器辨別,每個正常的web請求都包含使用者的浏覽器資訊,除非經過僞裝,惡意掃描工具一般都會在user-agent裡留下某些特征字眼,比如scan,nmap等。我們可以用正則比對這些字眼,進而達到過濾的目的,請根據需要調整。

補充增加nginx 安全政策
補充增加nginx 安全政策
  1. if ($http_user_agent ~* "java|python|perl|ruby|curl|bash|echo|uname|base64|decode|md5sum|select|concat|httprequest|httpclient|nmap|scan" ) {  
  2.     return 403;  
  3. if ($http_user_agent ~* "" ) {  

這裡分析得不夠細緻,具體的非法user-agent還得慢慢從日志中逐個提取。

通過上面兩個大招,相信你的日志裡很快就會有大量的403記錄。,我們接着幹。

3、封殺特定的url

特定的檔案擴充名,比如.bak

補充增加nginx 安全政策
補充增加nginx 安全政策
  1. location ~* \.(bak|save|sh|sql|mdb|svn|git|old)$ {  
  2. rewrite ^/(.*)$  $host  permanent;  

知名程式,比如phpmyadmin

補充增加nginx 安全政策
補充增加nginx 安全政策
  1. location /(admin|phpadmin|status)  { deny all; }  

4、封殺特定的http方法和行為,比如

補充增加nginx 安全政策
補充增加nginx 安全政策
  1. if ($request_method !~ ^(GET|POST|HEAD)$ ) {  
  2.     return 405;  
  3. if ($http_range ~ "\d{9,}") {  
  4.     return 444;  

5、強制網站使用域名通路,可以逃過IP掃描,比如

補充增加nginx 安全政策
補充增加nginx 安全政策
  1. if ( $host !~* 'abc.com' ) {  

6、url 參數過濾敏感字,比如

補充增加nginx 安全政策
補充增加nginx 安全政策
  1. if ($query_string ~* "union.*select.*\(") {   
  2.     rewrite ^/(.*)$  $host  permanent;  
  3. }   
  4. if ($query_string ~* "concat.*\(") {   

7、強制要求referer

補充增加nginx 安全政策
補充增加nginx 安全政策
  1. if ($http_referer = "" ) {  
  2. }  

其它方法

8、封殺IP

定時做日志分析,手動将惡意IP加入iptables拒絕名單,推薦使用ipset子產品。

補充增加nginx 安全政策
補充增加nginx 安全政策
  1. yum install ipset  
  2. ipset create badip hash:net maxelem 65535  
  3. iptables -I INPUT -m set --match-set badip src -p tcp --dport 80 -j DROP  
  4. /etc/init.d/iptables save  
  5. ipset add badip 1.1.1.2  
  6. ipset add badip 2.2.2.0/24  
  7. /etc/init.d/ipset save  

9、限速

适當限制用戶端的請求帶寬,請求頻率,請求連接配接數,這裡不展開論述。根據具體需求,閥值應當稍稍寬泛一點。特别要注意辦公室/網吧場景的使用者,他們的特點是多人使用同一個網絡出口。

10、目錄隻讀

如果沒有上傳需求,完全可以把網站根目錄弄成隻讀的,加強安全。

做了一點小動作,給網站根目錄搞了一個隻讀的挂載點。這裡假設網站根目錄為/var/www/html

補充增加nginx 安全政策
補充增加nginx 安全政策
  1. mkdir -p /data  
  2. mkdir -p /var/www/html  
  3. mount --bind /data /var/www/html  
  4. mount -o remount,ro --bind /data /var/www/html  

網站内容實際位于/data,網站内容更新就往/data裡更新,目錄/var/www/html無法執行任何寫操作,否則會報錯“Read-only file system”,極大程度上可以防止提權篡改。

11、定時總結和豐富過濾規則

1-11、轉載連接配接http://blog.csdn.net/jy_he/article/details/52299884

12. 在配置檔案中小心使用"if"

它是重寫子產品的一部分,不應該在任何地方使用。

“if”聲明是重寫子產品評估指令強制性的部分。換個說法,Nginx的配置一般來說是聲明式的。在有些情況下,由于使用者的需求,他們試圖在一些非重寫指令内使用“if”,這導緻我們現在遇到的情況。大多數情況下都能正常工作,但…看上面提到的。

看起來唯一正确的解決方案是在非重寫的指令内完全禁用“if”。這将更改現有的許多配置,是以還沒有完成。IfIsEvil:http://wiki.nginx.org/IfIsEvil

13. 将每個~ .php$請求轉遞給PHP

我們上周釋出了這個流行指令的潛在安全漏洞介紹。即使檔案名為hello.php.jpeg它也會比對~ .php$這個正則而執行檔案。

現在有兩個解決上述問題的好方法。我覺得確定你不輕易執行任意代碼的混合方法很有必要。

13.1 如果沒找到檔案時使用try_files和only(在所有的動态執行情況下都應該注意) 将它轉遞給運作PHP的FCGI程序。

13.2 确認php.ini檔案中cgi.fix_pathinfo設定為0 (cgi.fix_pathinfo=0) 。這樣確定PHP檢查檔案全名(當它在檔案結尾沒有發現.php它将忽略)

13.3 修複正規表達式比對不正确檔案的問題。現在正規表達式認為任何檔案都包含".php"。在站點後加“if”確定隻有正确的檔案才能運作。将/location ~ .php$和location ~ ..*/.*.php$都設定為return 403;

14. 禁用autoindex子產品

這個可能在你使用的Nginx版本中已經更改了,如果沒有的話隻需在配置檔案的location塊中增加autoindex off;聲明即可。

15. 禁用伺服器上的ssi (伺服器端引用)

這個可以通過在location塊中添加ssi off; 。

16. 關閉伺服器标記

如果開啟的話(預設情況下)所有的錯誤頁面都會顯示伺服器的版本和資訊。将server_tokens off;聲明添加到Nginx配置檔案來解決這個問題。

17. 在配置檔案中設定自定義緩存以限制緩沖區溢出攻擊的可能性

1

2

3

4

client_body_buffer_size 1K;

client_header_buffer_size 1k;

client_max_body_size 1k;

large_client_header_buffers 2 1k;

18. 将timeout設低來防止DOS攻擊

所有這些聲明都可以放到主配置檔案中。

client_body_timeout 10;

client_header_timeout 10;

keepalive_timeout 5 5;

send_timeout 10;

19. 限制使用者連接配接數來預防DOS攻擊

limit_zone slimits $binary_remote_addr 5m;

limit_conn slimits 5;

20. 試着避免使用HTTP認證

HTTP認證預設使用crypt,它的哈希并不安全。如果你要用的話就用MD5(這也不是個好選擇但負載方面比crypt好) 。

繼續閱讀