土法炼钢兴趣小组的算法知识备份

【网络工程】DDoS 防御架构:容量型、协议型与应用层攻击

文章导航

分类入口
network
标签入口
#ddos#syn-flood#anycast#bgp-flowspec#rate-limiting#network-security

目录

网络安全工程的第一课从 DDoS 开始——因为它是最暴力、最直接、也最难彻底解决的攻击类型。DDoS 不利用漏洞,它利用的是协议设计的固有特征和资源的有限性。防御 DDoS 不是写一条防火墙规则的事,而是一个涉及网络架构、流量清洗、协议加固和容量规划的系统工程。

一、DDoS 攻击分类学

理解 DDoS 防御的前提是理解攻击分类。不同类型的 DDoS 攻击利用不同的协议层弱点,防御策略截然不同。

1.1 三大类攻击

┌─────────────────────────────────────────────────────────────────┐
│                     DDoS 攻击分类                                │
├─────────────┬──────────────────┬────────────────────────────────┤
│  容量型攻击  │   协议型攻击      │     应用层攻击                  │
│ (Volumetric) │  (Protocol)      │  (Application Layer)           │
├─────────────┼──────────────────┼────────────────────────────────┤
│ UDP Flood   │ SYN Flood        │ HTTP Flood                     │
│ DNS 放大    │ ACK Flood        │ Slowloris                      │
│ NTP 放大    │ RST Flood        │ Slow POST                      │
│ Memcached   │ LAND Attack      │ API Abuse                      │
│ SSDP 反射   │ Ping of Death    │ CC 攻击                        │
├─────────────┼──────────────────┼────────────────────────────────┤
│ 目标:带宽   │ 目标:状态表      │ 目标:应用资源                  │
│ 量级:Tbps  │ 量级:Mpps       │ 量级:Krps                     │
│ 防御:清洗   │ 防御:协议加固    │ 防御:行为分析                  │
└─────────────┴──────────────────┴────────────────────────────────┘

1.2 攻击规模的演进

DDoS 攻击规模在过去十年呈指数增长:

年份 代表性攻击 峰值流量 攻击手法
2013 Spamhaus 300 Gbps DNS 放大
2016 Dyn DNS 1.2 Tbps Mirai 僵尸网络(IoT)
2018 GitHub 1.35 Tbps Memcached 放大
2020 AWS Shield 2.3 Tbps CLDAP 反射
2023 Google Cloud 398 Mrps HTTP/2 Rapid Reset
2024 Cloudflare 5.6 Tbps Mirai 变种(UDP)

两个趋势值得关注:一是容量型攻击从 Gbps 进入了 Tbps 时代,单靠本地设备已经无法吸收;二是应用层攻击越来越精细——HTTP/2 Rapid Reset 利用的是协议特性而非带宽。

1.3 放大系数

反射放大攻击的核心是利用请求与响应大小不对称的协议。攻击者伪造源 IP 为受害者地址,向开放的反射器发送小请求,反射器返回大响应给受害者:

协议 放大系数 常用端口 开放反射器数量(估算)
Memcached 10,000–51,000x 11211/UDP ~10 万
NTP (monlist) 556x 123/UDP ~40 万
DNS (ANY) 28–54x 53/UDP ~2800 万(Open Resolver)
SSDP 30x 1900/UDP ~800 万
CLDAP 56–70x 389/UDP ~25 万
Chargen 358x 19/UDP <5 万
SNMP v2c 6x 161/UDP ~100 万

Memcached 的 51,000 倍放大系数意味着攻击者发送 1 Mbps 的请求就能产生 51 Gbps 的攻击流量。

二、容量型攻击与防御

2.1 UDP Flood

UDP Flood 是最简单也最常见的容量型攻击。攻击者向目标发送大量 UDP 数据包,不关心端口和内容,目标是消耗带宽和服务器处理能力。

攻击特征: - 源 IP 通常是伪造的(Spoofed) - 目标端口随机或固定 - 数据包大小可变(小包消耗 PPS,大包消耗带宽)

检测方法

# 检查 UDP 流量异常
# 观察 UDP 接收速率是否异常飙升
ss -u -a | wc -l

# 用 iptables 统计 UDP 包速率
iptables -A INPUT -p udp -j LOG --log-prefix "UDP-FLOOD: " --log-level 4
iptables -A INPUT -p udp -m limit --limit 100/s --limit-burst 200 -j ACCEPT
iptables -A INPUT -p udp -j DROP

# 用 nftables 实现更高效的 UDP 速率限制
nft add table inet filter
nft add chain inet filter input '{ type filter hook input priority 0; }'
nft add rule inet filter input ip protocol udp \
    limit rate over 10000/second burst 5000 packets drop

