大多数托管套餐都承诺提供 DDoS 防护。这通常指在海量垃圾数据包(第 3 层和第 4 层)到达你的服务器之前将其过滤掉。但它无法阻止上千个“真实”浏览器同时加载你最慢的页面。这些应用层(第 7 层)攻击看起来就像普通访客,你必须自己应对。背景知识请参阅什么是 DDoS 防护。
了解其中的区别
- 流量型洪水攻击:占满网络管道。由主机或上游来过滤。
- 协议攻击:耗尽连接表。大部分由网络处理。
- 第 7 层攻击:看似合法的 HTTP 请求,会耗尽 CPU、数据库或工作进程。这些会到达你的应用。
第 1 步:在 Nginx 中限速
限制单个地址发出请求的速度。在 http 块中定义一个区域,并将其应用到你的站点。
limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=connip:10m;
server {
location / {
limit_req zone=perip burst=20 nodelay;
limit_conn connip 20;
}
location = /login {
limit_req zone=perip burst=3 nodelay;
}
}
对登录和搜索使用严格得多的限制,因为它们开销很大。
第 2 步:尽可能缓存
缓存的页面几乎不消耗任何资源。对匿名流量启用 FastCGI 或代理缓存,哪怕只有 30 到 60 秒。它能把大量相同的请求变成少数几个真实请求。
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=site:50m inactive=10m;
fastcgi_cache site;
fastcgi_cache_valid 200 60s;
fastcgi_cache_use_stale updating error timeout;
第 3 步:设置合理的超时
慢速连接攻击会一直占用工作进程。请缩短限制时间。
client_body_timeout 10s;
client_header_timeout 10s;
send_timeout 15s;
keepalive_timeout 15s;
client_max_body_size 5m;
第 4 步:用 fail2ban 封禁屡犯者
封禁触发限速器的地址。Nginx 会把被拒绝的请求记录到错误日志中,过滤规则可以匹配它们。
[nginx-limit-req]
enabled = true
filter = nginx-limit-req
logpath = /var/log/nginx/error.log
maxretry = 10
findtime = 60
bantime = 1h
第 5 步:情况严重时在前面加一层代理
带有机器人挑战的反向代理或 CDN,可以吸收单台 VPS 无法承受的攻击。请记得按照保守源站 IP 的秘密中所述保护源站,否则攻击者会绕过它。
在事情发生之前做好准备
- 了解你最慢的页面,并修复或缓存它们。
- 持续监控,以便迅速发现流量激增。
- 制定预案:更严格的限制、维护页面、更大的服务器。
UFW 与 fail2ban 指南中的基础内容可与本文配合使用。