3.4 限流與 DoS 防護#
可用性也是安全(回顧 CIA)#
資料被偷(C)、被改(I)之外,「服務癱瘓」是第三種直接傷害(A)。DoS 的本質:把系統的有限資源(頻寬、連線、CPU、記憶體、DB 查詢)耗盡。
\[ \text{DoS 成立條件}: \lambda_{\text{攻擊}} > \lambda_{\text{容量}} \quad \text{(1.2 攻擊面:任何有限資源都是入口)} \]
DoS 的分類#
flowchart TD
A[DoS] --> B[頻寬型<br/>DDoS: 洪水灌爆頻寬]
A --> C[協議型<br/>SYN flood 耗盡半連線佇列]
A --> D[應用層<br/>昂貴請求: 慢查詢/regex回溯/大解析]
A --> E[慢速型<br/>Slowloris: 慢慢發標頭吊住連線]- 頻寬型只能靠上游(CDN/ISP)吸收 —— 你的機器物理上收不完
- 應用層 DoS 是網站工程師的真正戰場:每秒 10 個請求也可能是 DoS,如果每個請求讓 DB 做 5 秒全表掃描
應用層限流(Rate Limiting)#
演算法選擇#
| 演算法 | 機制 | 特點 |
|---|---|---|
| 固定視窗 | 每分鐘重置計數 | 簡單;邊界突刺(兩窗交接口 2 倍量) |
| 滑動視窗日誌 | 記每筆時間戳 | 精確;記憶體貴 |
| 滑動視窗計數 | 前後窗加權 | 精確與成本的平衡,實務首選 |
| Token Bucket | 桶裝令牌,以速率補充,請求取令牌 | 允許突發、控制平均速率 |
| Leaky Bucket | 恆定速率漏出 | 削峰填谷 |
\[ \text{Token Bucket}: \text{容量 } b, \text{補充速率 } r \Rightarrow \text{允許 } b \text{ 突發,長期 } r \text{ 平均} \]
維度選擇:限誰?#
| 維度 | 防 |
|---|---|
| IP | 機會型濫用(注意 NAT 後多使用者、代理池) |
| 帳號 | 登入爆破(比 IP 維度穩) |
| API key | 商業 API 配額 |
| 混合 | 敏感操作(登入/寄信)多重維度疊加 |
// Axum:tower_governor 按路徑掛限流(前書 3.4)
let sensitive = Router::new()
.route("/login", post(login))
.route("/password-reset", post(reset))
.layer(governor_layer(GovernorConfigBuilder::default()
.per_second(1)
.burst_size(5) // 5 秒內最多 5 次,之後每秒 1 次
.finish().unwrap()));
慢速攻擊與連線資源#
Slowloris(2009)只需極低頻寬:不斷髮半截標頭,吊住數千連線 —— 傳統「每連線一執行緒」伺服器直接枯竭。
防禦:連線逾時(讀超時、標頭超時)、非同步伺服器(Node/Tokio 天然耐連線數)、反向代理(Nginx 預設擋 slowloris)。
ReDoS:正則回溯炸彈#
/(a+)+$/.test("aaaaaaaaaaaaaaaaaaaaaaaaX");
// 災難性回溯 O(2^n) → 單一請求凍結事件循環
惡意輸入觸發正則災難回溯 = 單執行緒 JS 服務(前書 6.1)整站凍結。防禦:
- 避免 nested quantifier(
(a+)+、(a|a)*) - RE2 / Rust regex(線性時間引擎,語法受限)
- 正則也限流/限長
應用層的昂貴請求#
| 資源耗費 | 例 | 防禦 |
|---|---|---|
| DB | 複雜查詢、offset 分頁 | 查詢超時、cursor 分頁(前書 5.4) |
| 解析 | 大 XML/zip bomb | 大小上限、深度上限 |
| 圖片 | 上傳 10000×10000 縮圖 | 限制尺寸、串流處理 |
| 幣 | 註冊送信 | 驗證碼 + 限流 |
每個端點問一句:最壞情況這個請求花多少資源? —— 這是 1.2 威脅建模 STRIDE 中 D(DoS)的具體化。
分層防禦架構#
flowchart TD
A[網際網路] --> CDN[CDN/WAF\n吸頻寬型+擋已知payload]
CDN --> LB[負載平衡\n連線限制]
LB --> APP[應用\n端點限流+超時]
APP --> DB[(資料庫\n查詢超時+連線池上限)]每層的限流數值設計原則:正常使用者的 P99 行為 + 安全餘量。過緊傷真用戶(誤殺),過鬆形同虛設 —— 觀測(5.3)先行,再設閾值。
習題#
- 為登入端點設計三維限流(IP/帳號/全局),寫出各維度閾值與理由。
- 找出你專案中最昂貴的三個端點,為每個估算「最壞請求成本」並加防禦。
- 為什麼 DDoS 無法在自家伺服器上解決?從封包物理路徑說明。