2.2 DNS 反射放大

DNS 反射放大攻击利用开放 DNS 解析器(Open Resolver)。攻击者伪造源 IP 为受害者地址,向开放解析器发送 ANY 类型的查询请求,解析器返回的大响应直接打到受害者:

攻击者 ──(伪造源IP=受害者)──→ 开放DNS解析器
                                    │
                              (大响应包)
                                    │
                                    ↓
                                 受害者

DNS 放大防御——服务端

# BIND9:禁止开放递归解析
# /etc/named.conf
# options {
#     recursion no;               # 禁止递归
#     allow-query { trusted; };   # 限制查询来源
#     rate-limit {
#         responses-per-second 10;  # 限制响应速率
#         window 5;
#     };
# };

# 验证 DNS 服务器是否为开放解析器
dig @your-dns-server example.com ANY +short
# 如果返回结果,说明允许递归查询,需要关闭

# 检查 DNS 流量异常
tcpdump -i eth0 -c 1000 'udp port 53' 2>/dev/null | \
    awk '/A\?/{print $NF}' | sort | uniq -c | sort -rn | head -20

2.3 BGP Flowspec 清洗

当攻击流量超过本地设备处理能力时,需要在上游路由器层面进行流量清洗。BGP Flowspec(RFC 5575)允许通过 BGP 协议动态下发细粒度的流量过滤规则:

# BGP Flowspec 规则示例
# 匹配条件:目标 IP + 协议 + 端口 + 包大小
# 动作:丢弃 / 限速 / 重定向到清洗中心

# ExaBGP 配置示例:丢弃到特定 IP 的 UDP 小包
neighbor 10.0.0.1 {
    router-id 10.0.0.2;
    local-address 10.0.0.2;
    local-as 65000;
    peer-as 65001;

    flow {
        route ddos-block {
            match {
                destination 203.0.113.10/32;
                protocol udp;
                packet-length < 100;
                source-port > 1024;
            }
            then {
                discard;
            }
        }
        route ddos-ratelimit {
            match {
                destination 203.0.113.0/24;
                protocol udp;
                destination-port 53;
            }
            then {
                rate-limit 1000000;  # 限速 1 Mbps
            }
        }
    }
}

BGP Flowspec 的优势在于规则可以在几秒内传播到上游路由器,无需人工登录设备操作。但它需要上游运营商的 BGP Flowspec 支持,且规则复杂度受限于路由器的硬件转发能力。

2.4 Remotely Triggered Black Hole(RTBH)

当攻击流量极大且无法细粒度过滤时,最后的手段是 RTBH——通过 BGP 通告将攻击目标 IP 的所有流量导向黑洞(null route):

# 在边界路由器上配置 RTBH
# 将被攻击的 IP 203.0.113.10 的所有流量丢弃
ip route add blackhole 203.0.113.10/32

# BGP 社区标记触发上游黑洞路由
# 向上游 ISP 通告带有黑洞社区的路由
# 例如 ISP 的黑洞社区为 65001:666
# 上游收到后将该前缀的流量在其边缘丢弃

RTBH 的代价是被攻击的 IP 完全离线——攻击者的目标反而达成了。因此 RTBH 通常只用于保护其他未被攻击的服务,牺牲单个 IP 换取整体网络的存活。

三、协议型攻击与防御

3.1 SYN Flood 攻击原理

SYN Flood 利用 TCP 三次握手的设计:攻击者发送大量 SYN 包但不完成握手,服务器为每个半开连接分配内存(存储 TCB——传输控制块),当半开连接数耗尽 Backlog 队列时,合法连接无法建立。

攻击者 ──→ SYN (伪造源IP) ──→ 服务器
                                  │
                            分配 TCB 内存
                            加入半开队列
                                  │
                            SYN-ACK ──→ 伪造地址(无响应)
                                  │
                            等待 ACK 超时...(默认 ~63 秒)
                                  │
                            队列满 → 拒绝新连接

SYN Flood 检测

# 查看当前 SYN_RECV 状态的连接数
ss -t state syn-recv | wc -l

# 按源 IP 统计 SYN_RECV 连接
ss -t state syn-recv | awk '{print $5}' | cut -d: -f1 | \
    sort | uniq -c | sort -rn | head -20

# 观察 SYN 包速率
# 如果 SYN 速率远高于正常水平,可能遭受 SYN Flood
sar -n DEV 1 5

# 查看半开连接溢出
cat /proc/net/netstat | grep -i "listenoverflows\|listendrops"
# ListenOverflows: 半开队列溢出次数
# ListenDrops: 因队列满丢弃的连接数

