服务器DDoS攻击是什么?攻击类型、识别方法与防护方案

网站突然打不开,SSH 也连不上,看监控发现带宽从平时的 5 Mbps 涨到 900 Mbps——这是很多人第一次遭遇 DDoS 的场景。DDoS 和普通的"访问量大"最大的区别在于:请求不是真实用户发出的,来源高度集中或高度分散但行为异常,且目的就是让你不可用。它不偷数据、不留后门,代价是业务中断和账单。

这篇文章只讲防御视角:DDoS 有哪些类型、怎么从监控和日志里判断自己正在被打、单机层面能做哪些自助缓解、架构层面该怎么设计才能扛住,以及事后怎么复盘。本文不涉及任何发起攻击的方法或工具使用教程,讨论的所有命令和配置都用于识别和防护。

DDoS 到底是什么

DDoS(Distributed Denial of Service,分布式拒绝服务)的核心定义是:攻击者控制大量分布式的主机,向目标持续发送超出其处理能力的流量或请求,使正常用户无法获得服务。关键词是"分布式"和"超出处理能力"。

它和几种容易混淆的情况要区分开:

现象 与 DDoS 的区别
正常大促流量峰值 来源分散、行为合理、有业务节奏、可预测
爬虫抓站 请求有规律但量级有限,可用频率限制与 robots 约束
程序 bug 导致资源耗尽 流量不大但服务不可用,属自身问题
上游网络故障 与流量无关,表现为全站不可达但无任何请求
DDoS 请求量大且异常、来源集中或伪造、与业务节奏无关

理解"超出处理能力"很重要。同一套流量打在不同规模的架构上结果完全不同:100 Mbps 的流量对单机是灾难,对有清洗能力的大带宽集群可能毫无影响。所以防护的本质是让自己一侧的处理能力大于攻击流量,或者让攻击流量到不了自己。

攻击类型与分层

按 OSI 层级划分,DDoS 通常分为三类,防护手段完全不同。

第一类是网络层与传输层的流量型攻击,目标是塞满带宽。典型如 UDP Flood、ICMP Flood,以及利用放大效应的反射攻击:攻击者把源地址伪造成受害者地址,向开放的第三方服务发请求,第三方把放大的响应全部发给受害者。常见的反射源包括 DNS、NTP、Memcached 等,放大倍数从几倍到上万倍不等(这也是为什么运维要关闭对公网开放的这些服务,属于"不做帮凶"的合规要求)。这类攻击的特征是入向带宽被打满,单机完全无力抵抗,因为瓶颈在链路上。

第二类是协议型攻击,目标是耗尽服务器的连接资源而不是带宽。最典型的是 SYN Flood:攻击者发送大量 TCP 连接请求但不完成握手,服务器的半连接队列被占满,正常用户的连接请求排不进去。特征是带宽可能没满,但新连接建立不了,ss 里能看到大量 SYN_RECV 状态的连接。此外还有 ACK Flood、RST Flood、连接耗尽等变体。

第三类是应用层攻击,也就是常说的 CC 攻击。它发送的是看起来完全合法的 HTTP 请求,比如反复请求最耗资源的搜索页、动态生成页、大文件下载接口。特征是请求量不一定特别大、带宽占用不高,但 CPU、数据库、磁盘 IO 被打满。这类攻击最难防,因为请求本身没有明显异常特征,很难与真实用户区分。

类型 攻击目标 典型特征 主要防护位置
流量型 带宽 入向带宽突增、PPS 极高 运营商清洗、高防、CDN
协议型 连接表、CPU SYN_RECV 堆积、带宽不高 内核参数、清洗设备、高防
应用层 CPU、数据库、IO QPS 高、带宽不高、URL 集中 WAF、限流、缓存、扩容

这张表决定了后面的防护策略:流量型靠带宽和清洗,协议型靠连接处理能力和系统参数,应用层靠限流、缓存和业务架构。用错位置等于白花钱。

怎么识别自己被打

第一看带宽和 PPS。 云监控里入向带宽、包速率突然背离历史基线是最直观的信号。需要留意的是,很多攻击发生在深夜,等第二天看监控图才发现有一条很高的柱子。所以告警比看图更重要:对入向带宽、出向带宽、PPS 设置同比、环比阈值。

第二看连接状态。 协议型攻击在连接上表现明显:

# 统计各状态连接数
ss -ant | awk 'NR>1 {print $1}' | sort | uniq -c | sort -rn

# 查看 SYN_RECV 堆积
ss -ant state syn-recv | wc -l
ss -ant state syn-recv | head -20

# 统计来源 IP 连接数 Top 20
ss -ant | awk '{print $5}' | grep -oP '^[0-9.]+' | sort | uniq -c | sort -rn | head -20

# 统计总连接数与 TIME_WAIT
ss -s

