游戏服务器 DDoS 防护实战:从流量清洗到应用层防御的完整方案 原创
引言:为什么游戏服务器是 DDoS 的重灾区
对于游戏服务器运维来说,DDoS(分布式拒绝服务)攻击不是”可能遇到”的问题,而是”一定会遇到”的问题。游戏服务器有几个先天弱点,让它们成为攻击者的首选目标:
- 端口固定且必须开放:玩家需要连接固定的游戏端口(如 WoW 登录 3724、世界 8085、TrinityCore 等),你无法像网站那样把端口藏在 CDN 后面。
- 连接时长长、状态敏感:玩家建立的是长连接,一旦被 Flood 打爆,所有在线玩家全部掉线,口碑崩塌。
- 带宽消耗型攻击效果明显:游戏服务器往往是租用的高配机器,带宽有限(一般 5M-100M),几十 Gbps 的流量清洗成本远高于服务器本身。
- 对手有明确利益动机:商业服会被同行竞争恶意攻击,公益服可能因为”不爽”被报复,甚至还有勒索型 DDoS。
本文不讨论”要不要上高防”这类泛泛之谈,而是从可落地的实战配置出发,从内核参数、iptables/nftables、Nginx 反代、游戏协议层到流量清洗和监控告警,给你一套开箱即用的完整方案。
一、游戏服务器面临的 DDoS 攻击类型
在动手配置之前,先分清你面对的是哪种攻击。不同攻击类型的防护手段完全不同,对症下药才能有效。
| 攻击类型 | 攻击原理 | 特征 | 影响 |
|---|---|---|---|
| SYN Flood | 发送大量不完成三次握手的 SYN 包,耗尽半连接队列 | 半连接数暴涨,`ss -s` 中 SYN_RECV 堆积 | 新玩家无法登录,服务器 TCP 层瘫痪 |
| UDP Flood | 向游戏端口/随机端口灌入大量 UDP 包 | 带宽被打满,网卡丢包率升高 | 整机带宽耗尽,所有服务掉线 |
| HTTP Flood | 大量僵尸机模拟正常 HTTP 请求攻击登录/注册/公告页面 | 请求量高但来源 IP 分散,特征不明显 | Web 服务(网站、API)响应缓慢或 502 |
| 游戏协议 Flood | 伪造游戏客户端登录包、心跳包、刷屏包,制造大量”合法”流量 | 连接数正常但包频率异常、行为可疑 | WorldServer 负载升高,卡顿、回档风险 |
一个残酷的现实是:大流量攻击(带宽型)只能靠流量清洗解决,服务器本身的规则只能缓解小流量攻击。所以下面的配置,一部分是”扛小打小闹”,一部分是”给清洗争取时间”。
二、网络层防御:iptables / nftables 实战配置
网络层是防御的第一道防线。下面给出 iptables 和 nftables 两套等价配置,根据你服务器的发行版选择。CentOS 7 及以前用 iptables,Debian 11+/Ubuntu 22.04+ 建议用 nftables。
2.1 iptables 版本(CentOS / 老系统)
先保存现有规则,防止配置错误后无法回滚:
# 备份现有规则
iptables-save > /root/iptables.bak.$(date +%F)
# 1) 默认策略:INPUT 默认 DROP,避免漏网
iptables -P INPUT DROP
iptables -P FORWARD DROP
# 2) 放行本地回环和已建立连接(必须最先,否则全断)
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# 3) 常用管理端口白名单(按需修改,SSH 用 22)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# 4) 游戏端口放行(以 AzerothCore/TrinityCore 为例)
# 3724 = 登录服务器, 8085 = 世界服务器
iptables -A INPUT -p tcp --dport 3724 -j ACCEPT
iptables -A INPUT -p tcp --dport 8085 -j ACCEPT
iptables -A INPUT -p udp --dport 8085 -j ACCEPT
# 5) 限制每 IP 并发连接数(connlimit):防单点刷爆
iptables -A INPUT -p tcp --syn --dport 3724 -m connlimit --connlimit-above 20 --connlimit-mask 32 -j REJECT
iptables -A INPUT -p tcp --syn --dport 8085 -m connlimit --connlimit-above 100 --connlimit-mask 32 -j REJECT
# 6) 限速(hashlimit):限制每个源 IP 的新连接速率
iptables -A INPUT -p tcp --syn --dport 8085 -m hashlimit \
--hashlimit-above 5/sec --hashlimit-burst 10 \
--hashlimit-mode srcip --hashlimit-name ws_syn -j DROP
connlimit 和 hashlimit 是两个最容易出效果的模块,务必先测好阈值再上线,避免误伤正常玩家(同一网吧/NAT 出口可能共享一个公网 IP)。
2.2 nftables 版本(Debian 11+ / Ubuntu 22.04+)
cat > /etc/nftables.conf <<'EOF'
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
# 本地回环与已建立连接
iif "lo" accept
ct state established,related accept
# 管理端口
tcp dport { 22, 80, 443 } accept
# 游戏端口
tcp dport { 3724, 8085 } accept
udp dport 8085 accept
# 限制每 IP 新连接速率(对应 hashlimit)
tcp dport 8085 ct state new \
limit rate 5/second burst 10 packets \
accept
# 未达限速条件的默认丢弃(配合 policy drop)
}
}
EOF
# 加载并开机自启
nft -f /etc/nftables.conf
systemctl enable nftables
注意:nftables 的 limit 是”全局限速”,不区分源 IP。要按源 IP 分别限速,需要用 ct count 配合 set 集合做更精细的控制,这里给出一个按 IP 计数限速的示例:
table inet filter {
# 定义动态集合:记录每个源 IP 的并发连接数
set conn_track {
type ipv4_addr
flags dynamic, timeout
timeout 60s
}
chain input {
type filter hook input priority filter; policy drop;
tcp dport 8085 ct state new \
add @conn_track { ip saddr } \
ct count 100 \
accept
}
}
这套集合会在 60 秒后自动清理过期的源 IP 记录,避免集合无限膨胀。
三、SYN Flood 防护:内核参数调优
SYN Flood 的核心理念是:让内核自己扛住半连接风暴,而不是把压力交给应用层。Linux 内核自带的 SYN cookies 机制非常有效,配合背压队列调优,能扛住相当规模的 SYN Flood。
编辑 /etc/sysctl.conf:
# 开启 SYN Cookies:不依赖半连接队列,用加密 Cookie 验证
net.ipv4.tcp_syncookies = 1
# 半连接队列长度:调大以吸收突发 SYN
net.ipv4.tcp_max_syn_backlog = 65536
# 全连接队列长度(与 listen backlog 配合)
net.core.somaxconn = 65536
# 关闭 SYN Flood 相关的延迟 ACK(加速握手)
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
# SYN-ACK 重传间隔收紧,快速释放无效半连接
net.ipv4.tcp_abort_on_overflow = 1
# 允许的最大 TIME_WAIT 数,防连接堆积
net.ipv4.tcp_max_tw_buckets = 65536
net.ipv4.tcp_tw_reuse = 1
# conntrack 表大小调大,防 UDP Flood 打爆连接跟踪表
net.netfilter.nf_conntrack_max = 1048576
net.netfilter.nf_conntrack_buckets = 262144
# 生效
sysctl -p
几个关键点的说明:
tcp_syncookies = 1:SYN Flood 时的”保命符”。当半连接队列满时,内核不再把 SYN 排入队列,而是直接返回加密的 SYN-ACK Cookie,只有真正完成握手的客户端才会回 ACK。tcp_max_syn_backlog与somaxconn:两个队列长度,前者管半连接,后者管全连接。调大后能吸收突发的连接请求,但要注意会占用更多内存。tcp_synack_retries = 2:缩短 SYN-ACK 重传次数,攻击者根本不回 ACK,快速把无效半连接从队列里踢出去。
内核调优是”免费”的第一层防护,务必在搭建服务器时就配好,而不是等被打了才想起来。
四、UDP Flood 防护:conntrack + 端口白名单
UDP 是无连接协议,天然比 TCP 难防御。游戏常用 UDP 做实时数据(移动同步、战斗指令),所以不能简单丢弃 UDP,而是要精细化限制。
4.1 conntrack 限速:只放行”有来有回”的 UDP
正常玩家是”先发请求、再收响应”的,而 UDP Flood 是单方面猛灌。用 conntrack 的状态机可以识别这一点:
# 只放行 ESTABLISHED 的 UDP 会话(已建联、双向通信)
iptables -A INPUT -p udp --dport 8085 -m conntrack --ctstate ESTABLISHED -j ACCEPT
# 对新建的 UDP 会话做速率限制
iptables -A INPUT -p udp --dport 8085 -m conntrack --ctstate NEW -m hashlimit \
--hashlimit-above 30/sec --hashlimit-burst 60 \
--hashlimit-mode srcip --hashlimit-name udp_conn -j DROP
# 其余未匹配的 UDP 一律丢弃
iptables -A INPUT -p udp --dport 8085 -j DROP
这里的关键是:先放行 ESTABLISHED,再对新会话限速。这样正在玩的玩家不受影响,而纯灌包的攻击流量会被新会话限速挡在外面。
4.2 端口白名单:只开放真正需要的端口
很多攻击是打向随机高位端口的(尤其是带宽型 UDP Flood),因为它们知道运维可能只封了 8085。用白名单策略从根上杜绝:
# 明确只放行这些 UDP 端口,其他全部丢弃
iptables -A INPUT -p udp --dport 8085 -j ACCEPT # 游戏数据
iptables -A INPUT -p udp --dport 1119 -j ACCEPT # 语音(如 TeamSpeak)
iptables -A INPUT -p udp --dport 9987 -j ACCEPT # TeamSpeak 语音
# 最后一条兜底:丢弃所有未明确放行的 UDP
iptables -A INPUT -p udp -j DROP
同时建议把 conntrack 表调大(前面 sysctl 已配置),因为 UDP Flood 会大量创建 conntrack 条目,表满了会拖垮整个防火墙性能。
最后,把规则持久化,重启不丢失:
# CentOS
service iptables save
# 或 Debian/Ubuntu
apt install iptables-persistent
netfilter-persistent save
五、应用层防御:Nginx 反代 + limit_req + limit_conn
游戏服的网站(官网、登录 API、充值页面)是 HTTP Flood 的靶子。用 Nginx 做反向代理,在前面挡一层,配合限流限并发,能把大部分流量挡在应用之外。
5.1 Nginx 限流配置
# /etc/nginx/nginx.conf 的 http 块内定义限流 zone
http {
# 按 IP 限流:每 IP 每秒 5 个请求,突发 10
limit_req_zone $binary_remote_addr zone=req_per_ip:10m rate=5r/s;
# 按 IP 限并发:每 IP 最多 20 个并发连接
limit_conn_zone $binary_remote_addr zone=conn_per_ip:10m;
# 按服务器(全局限流)用于防整体洪峰
limit_req_zone $server_name zone=req_global:10m rate=100r/s;
# 超出限流的响应码与日志级别
limit_req_status 429;
limit_conn_status 429;
server {
listen 443 ssl;
server_name game.example.com;
# 登录/注册 API:严格限流
location /api/login {
limit_req zone=req_per_ip burst=10 nodelay;
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 静态资源:直接本地返回,不进后端
location ~* \.(js|css|png|jpg|gif|ico|woff2)$ {
limit_conn conn_per_ip 20;
expires 7d;
access_log off;
try_files $uri =404;
}
# 其他动态请求:全局限流保护
location / {
limit_req zone=req_global burst=200 nodelay;
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
5.2 配合 fail2ban 封 IP
对于反复触发限流(返回 429)的 IP,用 fail2ban 自动拉黑:
# /etc/fail2ban/jail.local
[nginx-limit-req]
enabled = true
filter = nginx-limit-req
action = iptables-multiport[name="nginx-limit-req", port="http,https"]
logpath = /var/log/nginx/error.log
maxretry = 5
findtime = 300
bantime = 3600
[game-port]
enabled = true
filter = game-port
action = iptables-multiport[name="game-port", port="3724,8085"]
logpath = /var/log/game-server/abuse.log
maxretry = 10
findtime = 60
bantime = 86400
# /etc/fail2ban/filter.d/nginx-limit-req.conf
[Definition]
failregex = ^.* limiting requests, excess: .* by zone .* client: <HOST>$
ignoreregex =
限流(limit_req)+ 限并发(limit_conn)+ 自动封禁(fail2ban)三件套,是应用层防护的黄金组合。
六、游戏协议层防御:WorldServer 加固
最狡猾的攻击是游戏协议 Flood——它看起来完全像正常玩家,只是量特别大。这一层只能在游戏服务器内部做防御,常见的开源框架(AzerothCore、TrinityCore、MaNGOS)都提供了相关手段。
6.1 包频率限制与异常客户端检测
以 AzerothCore/TrinityCore 为例,关键配置在 worldserver.conf:
# 每个连接的包速率限制(防止刷屏/协议 Flood)
MaxOverspeedPings = 2
KickAFKTime = 0
# 单 IP 最大连接数(防止单 IP 开一堆号打)
MaxPlayerLevel = 80
# 客户端校验
StrictChecks = 1
# 断线保护
Anticheat.Enable = 1
更细粒度的做法是在核心层做包频率监控。你可以给 WorldServer 加一个简单的插件,统计每个客户端连接每秒收到的包数量,超过阈值就断开并记录:
// 伪代码:按连接记录包计数
// 每秒重置计数器,超过阈值(如 100 包/秒)判定为 Flood
std::unordered_map<uint32, uint32> pktCount; // connId -> count
std::unordered_map<uint32, uint32> warnCount;
void OnPacketReceived(Connection* conn, Packet* pkt) {
uint32 id = conn->GetId();
if (++pktCount[id] > 100) { // 阈值 100 包/秒
if (++warnCount[id] > 3) { // 连续 3 秒超限
conn->Kick(); // 断开
BanIP(conn->GetRemoteAddress()); // 自动封 IP
Log("FLOD_KICK ip=%s pps=%d", ...);
}
}
}
6.2 自动封禁脚本
WorldServer 把可疑 IP 写进日志后,用脚本定时扫描并写入 iptables/nftables 黑名单:
#!/bin/bash
# /usr/local/bin/autoban.sh
# 从游戏日志中提取可疑 IP 并封禁
LOG=/var/log/game-server/abuse.log
BLOCKLIST=/var/log/game-server/blocklist.txt
BANTIME=86400
# 提取被踢且标记为 FLOD 的 IP(日志格式: FLOD_KICK ip=1.2.3.4 pps=999)
grep "FLOD_KICK" "$LOG" | sed -n 's/.*ip=\([0-9.]*\).*/\1/p' \
| sort -u | while read ip; do
# 跳过已经在黑名单里的
grep -q "$ip" "$BLOCKLIST" && continue
# 写入 iptables 黑名单(nftables 同理)
iptables -A INPUT -s "$ip" -j DROP
echo "$ip $(date +%s)" >> "$BLOCKLIST"
echo "[$(date)] BAN $ip" >> /var/log/game-server/autoban.log
done
# 定时清理过期封禁(示例:nftables 用 timeout 更优雅)
# 这里留个清理占位,nftables 场景直接用 set 的 timeout 自动过期
配合 cron 每分钟执行一次:
*/1 * * * * /usr/local/bin/autoban.sh
协议层防御的原则是:误封代价 < 被打代价。宁可误伤极少数 NAT 出口下的玩家,也不能让一个 Flood 把全服打崩。
七、流量清洗方案:高防 + 自建清洗节点
当攻击流量达到 Gbps 级别,服务器本机的任何规则都是杯水车薪——流量在到达你的网卡之前就把链路打满了。这时候必须上流量清洗,让攻击流量在”上游”就被过滤掉。
7.1 商业高防方案
| 方案 | 适用场景 | 清洗能力 | 优缺点 |
|---|---|---|---|
| Cloudflare Spectrum | 面向海外玩家的游戏服 | 可防护 DDoS,TCP/UDP 代理 | 优点:全球节点、配置简单;缺点:延迟略增、中国大陆访问需注意合规 |
| 阿里云 DDoS 高防(IP 高防) | 中国大陆玩家为主的游戏服 | 最高数百 Gbps 清洗 | 优点:大陆节点快、清洗能力强;缺点:按防护峰值计费较贵 |
| 腾讯云大禹 / 自建清洗 | 对延迟敏感、预算有限的场景 | 视配置而定 | 优点:可控、成本弹性;缺点:需自运维 |
关键点:高防方案通常不直接改变你的源站 IP,而是提供一个”高防 IP”,玩家连接高防 IP,流量清洗后再回源到你的服务器。因此务必:
- 开启回源保护:让源站只接受来自清洗节点的 IP 访问(iptables 只放行高防回源 IP),防止攻击者探测到真实 IP 直接打源站。
- 游戏服尽量走 TCP/UDP 代理模式,不要裸暴露源 IP。
7.2 自建清洗节点架构(预算有限时的方案)
如果买不起高防,可以用一台”前置清洗机”做简易的流量过滤,架构如下:
玩家流量
│
▼
[清洗节点 - 高性能转发机]
│ iptables/nftables 过滤 + 限速 + 白名单
│ 攻击流量在此被丢弃
▼
[游戏服务器 - WorldServer]
# 清洗节点上启用 IP 转发,只转发"干净"的流量
echo 1 > /proc/sys/net/ipv4/ip_forward
# 只转发白名单/清洗后流量到游戏服
iptables -t nat -A PREROUTING -d 清洗节点IP -p tcp --dport 8085 \
-m hashlimit --hashlimit-above 100/sec --hashlimit-burst 200 \
--hashlimit-mode srcip --hashlimit-name fwd -j DNAT --to-destination 游戏服IP
自建清洗节点的核心思路是:把”贵的计算/带宽”从游戏服前移到一台便宜的高带宽转发机上,让攻击流量在转发层就被规则过滤,游戏服只接收干净流量。缺点是需要额外的机器和运维,适合有一定技术能力、流量规模在”几 G 到几十 G”之间的场景。
八、监控告警:NetFlow 分析 + 实时告警 + Discord 通知
被动挨打不可取,主动发现攻击才是高级运维的做法。流量异常往往在被打之前就有征兆。
8.1 NetFlow / sFlow 流量分析
在服务器上抓取并分析流量特征。轻量方案用 iftop、vnstat 看实时流量,重量级方案用 ntopng 或软路由 NetFlow 导出。先看最直接的:
# 实时查看各 IP 的流量排行(秒级)
iftop -i eth0 -n -B
# 统计端口流量
vnstat -i eth0 -d
# 查看当前连接数 TOP 10(快速判断是否被连接洪水)
ss -s
ss -tn state established | awk '{print $4}' | cut -d: -f1 \
| sort | uniq -c | sort -rn | head -10
8.2 实时流量告警脚本 + Discord Webhook
写一个脚本,周期检测入站流量,超过阈值就发 Discord Webhook 告警:
#!/bin/bash
# /usr/local/bin/traffic_alert.sh
# 通过 /proc/net/dev 采样计算实时入站带宽,超阈值发 Discord 告警
INTERFACE=eth0
THRESHOLD_MBPS=200 # 告警阈值:200 Mbps
CHECK_INTERVAL=5 # 采样间隔(秒)
WEBHOOK_URL="https://discord.com/api/webhooks/你的WEBHOOK_ID/你的TOKEN"
STATE_FILE=/var/run/traffic_alert.state
read_txrx() {
awk -v iface="$INTERFACE" \
'$1 ~ iface { print $2, $10 }' /proc/net/dev
}
# 首次采样
read RX1 TX1 < <(read_txrx)
sleep $CHECK_INTERVAL
read RX2 TX2 < <(read_txrx)
# 计算 Mbps(字节差 / 间隔秒 * 8 / 1e6)
RX_BPS=$(( (RX2 - RX1) * 8 / CHECK_INTERVAL ))
RX_MBPS=$(( RX_BPS / 1000000 ))
echo "[$(date '+%F %T')] 入站: ${RX_MBPS} Mbps"
# 超过阈值且未处于告警抑制期,则发送
if [ "$RX_MBPS" -ge "$THRESHOLD_MBPS" ]; then
if [ ! -f "$STATE_FILE" ] || [ $(( $(date +%s) - $(cat $STATE_FILE) )) -gt 600 ]; then
# 防止频繁刷屏,10 分钟内只发一次
echo $(date +%s) > "$STATE_FILE"
curl -s -H "Content-Type: application/json" -X POST "$WEBHOOK_URL" \
-d "{\"content\": \"🚨 **流量告警**\\n入站流量: **${RX_MBPS} Mbps** (阈值 ${THRESHOLD_MBPS} Mbps)\\n时间: $(date '+%F %T')\\n可能正在遭受 DDoS 攻击!\"}"
fi
else
rm -f "$STATE_FILE"
fi
加入 cron 每 5 秒执行一次(用 */5 * * * * * 或写个死循环 daemon):
# cron 最短周期是分钟,推荐用 systemd timer 或直接跑常驻脚本
# 简单方案:每分钟跑一次,间隔 5 秒采样
*/1 * * * * /usr/local/bin/traffic_alert.sh
Discord Webhook 的最大好处是:你人在手机前也能第一时间收到通知,比看监控面板被动得多。同理可以扩展推送到企业微信、钉钉、Telegram。
九、应急响应流程:从发现到恢复
防御做得再好,总会有被打的时刻。应急预案比配置更重要——真被打时,你只有几分钟的反应时间。
| 阶段 | 动作 | 关键命令/操作 |
|---|---|---|
| 1. 攻击发现 | 收到告警 / 玩家反馈掉线 | 确认监控告警,SSH 登入(注意别被一起卡死) |
| 2. 流量分析 | 判断攻击类型与来源 | iftop -n 看流量;ss -s 看半连接;tcpdump -i eth0 -c 1000 抓包看协议 |
| 3. 规则下发 | 按攻击类型下发临时封禁 | SYN Flood:加 connlimit/hashlimit;UDP Flood:加端口限速;打源 IP:临时 DROP |
| 4. 切换清洗 | 大流量时切换高防/清洗节点 | 域名解析切到高防 IP,或让玩家改连清洗节点 |
| 5. 恢复验证 | 确认服务恢复、玩家可登录 | 检查 ss -s 连接数回落,curl 官网 200,让玩家测试登录 |
| 6. 复盘加固 | 记录攻击特征,完善规则 | 把本次攻击的源 IP 段、特征写入长期黑名单/规则库 |
9.1 一份可复用的应急脚本
#!/bin/bash
# /usr/local/bin/ddos_emergency.sh
# 用法: ddos_emergency.sh [syn|udp|all]
# 一键下发应急封禁规则
MODE="${1:-all}"
case "$MODE" in
syn)
echo "[SYN] 启用 SYN Flood 应急防护"
iptables -A INPUT -p tcp --syn -m limit --limit 100/s -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP
;;
udp)
echo "[UDP] 启用 UDP Flood 应急防护"
iptables -A INPUT -p udp -m limit --limit 100/s -j ACCEPT
iptables -A INPUT -p udp -j DROP
;;
all|*)
echo "[ALL] 启用全量应急防护(保留管理端口)"
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# 限速放行游戏端口,其余一律丢弃
iptables -A INPUT -p tcp --dport 8085 -m limit --limit 50/s -j ACCEPT
iptables -A INPUT -p tcp --dport 8085 -j DROP
iptables -A INPUT -p udp --dport 8085 -m limit --limit 50/s -j ACCEPT
iptables -A INPUT -p udp --dport 8085 -j DROP
iptables -A INPUT -j DROP
;;
esac
echo "[OK] 应急规则已下发,攻击结束后执行:"
echo " iptables-save > /root/iptables.bak.emergency"
echo " 如需恢复:iptables-restore < /root/iptables.bak.$(date +%F 之前保存的备份)"
应急核心心法:先恢复服务(宁可暂时误伤一部分),再慢慢精准。不要试图在攻击最猛时追求”零误伤”的完美规则——那会让你陷入”边被打边调规则”的泥潭。
十、DDoS 防护配置速查表
以下是全文所有关键参数的汇总,方便你对照服务器快速核对:
10.1 iptables / nftables 速查
| 场景 | 规则 | 参数参考 |
|---|---|---|
| 限并发 | connlimit | 登录 20,世界服 100 |
| 限新连接速率 | hashlimit | 5/s,burst 10 |
| UDP 双向放行 | conntrack ESTABLISHED | 先放行已建联 |
| UDP 新会话限速 | hashlimit + NEW | 30/s,burst 60 |
| UDP 端口白名单 | 仅放行必要端口 | 末尾 DROP 兜底 |
| 应急封禁 | limit + DROP | 50/s 限速放行 |
10.2 内核参数速查
| 参数 | 推荐值 | 作用 |
|---|---|---|
tcp_syncookies |
1 | SYN Flood 保命符 |
tcp_max_syn_backlog |
65536 | 吸收突发 SYN |
somaxconn |
65536 | 全连接队列 |
tcp_synack_retries |
2 | 快速释放无效半连接 |
tcp_abort_on_overflow |
1 | 队列满时主动拒绝 |
nf_conntrack_max |
1048576 | 防 UDP Flood 打爆跟踪表 |
10.3 Nginx 限流速查
| 指令 | 推荐值 | 作用 |
|---|---|---|
limit_req_zone |
5r/s, burst 10 | 按 IP 限速 |
limit_conn_zone |
20/IP | 按 IP 限并发 |
limit_req_status |
429 | 超限响应码 |
| fail2ban | 5 次/5 分钟 | 自动封禁超限 IP |
结语
游戏服务器 DDoS 防护不是”配一次就完事”的一次性工作,而是一个需要持续迭代的体系。最后的建议:
- 优先级:内核调优 > 网络层规则 > 应用层限流 > 协议层检测 > 流量清洗。先把免费的做好,再考虑花钱的方案。
- 先测再上线:所有阈值(connlimit、hashlimit、limit_req)都先用测试机小流量验证,避免上线即误伤。
- 备份规则:每次修改 iptables/nftables 前务必
save,这是你被打时的救命稻草。 - 写好应急预案:真被打时,时间就是玩家口碑。一份能一键下发的应急脚本,胜过临场翻文档。
最后提醒一句:攻击者的手法也在不断进化,比如打高防 IP 探测源站、伪造 CDN 回源 IP、针对特定游戏协议的定制 Flood。保持监控、定期复盘、及时更新规则库,才能在攻防博弈中长期立于不败之地。