SYN Cookie 是 Linux 内核的 SYN Flood 防御机制。核心思想:不在收到 SYN 时分配任何资源,而是将连接状态编码到 SYN-ACK 的序列号中。

SYN Cookie 的编码方式

ISN(初始序列号)编码:
┌───────┬──────────────┬────────────┐
│ 5-bit │   3-bit      │  24-bit    │
│ time  │ MSS index    │  hash      │
├───────┼──────────────┼────────────┤
│ t mod │ MSS编码      │ HMAC(src,  │
│ 32    │ (8种MSS值)   │ dst, port, │
│       │              │ t, secret) │
└───────┴──────────────┴────────────┘

当客户端返回 ACK 时,服务器从 ACK 号反推出原始状态,验证 hash 正确后才分配资源。

配置与调优

# 启用 SYN Cookie(Linux 默认开启)
sysctl -w net.ipv4.tcp_syncookies=1

# SYN Cookie 的局限:
# 1. 只支持 8 种 MSS 值(精度损失)
# 2. 无法携带 TCP 选项(Window Scale、SACK、Timestamp)
# 3. 每次连接都需要密码学计算

# 调优半开队列大小(SYN Cookie 激活前的缓冲)
sysctl -w net.ipv4.tcp_max_syn_backlog=65535

# 减少 SYN-ACK 重传次数(加速超时释放)
sysctl -w net.ipv4.tcp_synack_retries=2

# 完整的 SYN Flood 防御参数集
cat << 'EOF'
# /etc/sysctl.d/99-syn-flood.conf
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_synack_retries = 2
net.core.somaxconn = 65535
net.ipv4.tcp_abort_on_overflow = 0
net.netfilter.nf_conntrack_max = 2000000
EOF

3.3 SYN Proxy

SYN Proxy 比 SYN Cookie 更进一步——由防火墙/负载均衡器代替后端服务器完成 TCP 三次握手,只有握手成功后才将连接转发到后端:

客户端 ──→ SYN ──→ [SYN Proxy] ──(不转发)──→ 后端服务器
                       │
                  SYN-ACK(代理生成)
                       │
客户端 ──→ ACK ──→ [SYN Proxy] ──→ SYN ──→ 后端服务器
                       │              │
                  验证合法连接     建立真实连接
                       │              │
客户端 ←──────────── 数据转发 ←────────┘

nftables 实现 SYN Proxy

# nftables SYN Proxy 配置
nft add table inet synproxy_table
nft add chain inet synproxy_table prerouting \
    '{ type filter hook prerouting priority raw; }'
nft add chain inet synproxy_table input \
    '{ type filter hook input priority filter; }'

# 在 prerouting 阶段跟踪 SYN 包
nft add rule inet synproxy_table prerouting \
    tcp dport 80 tcp flags syn notrack

# 在 input 阶段使用 synproxy
nft add rule inet synproxy_table input \
    ct state invalid,untracked tcp dport 80 \
    synproxy mss 1460 wscale 7 timestamp sack-perm

# 允许已建立的连接
nft add rule inet synproxy_table input \
    ct state established,related accept

3.4 ACK Flood 与 RST Flood

ACK Flood:攻击者发送大量伪造的 ACK 包。服务器收到不属于任何连接的 ACK 后需要查表判断——如果用了 conntrack,每个包都要查 conntrack 表,消耗 CPU。

RST Flood:攻击者发送伪造的 RST 包试图中断已有连接。TCP RFC 要求收到 RST 时检查序列号是否在接收窗口内——攻击者需要猜对序列号。

防御措施:

# 对不属于已知连接的 ACK 包限速
iptables -A INPUT -p tcp --tcp-flags ALL ACK \
    -m conntrack --ctstate INVALID \
    -m limit --limit 100/s -j DROP

# 启用 TCP RFC 5961 的 RST 验证(Linux 默认启用)
# 收到窗口内的 RST 时发送 Challenge ACK 验证
sysctl -w net.ipv4.tcp_challenge_ack_limit=2147483647
# 设为极大值防止 Challenge ACK 限速泄露信息
# (CVE-2016-5696 利用了该限速机制侧信道推断序列号)

四、应用层攻击与防御

4.1 HTTP Flood

HTTP Flood 是最难防御的 DDoS 类型,因为每个请求看起来都像合法流量。攻击者使用真实的 TCP 连接和有效的 HTTP 请求,无法在 L3/L4 层过滤。

HTTP Flood 的变种

