首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

Nginx 限制單 IP 訪問頻率與並發連接:防 CC 攻擊完整配置指南

     編輯:PHP 相關知識

核心模組

  • ngx_http_limit_req_module:限制**請求速率** (漏桶算法),超限返回 503
  • ngx_http_limit_conn_module:限制**並發連接數**,超限返回 503

場景一:限制請求頻率 (limit_req)

配置示例

http {
    # 定義共享內存區域,鍵為客戶端二進制 IP,10MB 可存 ~16 萬狀態
    # 速率:平均每秒 20 請求 (突發允許 5 個額外突發)
    limit_req_zone $binary_remote_addr zone=one:10m rate=20r/s;

    server {
        location / {
            # 套用限制:zone=one,突發桶大小 5,nodelay=立即處理突發而不延遲
            limit_req zone=one burst=5 nodelay;
            
            # 自定義超限返回碼 (默認 503)
            limit_req_status 429;
        }
        
        # 登錄/註冊接口更嚴格
        location /api/login {
            limit_req zone=one burst=2 nodelay;
        }
    }
}

關鍵參數解析

指令說明
limit_req_zone定義區域:key zone=name:size rate=rate。rate 單位 r/s (每秒) 或 r/m (每分鐘),必須為整數
limit_req套用區域:zone=name [burst=number] [nodelay]
burst漏桶容量。允許突發流量超過 rate,超出部分排隊 (無 nodelay) 或直接拒絕 (有 nodelay)
nodelay啟用後,突發請求不排隊直接處理,桶滿則拒絕。關閉時,突發請求按 rate 速率排隊延遲處理
limit_req_status自定義超限狀態碼 (默認 503),建議 429 Too Many Requests

速率單位換算

  • 30r/m = 每分鐘 30 請求 = 平均 0.5 r/s (適合極嚴格限制)
  • 100r/s = 每秒 100 請求 (適合靜態資源/API 閘道)

場景二:限制並發連接數 (limit_conn)

配置示例

http {
    # 定義並發限制區域
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

    server {
        location / {
            # 每個 IP 最大 20 個並發連接
            limit_conn conn_limit 20;
            
            # 限制單連接傳輸速度 500KB/s (配合並發限制防盜鏈/下載工具)
            limit_rate 500k;
            
            limit_conn_status 429;
        }
    }
}

參數說明

指令說明
limit_conn_zone僅能在 http 上下文定義
limit_conn可在 http/server/location 使用。zone number
limit_rate限制**單連接**傳輸速率 (bytes/s)。單 IP 總速率 ≈ limit_rate × limit_conn
limit_conn_status超限狀態碼

白名單機制:放行搜索引擎爬蟲與內部 IP

步驟 1:geo 指令定義白名單變量

http {
    geo $limited {
        default 1;  # 默認限制
        
        # Googlebot IP 段
        64.233.160.0/19  0;
        66.102.0.0/20    0;
        66.249.64.0/19   0;
        72.14.192.0/18   0;
        74.125.0.0/16    0;
        209.85.128.0/17  0;
        216.239.32.0/19  0;
        
        # Bingbot
        157.55.0.0/16    0;
        157.56.0.0/14    0;
        207.46.0.0/16    0;
        
        # 內部測試 IP
        127.0.0.1/32     0;
        10.0.0.0/8       0;
        192.168.0.0/16   0;
    }
}

步驟 2:map 指令映射限制鍵

http {
    # 白名單 IP 映射為空字符串,不會寫入 limit_req_zone 共享內存
    map $limited $limit_key {
        1  $binary_remote_addr;  # 普通 IP 正常限制
        0  "";                   # 白名單 IP 不限制
    }
}

步驟 3:套用映射後的鍵

http {
    limit_req_zone $limit_key zone=api_limit:10m rate=100r/s;
    
    server {
        location /api/ {
            limit_req zone=api_limit burst=20 nodelay;
        }
    }
}

完整防 CC 攻擊配置模板

http {
    # 1. 白名單定義
    geo $is_limited {
        default 1;
        127.0.0.1/32 0;
        10.0.0.0/8 0;
        # 添加已知爬蟲 IP 段...
    }
    map $is_limited $limit_key {
        1 $binary_remote_addr;
        0 "";
    }

    # 2. 請求頻率限制區域
    limit_req_zone $limit_key zone=req_zone:20m rate=50r/s;
    
    # 3. 並發連接限制區域
    limit_conn_zone $limit_key zone=conn_zone:10m;

    server {
        listen 80;
        server_name example.com;

        # 4. 全局套用
        limit_req zone=req_zone burst=10 nodelay;
        limit_req_status 429;
        limit_conn conn_zone 30;
        limit_conn_status 429;
        limit_rate 1m;  # 單連接 1MB/s

        # 5. 敏感接口加強
        location /api/login {
            limit_req zone=req_zone burst=3 nodelay;
        }
        location /api/register {
            limit_req zone=req_zone burst=2 nodelay;
        }

        # 6. 靜態資源放寬
        location ~* \.(jpg|jpeg|png|gif|css|js|ico|woff2?)$ {
            limit_req zone=req_zone burst=50 nodelay;
            limit_conn conn_zone 50;
            expires 30d;
        }
    }
}

驗證與調試

  1. nginx -t 測試配置語法
  2. systemctl reload nginx 熱加載
  3. 使用 ab -n 100 -c 10 https://example.com/ 壓測,觀察 429 響應
  4. 查看錯誤日誌:grep "limiting requests" /var/log/nginx/error.log

進階建議

  • 雙層防護:Nginx 限流 + 應用層 (PHP/Redis) 限流,針對不同業務邏輯精細控制
  • 動態調整:結合 OpenResty + Lua 共享字典,根據實時流量動態修改 rate/burst
  • 日誌分析:將 429 日誌接入 ELK/Grafana,設置告警觸發自動封禁 (fail2ban/iptables)
  • HTTPS 場景:確保 $binary_remote_addr 獲取真實客戶端 IP (配置 real_ip_header + set_real_ip_from)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved