12、网络层防护:TCP/UDP异常流量检测、IP代理/VPN识别、DDoS与CC攻击防护

网络层防护,说白了就是游戏服务器的第一道大门。我做了这么多年安全,见过太多游戏上线第一天就被打趴下的案例。你想想看,玩家还没进来,攻击者先到了。这章我就聊聊怎么把这扇门守好。

12.1 TCP/UDP异常流量检测

游戏服务器最常用的就是TCP和UDP。TCP讲究可靠,UDP讲究速度。但攻击者偏偏喜欢利用这些特性搞事情。

12.1.1 TCP异常行为识别

TCP协议本身有一套完整的状态机。正常玩家连接,三次握手,数据传输,四次挥手。但攻击者不会按套路出牌。

我在项目中遇到过一种情况:某个区服突然大量出现半连接状态。查了下,是典型的SYN Flood攻击。攻击者只发SYN包,不完成握手,把服务器的连接队列塞满了。

核心检测指标:

  • SYN包与ACK包的比例异常(正常约1:1,攻击时可达到10:1以上)
  • 单个IP的并发半连接数超过阈值(我一般设50-100)
  • TCP重传率突然飙升(超过5%就要警惕)
  • RST包异常增多(可能是扫描行为)
// 伪代码:TCP异常检测逻辑
function detectTCPAnomaly(packet):
    if packet.isSYN and not packet.isACK:
        halfOpenCount[packet.srcIP]++
        if halfOpenCount[packet.srcIP] > MAX_HALF_OPEN:
            alert("SYN Flood 嫌疑: " + packet.srcIP)
            blockIP(packet.srcIP, 60) // 临时封禁60秒
    if packet.isRST:
        rstCount[packet.srcIP]++
        if rstCount[packet.srcIP] > MAX_RST_PER_MIN:
            alert("端口扫描嫌疑: " + packet.srcIP)

12.1.2 UDP异常行为识别

UDP就更有意思了。它无连接,攻击者可以伪造源IP,你根本不知道谁打的你。

我记得有一次,一个MMO游戏突然延迟爆炸。查了半天,发现是UDP Flood。攻击者用僵尸网络发大量小包,每个包只有几十字节,但每秒几百万个,直接把带宽打满了。

我的经验:UDP防护不能只靠服务器端。一定要在网关层做限速。我习惯的做法是:

  1. 按IP统计UDP包速率,超过1000pps(包每秒)就丢包
  2. 对UDP payload长度做校验,小于20字节的包直接丢弃
  3. 建立UDP会话表,只有通过认证的玩家才转发数据

12.2 IP代理/VPN识别

为什么要识别代理和VPN?因为攻击者几乎都躲在代理后面。正常玩家用家庭宽带直连,攻击者用各种跳板。

识别方法主要有三种:

方法 原理 准确率 我踩过的坑
IP黑名单库 维护已知代理/VPN的IP段 70%左右 更新不及时,漏掉新节点
行为特征分析 检测延迟、路由跳数、TLS指纹 85%左右 误伤CDN节点
协议特征检测 识别OpenVPN、WireGuard等协议特征 90%以上 加密流量难识别

注意:我曾经把某云游戏的加速器节点误判为VPN,导致一批付费玩家无法登录。后来加了白名单机制,对已知的合法代理放行。记住,宁可漏过,不要误伤。

12.3 DDoS与CC攻击防护

DDoS和CC是游戏服务器最头疼的两种攻击。DDoS打带宽,CC打应用层。我见过最狠的一次,攻击流量达到800Gbps,直接把整个机房的出口打瘫了。

12.3.1 DDoS防护策略

DDoS防护讲究分层防御。你不能指望单点扛住所有攻击。

DDoS分层防御架构 第一层:云清洗中心 阿里云/腾讯云/AWS Shield 第二层:硬件防火墙 每秒过滤百万级包 第三层:网关层限流 IP白名单 + 连接数限制 第四层:应用层检测 行为分析 + 频率控制 攻击流量 清洗后 正常流量

我个人的习惯是:云清洗扛大流量(100Gbps以上),硬件防火墙做第一道过滤,网关层做精细控制。三层下来,大部分攻击都被挡在外面了。

12.3.2 CC攻击防护

CC攻击比DDoS更阴险。它不占带宽,但占你的CPU和数据库连接。攻击者模拟正常玩家行为,发大量业务请求。

举个例子:一个登录接口,正常玩家每秒请求1-2次。攻击者用几百个代理,每秒发几万次登录请求。你的数据库连接池瞬间被占满,正常玩家登录不了。

CC防护三板斧:

  • 频率限制:每个IP每秒最多N次请求。N根据业务定,登录接口我设5次/秒,游戏内操作设20次/秒
  • 验证码:触发频率限制后,弹出滑块验证。攻击者一般不会过验证码
  • 行为分析:检测鼠标轨迹、点击间隔。真人玩家有随机性,脚本是机械的
// 频率限制实现(Go语言示例)
type RateLimiter struct {
    visitors map[string]*Visitor
    mu       sync.Mutex
}

type Visitor struct {
    count    int
    lastSeen time.Time
}

func (rl *RateLimiter) Allow(ip string, limit int) bool {
    rl.mu.Lock()
    defer rl.mu.Unlock()
    
    v, exists := rl.visitors[ip]
    if !exists {
        rl.visitors[ip] = &Visitor{count: 1, lastSeen: time.Now()}
        return true
    }
    
    if time.Since(v.lastSeen) > time.Second {
        v.count = 1
        v.lastSeen = time.Now()
        return true
    }
    
    v.count++
    return v.count <= limit
}

避坑指南:我曾经把频率限制设得太死,导致游戏内公会战期间大量玩家被误封。后来我加了动态阈值——根据当前在线人数自动调整限制值。在线人数多的时候放宽限制,少的时候收紧。

12.4 实战经验总结

说了这么多,最后分享几个我在实战中总结的要点:

  1. 不要过度依赖单一方案。云清洗、硬件防火墙、软件检测,三者缺一不可。我见过只买云清洗的,结果云清洗节点被打穿后,服务器直接裸奔。
  2. 日志一定要全。没有日志,攻击过后你连谁打的都不知道。我习惯把所有网络层的日志存到Elasticsearch,保留30天。
  3. 自动化响应。检测到攻击后,自动触发防护策略。人工响应太慢了,等你登录服务器,攻击已经持续了10分钟。
  4. 定期演练。每个月做一次红蓝对抗。我让运维团队模拟攻击,安全团队防守。只有实战才能发现问题。

最后提醒一句:网络层防护不是一劳永逸的。攻击手段在进化,你的防护也要跟着升级。我每个月都会review一次防护策略,看看有没有新的攻击手法需要应对。


公众号:蓝海资料掘金营,微信deep3321