变种 特征 难度
简单 GET Flood 固定 URL、固定 User-Agent 易检测
随机 URL GET 随机路径,绕过缓存 中等
POST Flood 消耗服务器计算资源 中等
模拟浏览器 携带 Cookie、执行 JS 困难
分布式慢速 低速率、长时间 极难

4.2 速率限制

速率限制是应用层防御的第一道防线。关键是选对限制维度:

# Nginx 速率限制配置

# 按客户端 IP 限制请求速率
limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;

# 按 URI 限制(保护高成本接口)
limit_req_zone $request_uri zone=peruri:10m rate=50r/s;

# 按 IP + URI 组合限制
map $binary_remote_addr$request_uri $limit_key {
    default $binary_remote_addr$request_uri;
}
limit_req_zone $limit_key zone=peripuri:20m rate=5r/s;

server {
    location /api/ {
        # burst 允许突发,nodelay 不排队直接处理
        limit_req zone=perip burst=20 nodelay;
        limit_req zone=peruri burst=100;
        
        # 超限返回 429 而非默认的 503
        limit_req_status 429;
        
        proxy_pass http://backend;
    }
    
    location /api/login {
        # 登录接口更严格的限制
        limit_req zone=perip burst=5 nodelay;
        limit_req_status 429;
        
        proxy_pass http://backend;
    }
}

令牌桶 vs 漏桶

令牌桶(Token Bucket)          漏桶(Leaky Bucket)
┌─────────────┐               ┌─────────────┐
│  令牌生成器   │               │   请求入口    │
│  (恒定速率)  │               │             │
│      ↓       │               │      ↓      │
│  ┌───────┐  │               │  ┌───────┐  │
│  │ 令牌桶 │  │               │  │  漏桶   │  │
│  │ (有上限)│  │               │  │ (FIFO) │  │
│  └───┬───┘  │               │  └───┬───┘  │
│      ↓       │               │      ↓      │
│  请求消费令牌 │               │  恒定速率出  │
│  → 立即通过  │               │  → 排队等待  │
└─────────────┘               └─────────────┘
允许突发,适合流量波动          严格匀速,适合保护后端

Nginx 的 limit_req 使用漏桶算法,burst 参数定义桶的大小,nodelay 将桶内请求立即处理(类似令牌桶的效果)。

4.3 Slowloris 与 Slow POST

Slowloris 攻击不需要大带宽,它通过保持大量连接处于”正在发送请求”的状态来耗尽服务器的连接资源。攻击者发送不完整的 HTTP 头,定期续传一小段数据防止超时,但永远不发送完整请求。

Slow POST 类似:发送一个声称 Content-Length 很大的 POST 请求,然后以极慢的速度传送 body。

防御配置

# Nginx 防御 Slowloris 和 Slow POST
server {
    # 客户端请求头超时(默认 60s,缩短以防 Slowloris)
    client_header_timeout 10s;
    
    # 客户端请求体超时(防 Slow POST)
    client_body_timeout 10s;
    
    # 限制请求头大小
    large_client_header_buffers 4 8k;
    
    # 限制请求体大小
    client_max_body_size 10m;
    
    # 限制单个 IP 的并发连接数
    limit_conn_zone $binary_remote_addr zone=connperip:10m;
    limit_conn connperip 50;
    
    # 设置 keepalive 超时和请求数
    keepalive_timeout 15s;
    keepalive_requests 100;
}

为什么 Apache 更脆弱而 Nginx 天然抗 Slowloris?Apache 的 prefork 模型为每个连接分配一个进程/线程,连接数直接等于进程数;而 Nginx 使用事件驱动模型,一个 worker 进程处理数千个连接,Slowloris 占据的只是一个文件描述符,开销极小。

4.4 HTTP/2 Rapid Reset(CVE-2023-44487)

2023 年发现的 HTTP/2 Rapid Reset 攻击利用了 HTTP/2 的流多路复用特性。攻击者在单个 TCP 连接上快速发送 HEADERS 帧(创建流)然后立即发送 RST_STREAM 帧(取消流),服务器需要为每个流分配资源和执行清理逻辑,但攻击者不受流并发数限制。

攻击者 ──→ HEADERS (Stream 1) ──→ RST_STREAM (Stream 1)
       ──→ HEADERS (Stream 3) ──→ RST_STREAM (Stream 3)
       ──→ HEADERS (Stream 5) ──→ RST_STREAM (Stream 5)
       ──→ ...(每秒数万个流)

Google 报告此攻击达到了 3.98 亿 RPS(请求/秒)——这是纯粹的应用层攻击,无需大带宽。

防御措施

