游戏服务器 DDoS 防护实战:从流量清洗到应用层防御的完整方案 原创

温馨提示:
本文最后更新于 2026-09-12,已超过 0 天没有更新。 若文章内的图片失效(无法正常加载),请留言反馈或直接 联系我

引言:为什么游戏服务器是 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 实战配置

网络层是防御的第一道防线。下面给出 iptablesnftables 两套等价配置,根据你服务器的发行版选择。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

connlimithashlimit 是两个最容易出效果的模块,务必先测好阈值再上线,避免误伤正常玩家(同一网吧/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_backlogsomaxconn:两个队列长度,前者管半连接,后者管全连接。调大后能吸收突发的连接请求,但要注意会占用更多内存。
  • 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 流量分析

在服务器上抓取并分析流量特征。轻量方案用 iftopvnstat 看实时流量,重量级方案用 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。保持监控、定期复盘、及时更新规则库,才能在攻防博弈中长期立于不败之地。