如果 SYN_RECV 数量持续在几千以上且来自大量不同 IP,基本可以确定是 SYN Flood。如果某个来源 IP 有几千条 ESTABLISHED,说明它在做连接耗尽。

第三看 Web 日志。 应用层攻击在日志里最清楚:

# Top 来源 IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

# Top UA
awk -F'"' '{print $6}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10

# Top URL
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

# 实时 QPS(每秒请求数)
tail -f /var/log/nginx/access.log | awk '{print $4}' | uniq -c

# 统计最近一分钟请求数
awk -v d="$(date -d '1 min ago' '+%d/%b/%Y:%H:%M')" '$4 ~ d {c++} END {print c}' /var/log/nginx/access.log

判断要点:如果 Top IP 里前几个占了总请求量的一半以上,或者 UA 高度一致(同一个浏览器标识出现成千上万次),或者请求集中在一两个高消耗 URL 上,就可以判定为应用层攻击。注意不要只看单 IP:分布式 CC 会让每个 IP 的请求量看起来都正常,这时要看整体 QPS 是否远超历史峰值,以及新来源 IP 的比例是否异常升高。

第四看资源。 CPU、负载、数据库连接数、磁盘 IO 的异常突增,配合上面的流量和日志数据一起判断。单看 CPU 高会误判为程序问题。

单机自助缓解

必须诚实说明:单机能做的缓解非常有限。当攻击流量大于你的接入带宽时,包根本到不了服务器,任何软件层面的配置都无能为力。所以下面的措施主要应对中小规模攻击和协议型、应用层攻击。

Nginx 层面限流。 这是应用层最有效的手段:

# http 段定义限流区,$binary_remote_addr 按 IP 统计,10m 约可存 16 万条记录
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

server {
    # 单 IP 每秒最多 10 个请求,突发允许 20 个排队,超出返回 503
    limit_req zone=req_limit burst=20 nodelay;
    # 单 IP 最多 20 个并发连接
    limit_conn conn_limit 20;

    # 连接与读写超时缩短,快速释放资源
    client_body_timeout   10s;
    client_header_timeout 10s;
    send_timeout          10s;
    keepalive_timeout     15s;
}

rate 的值要按业务实际设定:API 服务可以设高些,纯动态页面设低些。设太严会误伤真实用户(尤其是公司出口 IP 共用的场景),上线前先在测试环境观察一段时间。

内核参数缓解 SYN Flood。 SYN Cookie 是最经典的机制,让服务器在半连接队列满时仍能通过 Cookie 验证完成握手:

# /etc/sysctl.d/99-ddos.conf
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_abort_on_overflow = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_max_tw_buckets = 65536
net.core.somaxconn = 65535
net.netfilter.nf_conntrack_max = 262144

sudo sysctl -p /etc/sysctl.d/99-ddos.conf

SYN Cookie 会牺牲少量 TCP 可选特性换取抗压能力,是合理的取舍。nf_conntrack_max 调大是为了避免连接跟踪表被打满,但注意它会增加内存占用,每条约几百字节,调太大要评估内存。

关闭不必要的服务与端口。 这一条既是安全加固也是 DDoS 防护:对外开放的 DNS、NTP、Memcached、SNMP 等服务不仅可能被利用做反射源,本身也是被攻击的目标。

封禁 IP 段的局限。 对 Top IP 做封禁能解决小规模问题,但面对分布式攻击时收益极小:

# 封禁单个 IP(Debian、Ubuntu)
sudo ufw deny from 1.2.3.4
# RHEL 系
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="1.2.3.4" drop'
sudo firewall-cmd --reload

原因有三点:攻击 IP 数量可能是几万甚至几十万,逐条加规则会拖垮防火墙性能;来源 IP 大多是被伪造的,封了也影响不到真正的攻击源;分布式攻击的单个 IP 请求量本来就不高,封掉意义不大。封 IP 只适合处理少量明显的恶意来源,不要把它当成主要手段。

架构层面的防护

真正能扛住大规模攻击的是架构,不是配置。

CDN 隐藏源站。 把域名解析到 CDN,源站 IP 不对外暴露。CDN 节点分散在各地且容量巨大,攻击流量会被分散到边缘节点,很多攻击在边缘就被限流或拦截。这里的关键动作是源站 IP 不能泄露:

  • 源站防火墙只放行 CDN 的回源 IP 段,其他来源一律拒绝访问 80、443。
  • 不要在同一台机器上用源站 IP 直接提供其他服务,避免被扫到。
  • 检查历史 DNS 解析记录,老的记录可能暴露过源站 IP。
  • 邮件服务、监控探测等不要配置在源站 IP 上,否则一封邮件头就泄露了。
  • 如果源站 IP 已经泄露,换 IP 并重新配置回源白名单。