# Nginx 1.25.3+ 包含 HTTP/2 Rapid Reset 防护
# 限制单个连接上的流重置速率
http2_max_concurrent_streams 100;

# 通过限制每个连接的请求数来间接防御
keepalive_requests 1000;
# HAProxy 防御配置
# haproxy.cfg
# defaults
#     # 限制 HTTP/2 的最大并发流数
#     tune.h2.max-concurrent-streams 100
#     # 限制每个连接的生命周期
#     timeout client 30s

4.5 行为分析与 JavaScript Challenge

对于模拟正常浏览器行为的高级 HTTP Flood,需要行为分析:

JavaScript Challenge(JS Challenge):向首次访问的客户端返回一个包含 JavaScript 计算的页面。合法浏览器执行 JS 后获得 Cookie/Token 再重新请求,Bot 通常无法执行 JS。

行为特征分析

# 伪代码:基于行为特征的 DDoS 检测
class BehaviorAnalyzer:
    def __init__(self):
        self.ip_profiles = {}
    
    def analyze_request(self, request):
        ip = request.remote_addr
        profile = self.ip_profiles.setdefault(ip, {
            'first_seen': time.time(),
            'request_count': 0,
            'unique_urls': set(),
            'user_agents': set(),
            'avg_interval': 0,
            'has_cookies': False,
            'has_referer': False,
            'http2_used': False,
        })
        
        profile['request_count'] += 1
        profile['unique_urls'].add(request.path)
        profile['user_agents'].add(request.headers.get('User-Agent', ''))
        profile['has_cookies'] = bool(request.cookies)
        profile['has_referer'] = bool(request.headers.get('Referer'))
        
        # 异常评分
        score = 0
        
        # 高速率但 URL 单一 → 可疑
        if profile['request_count'] > 100 and \
           len(profile['unique_urls']) < 3:
            score += 30
        
        # 无 Cookie、无 Referer → 可疑
        if not profile['has_cookies'] and \
           not profile['has_referer']:
            score += 20
        
        # 多个 User-Agent → 可疑(正常浏览器不换 UA)
        if len(profile['user_agents']) > 3:
            score += 25
        
        # 请求间隔过于均匀 → 机器行为
        intervals = calculate_intervals(ip)
        if coefficient_of_variation(intervals) < 0.1:
            score += 25
        
        return score  # >70 判定为攻击

五、Anycast 清洗架构

5.1 Anycast 原理

Anycast 是 DDoS 防御的核心网络架构。同一个 IP 地址在多个地理位置的清洗中心同时通告,BGP 路由自动将流量导向最近的清洗节点:

                    攻击流量 + 正常流量
                           │
                    ┌──────┴──────┐
                    │   BGP 路由   │
                    │  (Anycast)  │
                    └──┬────┬──┬─┘
                       │    │   │
              ┌────────┘    │   └────────┐
              ↓             ↓            ↓
     ┌─────────────┐ ┌──────────┐ ┌──────────┐
     │ 清洗中心 A   │ │ 清洗中心 B │ │ 清洗中心 C │
     │ (北美)      │ │ (欧洲)    │ │ (亚太)    │
     │             │ │           │ │           │
     │ ┌─────────┐ │ │ ┌───────┐ │ │ ┌───────┐ │
     │ │ 流量清洗 │ │ │ │ 清洗   │ │ │ │ 清洗   │ │
     │ │ 引擎    │ │ │ │ 引擎   │ │ │ │ 引擎   │ │
     │ └────┬────┘ │ │ └───┬───┘ │ │ └───┬───┘ │
     │      ↓      │ │     ↓     │ │     ↓     │
     │  干净流量   │ │  干净流量  │ │  干净流量  │
     └──────┬──────┘ └─────┬─────┘ └─────┬─────┘
            │              │              │
            └──────────────┼──────────────┘
                           │
                    ┌──────┴──────┐
                    │   源站服务器  │
                    └─────────────┘

Anycast 的 DDoS 防御优势

  1. 流量分散:攻击流量被分散到多个清洗节点,每个节点只承受部分流量
  2. 就近清洗:攻击流量在距离攻击源最近的节点被清洗,不需要穿越长途骨干网
  3. 自动故障转移:如果某个清洗节点过载,BGP 撤回通告,流量自动切换到其他节点
  4. 弹性扩展:增加清洗节点就是在新位置通告同一个 Anycast 前缀

5.2 云清洗服务架构

主流云 DDoS 防护服务(Cloudflare、AWS Shield、Akamai Prolexic)的典型架构:

