针对机器的攻击:我们做什么,您能做什么
针对通道和针对应用的攻击分别是什么样,两者有何区别,您这边可以配置什么,以及如何判断这根本不是攻击。
更新于 2026年8月23日
“攻击”这个词在两种完全不同的情况下听起来是一样的:一种是您的通道被垃圾流量淹没,另一种是每秒几百个请求拖垮了您的应用。这两种情况的处理方式不同,首先要弄清楚您面对的是哪一种。
区分两种情况
| 迹象 | 通道饱和 | 应用过载 |
|---|---|---|
| “概览”中的流量图 | 达到上限 | 数值正常 |
| 处理器 | 未满载 | 完全满载 |
| SSH | 无法连接 | 可以连接,但很慢 |
| Web 服务器日志 | 为空 | 数千条相同的请求 |
查看 /hosting/vds/m/<id> 的“概览”中最近 24 小时的处理器、内存和流量图。如果流量正常但处理器一直处于满载状态,那就是应用负载,需要您在自己这边处理。
您可以做什么
在 nginx 中限制请求速率:
limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn:10m;
server {
limit_req zone=perip burst=20 nodelay;
limit_conn conn 20;
client_body_timeout 10s;
client_header_timeout 10s;
}
在防火墙中限制连接数:
ufw limit 22/tcp
更灵活的规则见 nftables 一文:在那里您还可以限制新建连接的速率,并维护一份带生存时间的封禁地址列表。
在日志中查找来源:
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
ss -tn state established | awk '{print $4}' | cut -d: -f1 | sort | uniq -c | sort -rn | head
一次性封禁某个地址或网段:
ufw deny from 203.0.113.0/24
fail2ban 可以根据日志自动执行封禁。
我们做什么
我们的基础设施会在垃圾流量到达节点之前将其过滤掉——在它消耗您的带宽之前。这对针对通道的流量型攻击有效,且无需您做任何配置。
节点级防护做不到的事:它不会分析您应用的逻辑。从外部看起来正常的请求会到达您的机器,只有您自己的配置才能防御它们。
如果您的机器成为攻击的来源——例如它被入侵并参与了别人的垃圾信息活动——将依据可接受使用政策限制访问。请对照入侵迹象检查您的机器。
缓存与静态文件
应对请求洪流最有效的办法,就是不要重复计算同样的东西:
location /static/ {
expires 30d;
add_header Cache-Control "public";
}
在应用侧缓存开销大的页面。由缓存提供的请求,成本要低数百倍。
常见错误
- 只设置
limit_req而不设置burst——普通用户打开一个页面会拉取二十多个文件,结果被误伤。 - 在分布式攻击期间手动逐个封禁地址:地址有成千上万个,您根本跟不上。
- 完全封禁 ICMP——这会破坏数据包大小协商,参见 MTU。
- 把自己的 bug 当成攻击:代码中的循环、搜索机器人抓取您忘了排除的目录、客户端无休止地重试。
请提前在一台空闲的机器上设置好限制。在请求洪流期间,您无法从容调整
rate和burst的值:那时您只能盲改配置,而且只能零敲碎打地改。