高防 IP 与云清洗。 高防的原理是把流量先引到有大带宽和清洗能力的节点,过滤掉攻击流量后把正常流量回源。它的防护能力以"防护带宽"和"清洗能力"计量。接入方式通常是将域名 CNAME 到高防,或将业务 IP 替换为高防 IP。适用于流量型和协议型攻击。

WAF 应对应用层。 应用层攻击需要 WAF 做频率限制、人机校验、行为分析。WAF 与高防常常组合使用:高防清洗网络层,WAF 处理应用层。

弹性扩容。 对应用层攻击,扩容能换来喘息时间,但要清醒认识成本:攻击流量可以轻松超过你的扩容预算,所以扩容只能作为辅助,不能作为唯一手段。更实际的做法是降低单请求成本:加缓存、静态化、减少数据库查询,让同样的资源能扛住更多请求。

架构建议按业务重要性分层:

业务类型 推荐防护组合
企业官网、博客 CDN + 基础限流 + 源站隐藏
电商、门户 CDN + 高防 + WAF + 弹性扩容
游戏、实时通信 高防(UDP 防护能力)+ 多地域部署
金融、政务 高防 + WAF + 多线路 + 完整应急预案
API 服务 WAF 频率限制 + 网关限流 + 鉴权

事后复盘

攻击结束后要做的事比攻击中更重要:

一,保存完整数据。 监控图、日志、连接统计、ss 快照都能帮你在下次快速判断。攻击期间的日志要单独归档,默认轮转会覆盖掉。

二,分析攻击特征。 是流量型还是应用层?峰值是多少?持续多久?来源集中在哪些地区?目标 URL 是哪个?这些决定了你要加强哪一层的防护。

三,评估防护有效性。 哪些措施起了作用,哪些形同虚设。很多团队买了很多防护产品,真出事时发现配置没生效或者回源没做白名单,源头 IP 一被绕过所有防护都白搭。

四,完善预案。 明确攻击发生时的联系人、决策流程(什么时候切换高防、什么时候降级服务)、沟通话术。预案要演练,写在文档里没人看等于没有。

五,降级方案。 准备好"最坏情况下只保留核心功能"的方案:静态页、维护公告、关闭高消耗接口。牺牲部分功能保住核心业务,远比全站不可用好。

常见问题

攻击流量只有几十 Mbps,为什么网站就打不开了?

可能是应用层攻击。几十 Mbps 的请求量如果集中在动态页面,足以把数据库和 CPU 打满。判断方法是看 QPS 和 CPU、数据库连接数,而不是只看带宽。这种情况加带宽没用,要加缓存、限流和优化慢接口。

加了 CDN 是不是就不会被打了?

不是。CDN 能扛住大部分网络层攻击并隐藏源站,但如果源站 IP 泄露,攻击者绕过 CDN 直接打源站,防护就失效了。所以配置 CDN 后必须做回源 IP 白名单,且不要在源站 IP 上暴露任何其他服务。

高防能防住 CC 攻击吗?

要看产品定位。以流量清洗为主的高防主要处理网络层和协议层,应用层 CC 需要 WAF 的频率限制和人机校验配合。选型时要确认防护覆盖到哪一层,别假设"买了高防就什么都能防"。

能不能靠封 IP 解决问题?

小量级可以。分布式攻击基本无效,因为来源 IP 成千上万且可能是伪造的,逐条封禁还会让防火墙规则表膨胀影响性能。封 IP 只适合处理少量明显的持续恶意来源。

遭受攻击需要上报吗?

如果影响到大量用户或涉及关键信息基础设施,按所在行业的合规要求可能需要向监管或运营商报告。涉及违法犯罪行为的,可以向公安机关网络违法犯罪举报渠道反映。同时建议联系接入的云厂商或运营商获取技术支持。

总结

  • DDoS 分为流量型(打带宽)、协议型(打连接表)、应用层(打 CPU 和数据库)三类,防护位置完全不同,判断错类型会导致措施失效。
  • 识别靠四组数据:监控里的带宽与 PPS、ss -ant 的状态统计(尤其 SYN_RECV 堆积)、Nginx 日志的 Top IP/UA/URL、以及 CPU 与数据库连接数。要结合看,单看一项容易误判。
  • 单机能做的有限,主要在 Nginx 限流(limit_req、limit_conn)、缩短超时、SYN Cookie 与内核参数调优上;封 IP 对分布式攻击基本无效,不要当成主要手段。
  • 架构层面才是关键:CDN 隐藏源站并配置回源 IP 白名单、高防 IP 做流量清洗、WAF 处理应用层、降低单请求成本,并准备核心功能降级方案。
  • 事后必须复盘:归档攻击期间的完整数据、分析攻击特征、验证防护是否真正生效、完善并演练应急预案,把一次事故变成下次的从容。