┌──────────────────────────────────────────────────────────────┐
│                    云清洗服务架构                               │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  层1:边缘网络 Anycast(自动吸收)                              │
│  ┌──────────────────────────────────────────────────────┐    │
│  │ • 全球 PoP 节点(Cloudflare 300+,AWS 400+)          │    │
│  │ • L3/L4 自动过滤(UDP Flood、SYN Flood)              │    │
│  │ • 容量:Tbps 级                                       │    │
│  └──────────────────────────────────────────────────────┘    │
│                           ↓                                  │
│  层2:协议验证(有状态检查)                                    │
│  ┌──────────────────────────────────────────────────────┐    │
│  │ • TCP 代理 / SYN Proxy                                │    │
│  │ • 协议合规性检查                                       │    │
│  │ • 连接速率限制                                         │    │
│  └──────────────────────────────────────────────────────┘    │
│                           ↓                                  │
│  层3:应用层分析(深度检测)                                    │
│  ┌──────────────────────────────────────────────────────┐    │
│  │ • HTTP 请求分析 + JS Challenge                        │    │
│  │ • Bot 检测 + 行为分析                                  │    │
│  │ • WAF 规则引擎                                        │    │
│  └──────────────────────────────────────────────────────┘    │
│                           ↓                                  │
│  层4:回源(干净流量)                                         │
│  ┌──────────────────────────────────────────────────────┐    │
│  │ • GRE / IPsec 隧道回源                                │    │
│  │ • 或 Proxy Protocol 代理回源                           │    │
│  │ • 保留真实客户端 IP                                    │    │
│  └──────────────────────────────────────────────────────┘    │
│                                                              │
└──────────────────────────────────────────────────────────────┘

5.3 On-Demand vs Always-On

维度 On-Demand(按需触发) Always-On(常驻清洗)
流量路径 平时直连,攻击时切换 所有流量始终经过清洗
切换延迟 DNS 切换:分钟级;BGP 切换:秒级 无切换延迟
成本 低(按攻击时间计费) 高(持续计费)
适用场景 偶尔遭受攻击 频繁攻击或高价值业务
风险 切换期间有攻击窗口 增加了正常流量延迟
代表产品 AWS Shield Standard Cloudflare Spectrum

六、多层防御体系

6.1 纵深防御架构

没有单一的防御手段能应对所有 DDoS 攻击。有效的防御需要多层协同:

┌────────────────────────────────────────────────────────┐
│                    纵深防御体系                          │
├──────────┬─────────────────────────────────────────────┤
│ 层级      │ 防御措施                                    │
├──────────┼─────────────────────────────────────────────┤
│ 网络边缘  │ Anycast 清洗、BGP Flowspec、RTBH            │
│ (ISP级)   │ 吸收容量型攻击                               │
├──────────┼─────────────────────────────────────────────┤
│ 入口防护  │ SYN Cookie/Proxy、conntrack 调优            │
│ (防火墙)  │ 过滤协议型攻击                               │
├──────────┼─────────────────────────────────────────────┤
│ 负载均衡  │ 速率限制、连接数限制、地理封禁                 │
│          │ 分散和限制流量                                │
├──────────┼─────────────────────────────────────────────┤
│ 应用网关  │ WAF、JS Challenge、Bot 检测                  │
│          │ 识别和阻断应用层攻击                           │
├──────────┼─────────────────────────────────────────────┤
│ 应用层    │ 缓存、降级、熔断                              │
│          │ 保证核心功能可用                               │
└──────────┴─────────────────────────────────────────────┘

6.2 Linux 服务器加固清单

#!/bin/bash
# DDoS 防御基础加固脚本

# === 内核网络参数 ===
cat > /etc/sysctl.d/99-ddos-hardening.conf << 'EOF'
# SYN Flood 防御
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_synack_retries = 2
net.core.somaxconn = 65535

# 连接追踪表扩容
net.netfilter.nf_conntrack_max = 2000000
net.netfilter.nf_conntrack_tcp_timeout_established = 600
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30

# 防止 IP 欺骗
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# 禁用 ICMP 重定向(防止路由欺骗)
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0

# 忽略广播 ICMP(防 Smurf 攻击)
net.ipv4.icmp_echo_ignore_broadcasts = 1

# 禁用源路由
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0

# 增大文件描述符限制
fs.file-max = 2000000
fs.nr_open = 2000000

# 网络收发缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 65535
EOF

sysctl --system

# === nftables 基础防护规则 ===
cat > /etc/nftables.conf << 'NFTEOF'
#!/usr/sbin/nft -f
flush ruleset

