网络安全工程的第一课从 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 drop2.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 -202.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: 因队列满丢弃的连接数3.2 SYN Cookie 防御
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
EOF3.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 accept3.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 30s4.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 防御优势:
- 流量分散:攻击流量被分散到多个清洗节点,每个节点只承受部分流量
- 就近清洗:攻击流量在距离攻击源最近的节点被清洗,不需要穿越长途骨干网
- 自动故障转移:如果某个清洗节点过载,BGP 撤回通告,流量自动切换到其他节点
- 弹性扩展:增加清洗节点就是在新位置通告同一个 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.conf6.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
参考文献
- Jonker, M., et al., “Millions of Targets Under Attack: A Macroscopic Characterization of the DoS Ecosystem,” ACM IMC, 2017.
- Rossow, C., “Amplification Hell: Revisiting Network Protocols for DDoS Abuse,” NDSS, 2014.
- Cloudflare, “DDoS Threat Report,” quarterly reports, 2023–2024.
- RFC 5575, “Dissemination of Flow Specification Rules,” August 2009.
- Bernstein, D.J., “SYN Cookies,” cr.yp.to/syncookies.html.
- Google Cloud Blog, “How Google Cloud Blocked the Largest Layer 7 DDoS Attack at 398 Million rps,” October 2023.
- Linux Kernel Documentation, “SYN Cookie Implementation,” kernel.org.
- Kambourakis, G., et al., “DDoS in the IoT: Mirai and Other Botnets,” Computer, IEEE, 2017.
上一篇: 网络 I/O 模式:Reactor、Proactor 与协程 下一篇: WAF 工程:规则设计、误报控制与绕过防御
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【网络工程】网络入侵检测与防御:Suricata、签名与异常检测
IDS 和 IPS 是网络安全的纵深防御层。本文从 IDS/IPS 的工程差异、Suricata 的多线程架构与部署模式、Snort 规则语法与自定义签名编写、基于异常的流量基线检测、Eve JSON 日志分析与 SIEM 集成,到性能调优和容量规划,系统讲解网络入侵检测与防御的工程实践。
【网络工程】VPN 技术工程对比:IPSec vs WireGuard vs OpenVPN
VPN 是企业网络互联和远程访问的核心技术。本文从 IPSec 的 IKE/ESP/AH 协议栈、WireGuard 的 Cryptokey Routing 设计、OpenVPN 的 TLS 隧道模型,到三者在性能、安全、运维复杂度上的工程对比,系统讲解 VPN 技术的选型与部署实践。
【网络工程】全局负载均衡:GSLB、DNS 调度与 Anycast
系统讲解全局负载均衡的工程实现:GeoDNS 的原理与精度问题、Anycast 的路由收敛与故障转移、BGP 社区在流量调度中的应用、多活架构的流量切换策略,建立跨地域流量调度的完整知识体系。
【网络工程】TCP 连接管理:三次握手、四次挥手与状态机
深入剖析 TCP 连接的完整生命周期——三次握手的每个细节、四次挥手的工程陷阱、11 个状态的实测观察,以及 TIME_WAIT 堆积、SYN Flood 防御、端口复用等生产环境高频问题的系统化解决方案。