DDoS攻击是什么类型?看流量曲线就能判断

被 DDoS攻击时,第一个要回答的问题不是”打多大”,而是”打的哪一层”。判断错了,钱花了攻击还在。本文用 9 个问答讲清怎么从带宽曲线、pps、连接数、平均包长这几个数里反推攻击类型,怎么区分流量型、连接型和应用层攻击,以及每种类型对应的处置动作。

Q:为什么必须先判断攻击类型?

因为三类攻击打的是三种完全不同的资源,防护手段也不通用:

  • 流量型打带宽,UDP Flood、各类反射放大都属于这一类。
  • 连接型打连接资源,SYN Flood、连接跟踪表打满属于这一类。
  • 应用层打处理能力,CC 与 HTTP 洪水属于这一类。

用错手段的典型场景:拿 WAF 去挡 UDP 洪水。WAF 只看七层,UDP 根本到不了它那一层,配再多规则也没用。反过来,拿清洗设备去打针对某个接口的 CC,也会出现”流量没降、服务还是慢”的结果。

Q:拿到监控图先看哪几个数?

六个:入向带宽、pps、新建连接数每秒、并发连接数、源 IP 数量、平均包长。其中最容易被忽略的是 pps 和平均包长——只看带宽会漏判一大类攻击。

# pps 与 Mbps 的换算
# pps = Mbps × 1,000,000 / (8 × 平均包长)
# 1 Gbps 且包长 1000B  → 约 12.5 万 pps
# 1 Gbps 且包长   60B  → 约 208 万 pps
# 同样 1 Gbps,小包场景的包数是大包的 16 倍

所以看到带宽不高但 pps 很高,就要立刻往小包攻击或反射放大方向查。

Q:怎么判断是流量型攻击?

四个特征凑齐两个就基本可以定性:入向带宽明显上涨;pps 同步上涨;平均包长偏小(60 到 200 字节);协议以 UDP 或 ICMP 为主。

# 抽样看入向流量以什么协议为主
tcpdump -i eth0 -nn -c 2000 'udp or icmp' | awk '{print $5}' | sort | uniq -c | sort -rn | head

# 常见被利用的反射放大端口
# 53 DNS / 123 NTP / 11211 memcached / 1900 SSDP / 389 LDAP

看到大量来自这些端口的入向包,就是你的地址被当成了反射放大的目标,这个时候源站做什么都没用,必须在入口侧清洗或转换入口。

Q:怎么判断是连接型攻击?

这类攻击最容易被误判,因为带宽不高、CPU 不高、请求数也不多,但服务就是不可用。要看的是连接维度:

ss -s                                              # 各状态连接数汇总
ss -ant state syn-recv | wc -l                     # 半开连接堆积数量
cat /proc/sys/net/netfilter/nf_conntrack_count     # 连接跟踪表当前占用
cat /proc/sys/net/netfilter/nf_conntrack_max       # 连接跟踪表上限
dmesg | grep -i 'nf_conntrack: table full'         # 表满的系统日志

关键认知:连接跟踪表打满之后,内核对新连接是直接丢包而不是拒绝。所以客户端表现为超时,服务器日志里一条报错都没有,值班的人很容易误判成”网络故障”或”运营商问题”。看到 syn-recv 堆积加上 conntrack 使用率超过 80%,就该按连接型攻击处置。

Q:怎么判断是应用层攻击?

特征是前面几个数都正常,只有应用侧指标恶化:

  • 带宽正常、pps 正常、并发连接正常,但 QPS 明显高于基线。
  • 动态页面响应时间 P95 抬升,缓存命中率下降、回源率上升。
  • 请求集中在少数动态接口,比如搜索、列表、下单。

要和真实活动区分开,靠两个信号:来源集中度(少量 IP 贡献大部分请求)和时间分布(夜间不回落、峰谷比被拉平)。

还有一个常见误区:应用层攻击不能只靠扩容解决。被刷的往往是数据库查询密集的贵接口,扩容等于把成本一起放大,正确顺序是缓存前置、动态接口限速、必要时上人机验证。

Q:遇到混合攻击怎么处理?

现实中很常见”下层压连接、上层刷接口”的组合拳。处置原则是分层处置,先保带宽和连接,再保应用:

  • 第一层:入口清洗,把带宽型和反射放大压掉,保住链路能通。
  • 第二层:内核与连接参数兜底,防止连接耗尽把服务拖死。
  • 第三层:应用限速与降级,保住核心业务链路。

顺序不能反。如果先去做应用限速而不处理下层洪水,链路会被打满,后面的动作都传不进去。

Q:监控曲线全正常,但网站就是挂了?

这种情况大概率不是 DDoS,按三个方向排查:

  • 资源上限被打满:连接跟踪表、文件描述符、本地端口 TIME_WAIT 耗尽,都可能在流量不高时让服务不可用。
  • 上游依赖故障:数据库、缓存、第三方支付或短信通道出问题,表现和攻击非常像。
  • 自身故障:刚发布的代码、内存泄漏、磁盘写满、证书过期。
ss -lnt                                  # 监听端口是否还在
ulimit -n                                # 文件描述符上限
lsof -p 12345 | wc -l                    # 单进程实际打开的资源数
df -h                                    # 磁盘是否写满

先排除自身问题再定性为攻击,可以避免”攻击期间乱改配置”这种二次伤害。

Q:连接型攻击的内核参数怎么调才有用?

sysctl -w net.ipv4.tcp_syncookies=1
sysctl -w net.ipv4.tcp_max_syn_backlog=8192
sysctl -w net.core.somaxconn=8192
sysctl -w net.ipv4.tcp_fin_timeout=15
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.netfilter.nf_conntrack_max=1048576

三点提醒:参数只是提高上限,不是防护,攻击超过上限一样会挂;somaxconn 必须和应用自身的 backlog 一起调,只改一边等于把瓶颈换了个位置;收益最大的是缩短连接超时,把 established 超时从默认的 86400 秒压到 600 秒,连接表回收速度会明显变快。tcp_syncookies 只是兜底,开启后在极端压力下会牺牲部分正常建连能力,攻击结束后应评估是否需要关闭。

Q:还有什么补充建议?

  • 先建基线再谈异常:正常峰值带宽、平均包长、正常新建连接数、单 IP 平均请求数,这四组数没有基线就没法判断。
  • 把 pps、连接数、包长放进同一张图:分开看三张图,判断速度会慢很多。
  • 攻击期间不要盲目改 DNS、不要随手重启:重启能救一时,但会丢掉判断攻击类型的现场数据。
  • 提前和高防服务商对齐:告警阈值、清洗阈值、弹性防护升档流程都要提前走通,临时找人多半来不及。
  • 事后复盘:把攻击曲线和处置动作放到同一条时间线上,才能知道哪一步真正起了作用。

一句话总结:带宽型看包长和协议、连接型看 syn-recv 和连接表、应用型看 QPS 和回源率;类型判断对了,处置动作才能一次打准,而不是拿 WAF 去挡 UDP 洪水。