table inet ddos_filter {
    # 限速集合
    set ratelimit_v4 {
        type ipv4_addr
        flags dynamic
        timeout 60s
    }
    
    chain input {
        type filter hook input priority filter; policy accept;
        
        # 允许已建立的连接
        ct state established,related accept
        
        # 丢弃无效包
        ct state invalid drop
        
        # 防止 TCP 端口扫描(无效标志位组合)
        tcp flags & (fin|syn|rst|ack) == fin drop
        tcp flags & (fin|syn) == (fin|syn) drop
        tcp flags & (syn|rst) == (syn|rst) drop
        tcp flags & (fin|syn|rst|psh|ack|urg) == 0 drop
        
        # ICMP 限速(防 Ping Flood)
        ip protocol icmp limit rate 10/second burst 20 packets accept
        ip protocol icmp drop
        
        # 新连接速率限制(每 IP 每秒最多 30 个新连接)
        ct state new limit rate over 30/second burst 10 packets drop
    }
}
NFTEOF

nft -f /etc/nftables.conf

6.3 监控与告警

DDoS 防御不只是配置规则——需要持续监控以便及时响应:

# Prometheus 告警规则示例
# prometheus-ddos-alerts.yml
groups:
  - name: ddos_alerts
    rules:
      # SYN Flood 检测
      - alert: SynFloodDetected
        expr: |
          rate(node_netstat_Tcp_PassiveOpens[1m]) > 10000
          and rate(node_netstat_TcpExt_ListenDrops[1m]) > 100
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "SYN Flood 检测:新连接速率异常且出现丢弃"
          
      # 带宽异常
      - alert: BandwidthAnomaly
        expr: |
          rate(node_network_receive_bytes_total{device="eth0"}[5m]) * 8
          > 8e9
        for: 3m
        labels:
          severity: warning
        annotations:
          summary: "入站带宽超过 8Gbps,可能遭受容量型攻击"
          
      # 连接数异常
      - alert: ConnectionFlood
        expr: |
          node_netstat_Tcp_CurrEstab > 50000
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "TCP 连接数超过 5 万,可能遭受连接耗尽攻击"
          
      # conntrack 表即将溢出
      - alert: ConntrackNearFull
        expr: |
          node_nf_conntrack_entries
          / node_nf_conntrack_entries_limit > 0.8
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "conntrack 表使用率超过 80%"
# 实时监控命令合集
# 监控 SYN_RECV 连接数变化
watch -n 1 'ss -t state syn-recv | wc -l'

# 监控每秒新建连接数
watch -n 1 'cat /proc/net/netstat | grep -oP "(?<=PassiveOpens )\d+"'

# 监控网卡 PPS(每秒包数)
sar -n DEV 1

# 监控 conntrack 表使用率
watch -n 5 'echo "$(cat /proc/sys/net/netfilter/nf_conntrack_count) / $(cat /proc/sys/net/netfilter/nf_conntrack_max)" | bc -l'

七、DDoS 应急响应手册

7.1 攻击判定流程

                    ┌─────────────────┐
                    │ 服务不可用 / 慢  │
                    └────────┬────────┘
                             │
                    ┌────────┴────────┐
                    │ 检查带宽和 PPS  │
                    └────────┬────────┘
                             │
                 ┌───────────┴───────────┐
                 │                       │
          带宽/PPS 异常            带宽/PPS 正常
                 │                       │
          容量型/协议型             ┌─────┴─────┐
                 │                 │           │
          ┌──────┴──────┐     CPU 高        CPU 正常
          │             │         │           │
     UDP 为主      TCP 为主    应用层攻击   检查应用
          │             │         │        自身问题
     UDP Flood    SYN Flood   HTTP Flood
     DNS 放大     ACK Flood   Slowloris

7.2 应急响应步骤

# 第一步:快速评估攻击类型和规模
echo "=== 网卡流量 ==="
ip -s link show eth0 | grep -A 2 "RX:"

echo "=== TCP 状态分布 ==="
ss -ant | awk '{print $1}' | sort | uniq -c | sort -rn

echo "=== TOP 源 IP ==="
ss -ant | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head -20

echo "=== conntrack 使用 ==="
echo "当前: $(cat /proc/sys/net/netfilter/nf_conntrack_count)"
echo "上限: $(cat /proc/sys/net/netfilter/nf_conntrack_max)"

echo "=== SYN_RECV 数 ==="
ss -t state syn-recv | wc -l

echo "=== 网络错误 ==="
netstat -s | grep -iE "overflow|drop|retrans|reset"

# 第二步:根据攻击类型采取措施
# 如果是 UDP Flood → 联系上游 ISP 启用 Flowspec / RTBH
# 如果是 SYN Flood → 确认 SYN Cookie 启用,调优 backlog
# 如果是 HTTP Flood → 启用 WAF 规则,开启 JS Challenge

