ginx發展多年,自身的安全漏洞比較少,發現軟體漏洞,一般利用軟體包管理器更新一下就好了。
本文側重講述的不是nginx自身的安全,而是利用nginx來加強web應用,幹一些應用防火牆(WAF)幹的活。
在做安全加強的時候,我們一定要頭腦清晰,手裡拿着刀,一刀一刀的切,将我們不想要的流量幹掉,除去隐患。
1、屏蔽IP
假設我們的網站隻是一個國内小站,有着公司業務,不是靠廣告生存的那種,那麼可以用geoip子產品封殺掉除中國和美國外的所有IP。這樣可以過濾大部分來自國外的惡意掃描或者無用通路。不用擔心封殺了網絡蜘蛛。主流的網絡蜘蛛(百度/谷歌/必應/搜狗)已經包含在了我們的IP範圍内了。如果是公網的登入背景,更應該屏蔽徹底一點。
[html] view plain copy
- if ( $geoip_country_code !~ ^(CN|US)$ ) {
- return 403;
- }
(很多人擔心geoip庫不夠準确,誠然,中國城市級别的IP段會有誤差,但是國家級别的IP段一般是沒有問題的,并且geoip庫可以随時線上更新)
2、封殺各種user-agent
user-agent 也即浏覽器辨別,每個正常的web請求都包含使用者的浏覽器資訊,除非經過僞裝,惡意掃描工具一般都會在user-agent裡留下某些特征字眼,比如scan,nmap等。我們可以用正則比對這些字眼,進而達到過濾的目的,請根據需要調整。
- if ($http_user_agent ~* "java|python|perl|ruby|curl|bash|echo|uname|base64|decode|md5sum|select|concat|httprequest|httpclient|nmap|scan" ) {
- return 403;
- if ($http_user_agent ~* "" ) {
這裡分析得不夠細緻,具體的非法user-agent還得慢慢從日志中逐個提取。
通過上面兩個大招,相信你的日志裡很快就會有大量的403記錄。,我們接着幹。
3、封殺特定的url
特定的檔案擴充名,比如.bak
- location ~* \.(bak|save|sh|sql|mdb|svn|git|old)$ {
- rewrite ^/(.*)$ $host permanent;
知名程式,比如phpmyadmin
- location /(admin|phpadmin|status) { deny all; }
4、封殺特定的http方法和行為,比如
- if ($request_method !~ ^(GET|POST|HEAD)$ ) {
- return 405;
- if ($http_range ~ "\d{9,}") {
- return 444;
5、強制網站使用域名通路,可以逃過IP掃描,比如
- if ( $host !~* 'abc.com' ) {
6、url 參數過濾敏感字,比如
- if ($query_string ~* "union.*select.*\(") {
- rewrite ^/(.*)$ $host permanent;
- }
- if ($query_string ~* "concat.*\(") {
7、強制要求referer
- if ($http_referer = "" ) {
- }
其它方法
8、封殺IP
定時做日志分析,手動将惡意IP加入iptables拒絕名單,推薦使用ipset子產品。
- yum install ipset
- ipset create badip hash:net maxelem 65535
- iptables -I INPUT -m set --match-set badip src -p tcp --dport 80 -j DROP
- /etc/init.d/iptables save
- ipset add badip 1.1.1.2
- ipset add badip 2.2.2.0/24
- /etc/init.d/ipset save
9、限速
适當限制用戶端的請求帶寬,請求頻率,請求連接配接數,這裡不展開論述。根據具體需求,閥值應當稍稍寬泛一點。特别要注意辦公室/網吧場景的使用者,他們的特點是多人使用同一個網絡出口。
10、目錄隻讀
如果沒有上傳需求,完全可以把網站根目錄弄成隻讀的,加強安全。
做了一點小動作,給網站根目錄搞了一個隻讀的挂載點。這裡假設網站根目錄為/var/www/html
- mkdir -p /data
- mkdir -p /var/www/html
- mount --bind /data /var/www/html
- 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好) 。