nginx作為一款高性能的web服務器和反向代理服務器,廣受網站架構師的青睞。但是在使用nginx時,我們也需要關注安全方面的問題,特別是在處理url上。
由于Nginx的靈活性,如果我們不采取一些URL安全策略,就可能受到如下攻擊:
- SQL注入
- XSS攻擊
- 非法文件下載
- CSRF攻擊
- 非法請求訪問等
本文將介紹Nginx URL安全策略編寫的指南。
一. 前置條件
在編寫Nginx URL安全策略之前,需要對以下知識點掌握:
- 正則表達式
- Nginx配置文件語法
- HTTP協議基礎知識
二. 輸入過濾
Nginx可使用http請求頭檢測,防止惡意Http請求。具體實現方式是添加類似如下配置到Nginx配置文件中:
if ($http_user_agent ~* "some evil expression") { return 403; }
或者使用Nginx內置的防火墻模塊進行輸入過濾,如下:
# block ip sends more than 100 requests per 5 seconds limit_conn_zone $binary_remote_addr zone=one:10m; limit_req_zone $binary_remote_addr zone=two:10m rate=1r/s; server { location / { limit_conn one 10; limit_req zone=two burst=5 nodelay; } }
該示例做了如下的事情:
- 首先定義了兩個zone,即可以存儲狀態信息的內存區域。(這也意味著如果有很多的訪問,這種防護的成本可能會比較高)
- 如果同一個IP地址在 5 秒鐘內發送了多于 100 個HTTP請求,則進行屏蔽。
- 如果同一個IP地址在 1 秒鐘內發送了多于 5 次HTTP請求,則進行屏蔽。
三. 防SQL注入
在實際開發中,避免SQL注入是必須的。為了防止SQL注入攻擊,我們可以如下配置:
location ~* (.php|.asp|.ashx)/?$ { if ($args ~* "select.*from") { return 403; } }
該示例用到了Nginx內置的if模塊,防止攻擊者使用select語句從數據庫中獲取數據,如果有這種情況,返回403禁止訪問。
四. 防XSS攻擊
針對XSS攻擊,我們可以加強對輸入的檢測。如果檢測到有可能的XSS攻擊,可以將連接重定向到一個安全的URL,或者返回錯誤信息。
if ($args ~* "<script.>") { return 403; }</script.>
該示例采用了Nginx內置的if模塊,檢測URL中是否有嵌套了script標簽的內容。
五. 防CSRF攻擊
在使用Nginx時,為了防止CSRF攻擊,需要禁止外部站點的請求。例如,可以增加如下配置:
location / { if ($http_referer !~ "^https?://$host/") { return 403; } }
該示例使用Nginx內置的if模塊,限制只能接收$host站點發送的請求,如果來自其他站點的請求,Nginx會返回403。
六. 防文件下載漏洞
為了防止訪問不正當的文件,如私人文檔、腳本、配置文件等,請使用如下策略:
location ~* .(xls|doc|pdf)$ { valid_referers none blocked server_names; if ($invalid_referer) { return 401; } }
該示例使用Nginx內置的valid_referers模塊,當發現請求來自沒有經過授權的站點時,會返回401。
七. 禁止一些URL訪問
在實際項目中,有些URL可以被攻擊者利用,例如admin.php、login.php等。我們可以直接禁止它們的訪問。
location ~ /(admin|login).php { deny all; }
該示例的配置,禁止了訪問以admin.php和login.php為結尾的URL。
八. 完整示例
最后,根據以上的配置,我們可以得到以下的完整示例:
server { listen 80; server_name yourdomain.com; # 設置過濾規則 location / { # 禁止非法請求 limit_conn_zone $binary_remote_addr zone=one:10m; limit_req_zone $binary_remote_addr zone=two:10m rate=1r/s; limit_conn one 10; limit_req zone=two burst=5 nodelay; # 防止XSS攻擊 if ($args ~* "<script.>") { return 403; } # 防止SQL注入 if ($args ~* "select.*from") { return 403; } # 禁止admin和login的訪問 location ~ /(admin|login).php { deny all; } } # 防止文件下載漏洞 location ~* .(xls|doc|pdf)$ { valid_referers none blocked server_names; if ($invalid_referer) { return 401; } } }</script.>