# 第三步:封禁攻击源(如果源 IP 集中)
# 用 ipset 批量封禁效率更高
ipset create ddos_blocklist hash:net hashsize 65536 maxelem 1000000
# 将攻击 IP 加入黑名单
# ipset add ddos_blocklist 1.2.3.0/24
iptables -I INPUT -m set --match-set ddos_blocklist src -j DROP

# 第四步:切换到云清洗服务
# 修改 DNS 将流量导向云清洗
# 或通过 BGP 通告将前缀切换到清洗中心

7.3 事后复盘

每次 DDoS 攻击都应进行事后复盘:

复盘项目 关键问题
攻击画像 攻击类型、峰值流量、持续时间、源 IP 分布
检测时效 从攻击开始到检测到经过多久?告警是否及时?
响应效率 从检测到缓解经过多久?瓶颈在哪里?
影响范围 哪些服务受影响?用户影响面多大?
防御效果 哪些防御措施生效了?哪些没有?
改进计划 需要增加什么防御能力?预案需要更新什么?

八、DDoS 防御选型

8.1 防御方案对比

方案 适用攻击类型 防御容量 成本 部署复杂度
内核参数加固 小规模协议型 100 Kpps 免费
nftables/iptables 协议型 + 基础限速 1 Mpps 免费
硬件防火墙 协议型 + 容量型 10–100 Gbps
ISP 清洗 容量型 ISP 带宽
云清洗(On-Demand) 全类型 Tbps
云清洗(Always-On) 全类型 Tbps
XDP 自研 定制化场景 10+ Mpps 人力 极高

8.2 决策流程

你的服务是否已经使用 CDN/云清洗?
├── 是 → 确保配置正确(源站 IP 不暴露、回源加密)
│        → 定期进行 DDoS 演练
│
└── 否 → 你的带宽 > 10 Gbps?
         ├── 是 → 考虑自建 + ISP 清洗
         │        (硬件防火墙 + BGP Flowspec)
         │
         └── 否 → 攻击频率?
                  ├── 偶尔 → 云清洗 On-Demand
                  │         + 内核加固 + nftables
                  │
                  └── 频繁 → 云清洗 Always-On
                            + 内核加固 + WAF

参考文献

  1. Jonker, M., et al., “Millions of Targets Under Attack: A Macroscopic Characterization of the DoS Ecosystem,” ACM IMC, 2017.
  2. Rossow, C., “Amplification Hell: Revisiting Network Protocols for DDoS Abuse,” NDSS, 2014.
  3. Cloudflare, “DDoS Threat Report,” quarterly reports, 2023–2024.
  4. RFC 5575, “Dissemination of Flow Specification Rules,” August 2009.
  5. Bernstein, D.J., “SYN Cookies,” cr.yp.to/syncookies.html.
  6. Google Cloud Blog, “How Google Cloud Blocked the Largest Layer 7 DDoS Attack at 398 Million rps,” October 2023.
  7. Linux Kernel Documentation, “SYN Cookie Implementation,” kernel.org.
  8. Kambourakis, G., et al., “DDoS in the IoT: Mirai and Other Botnets,” Computer, IEEE, 2017.

上一篇: 网络 I/O 模式:Reactor、Proactor 与协程 下一篇: WAF 工程:规则设计、误报控制与绕过防御

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2025-07-28 · network

【网络工程】网络入侵检测与防御:Suricata、签名与异常检测

IDS 和 IPS 是网络安全的纵深防御层。本文从 IDS/IPS 的工程差异、Suricata 的多线程架构与部署模式、Snort 规则语法与自定义签名编写、基于异常的流量基线检测、Eve JSON 日志分析与 SIEM 集成,到性能调优和容量规划,系统讲解网络入侵检测与防御的工程实践。

2025-07-28 · network

【网络工程】VPN 技术工程对比:IPSec vs WireGuard vs OpenVPN

VPN 是企业网络互联和远程访问的核心技术。本文从 IPSec 的 IKE/ESP/AH 协议栈、WireGuard 的 Cryptokey Routing 设计、OpenVPN 的 TLS 隧道模型,到三者在性能、安全、运维复杂度上的工程对比,系统讲解 VPN 技术的选型与部署实践。

2025-08-22 · network

【网络工程】全局负载均衡:GSLB、DNS 调度与 Anycast

系统讲解全局负载均衡的工程实现:GeoDNS 的原理与精度问题、Anycast 的路由收敛与故障转移、BGP 社区在流量调度中的应用、多活架构的流量切换策略,建立跨地域流量调度的完整知识体系。


By .