網站系統安全配置(Nginx)防止網站被惡意GJ。網站如DDos,CC等。他們之間都原理都一樣,即發送大量的請求數據到服務器。
- Nginx主動防禦方法
Nginx中有 2 個模塊用於控制訪問用戶連接的“數量”和“速度”。分別是
HttpLimitZoneModule:限制同時併發連接數訪問控制
HttpLimitReqModule:限制訪問數據,每秒最多多少次的請求
以上兩個模塊配置比較容易影響系統業務的正常訪問,每秒最多的訪問次數,同時的併發訪問控制,不能設置太死,要不然都殺無赦,統統將正常客戶請求擋在外面。 -
Nginx普通配置
http模塊中配置# 用戶的 IP 地址 $binary_remote_addr 作爲 Key,每個 IP 地址最多有 50 個併發連接 # 你想開幾千個連接 刷死我? 超過 50 個連接,直接返回 503 錯誤給你,根本不處理你的請求了 # limit single IP 50 concurrent control limit_conn_zone $binary_remote_addr zone=TotalConnLimitZone:20m ; limit_conn TotalConnLimitZone 50; limit_conn_log_level notice; # 用戶的 IP 地址 $binary_remote_addr 作爲 Key,每個 IP 地址每秒處理 20 個請求 # 你想用程序每秒幾百次的刷我,沒戲,再快了就不處理了,直接返回 503 錯誤給你 # limit single IP/s 20 Request limit_req_zone $binary_remote_addr zone=ConnLimitZone:20m rate=20r/s; limit_req_log_level notice;
其中“limit_conn_zone $binary_remote_addr zone=TotalConnLimitZone:20m ;”表示定義一個名稱爲TotalConnLimitZone的存儲區域,大小20M。 “limit_req_log_level notice;”爲定義log級別。
其中“limit_req_zone $binary_remote_addr zone=ConnLimitZone:20m rate=25r/s;”表示定義一個名稱爲ConnLimitZone的存儲區域,ConnLimitZone內容爲遠程IP地址,ConnLimitZone大小20M,ConnLimitZone中的平均請求速率爲每秒20個; “limit_req_log_level notice;”爲定義log級別。
以上配置應用於server模塊... location /abc/ { limit_req zone=ConnLimitZone burst=5 nodelay; proxy_pass http://abc_pool/; } ...
其中“zone=ConnLimitZone”設置使用哪個配置區域來做限制,與上面limit_req_zone的name對應;burst=5,burst爆發的意思,這個配置的意思是設置一個大小爲5的緩衝區,當有大量請求(爆發)過來時,超過了訪問頻次限制的請求可以先放到這個緩衝區內,所以,總的每秒處理請求是上面的20 + 5個排隊;nodelay,如果設置,超過訪問頻次並且緩衝區也滿了,會直接返回503,如果沒有設置,則所有請求會等待排隊。
-
Nginx高級一點的配置
上面是簡單的服務器安全限制訪問配置,是在比較簡單的客戶端瀏覽器 —–> 系統服務器的訪問結構,中間是沒有各種網絡加速(CDN)的情況下配置。
很多情況下,是普通用戶瀏覽器 —–> 360網站衛士加速(CDN,360防CC,DOS) ——> 阿里雲加速服務器(我們自己建的CDN,阿里雲盾) ——> 源服務器(PHP 程序部署在這裏,iptables,nginx 安全配置)。
網站中間經歷了好幾層透明加速和安全過濾, 這種情況下,就不能用上面的“普通配置”。“源IP”地址不再是普通用戶的IP,而是中間網絡加速服務器的IP地址了。
所以,要獲取真實客戶端IP,就需
X-Forwarded-For : 用戶IP,代理服務器IP...
經過多層代理之後,用戶的真實IP 在第一個位置,後面會跟一串中間代理服務器的IP地址,從這裏取到用戶真實的IP地址,針對這個IP 地址做限制就可以了。
Nginx配置:#這裏取得原始用戶的IP地址 map $http_x_forwarded_for $clientRealIp { "" $remote_addr; ~^(?P<firstAddr>[0-9\.]+),?.*$ $firstAddr; } # limit single IP 50 concurrent control,這裏的$binary_remote_addr變成$clientRealIp,$clientRealIp爲Key limit_conn_zone $clientRealIp zone=TotalConnLimitZone:20m ; limit_conn TotalConnLimitZone 50; limit_conn_log_level notice; # limit single IP/s 20 Request,這裏的$binary_remote_addr變成$clientRealIp,$clientRealIp爲Key limit_req_zone $clientRealIp zone=ConnLimitZone:20m rate=20r/s; limit_req_log_level notice; # 具體服務器配置 server { listen 80; location ~ \.php$ { limit_req zone=ConnLimitZone burst=5 nodelay; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi_params; } }
-
測試
Nginx配置怎麼測試,使用Echo模塊。查看本地的Nginx是否有此模塊,輸入nginx -V命令查看,如果沒有,需額外下載該模塊進行編譯安裝。
這裏直接展示nginx配置server { listen 80; server_name www.aaa.com; ## 當用戶訪問 /nginx-test 的時候,我們輸出 $clientRealIp 變量,看看這個變量, 用戶源IP 地址 location /nginx-test { echo $clientRealIp; } }
訪問網址接nginx-test,下載後用文本編譯器打開,即可看到用戶端通過多層CDN 之後,$clientRealIp仍然是有效的原始用戶IP地址。