服务器怎么防DDoS攻击

结论: 防 DDoS 攻击的核心是"隐藏源站 + 上游清洗 + 分层兜底"三件事:用 CDN 或高防 IP 隐藏源站真实 IP,把大流量交给云端清洗中心承担,源站侧再用 Nginx 限流与内核参数加固抵御 CC 与协议型攻击,并预留带宽冗余和一键切换预案。

引言:DDoS 不是"能不能防住",而是"在哪一层防"

DDoS(Distributed Denial of Service,分布式拒绝服务)攻击的本质是用远超你承受能力的流量淹没带宽、连接表或应用处理能力。它之所以难防,根本原因是攻击资源是分布式的、成本极低,而你的带宽和处理能力是有限且昂贵的。一台 4 核 8 G、10 Mbps 带宽的云服务器,面对几十 Gbps 的流量洪流,无论内核参数调得多漂亮都无济于事——因为流量在到达你的机器之前,机房入口的带宽就已经被打满了。

所以防 DDoS 的第一性原理是:必须在流量到达源站之前化解它。 这意味着防护能力的主体不在你的服务器上,而在上游——CDN 边缘节点、云厂商清洗中心、运营商骨干网。你自己在源站能做的,是兜住"漏过来的那部分",以及防住 CC 这类不需要大带宽的应用层攻击。

本文的重心是平时怎么建设防护体系:攻击分类、防护指标、CDN 隐藏源站、高防选型、源站限速与内核加固、架构层纵深防御。如果你正在被攻击、需要"此刻怎么止血和溯源",请看本站《服务器被DDoS攻击怎么防御》一文。命令以 Ubuntu 24.04 LTS、Rocky Linux 9 与 Nginx 1.26 为例(截至 2026 年)。

一、DDoS 攻击分类表:三类攻击,三种防御位置

DDoS 不是一个单一攻击,而是三类机制完全不同的攻击。防错了位置,投入再多也白搭。

类型典型手法消耗的资源流量规模(截至 2026 年常见值)主要防御位置
流量型(Volumetric)UDP Flood、NTP/DNS 反射放大、ACK Flood机房入口带宽10 Gbps ~ 数 Tbps运营商清洗、云高防、CDN
协议型(Protocol / State-exhaustion)SYN Flood、SYN-ACK Flood、分片 Flood连接表、防火墙/负载均衡会话数1~50 Gbps,包速率可达数 Mpps云高防、SYN Cookie、内核参数
应用层(Application Layer / CC)HTTP Flood、慢速连接(Slowloris)、高频 API 调用应用 CPU、数据库、连接池带宽往往不高(几十 Mbps),QPS 可达数万CDN/WAF、Nginx 限流、验证码、业务侧风控

三者的关键区别在于"带宽不高也可能是致命攻击"。很多运维看到带宽只用了 30 Mbps 就判断"没被 DDoS",实际上 CC 攻击正以每秒两万次的请求把 PHP-FPM 进程池和数据库连接打满,网站照样打不开。判断 CC 的指标是 QPS 与连接数,不是带宽。

另一个必须知道的数字:截至 2026 年,公开的 DDoS 峰值记录已超过 5 Tbps 量级,攻击时长则呈"短促化"趋势——超过六成的攻击在 10 分钟内结束。这意味着靠人工发现告警再手动切换高防,往往来不及。自动化的流量监测与自动切换能力,比"买更大的带宽"更重要。

二、防护能力要看哪些硬指标

选型或评估防护方案时,不要只看"能防多少 G"这一个数字。完整的指标清单如下:

指标含义中小企业建议值
防护带宽清洗中心能吸收的最大攻击流量单 IP 至少 100 Gbps,业务重要则 300 Gbps+
清洗能力能否区分流量型 / 协议型 / CC,误杀率多少必须支持 CC 独立识别,误杀率 < 1%
CC 防护单 IP QPS 限制、JS 挑战、验证码、URI 级限速支持按 URI、User-Agent、Cookie 限流
隐藏源站是否提供真实 IP 隐藏与回源 IP 白名单必须支持,这是最关键的一项
回源策略回源是否走私有线路、是否可限定回源 IP必须支持回源白名单
线路质量BGP 多线 / 单线、被攻击时是否牵连正常用户至少双线 BGP,有被攻击时的可用性承诺
弹性能力超防护上限时是否自动降级/黑洞,有无通知明确"超出后如何处理",避免整机黑洞
响应时延攻击开始到清洗生效的时间自动检测 < 1 分钟,人工工单 < 15 分钟

其中"超出防护上限后的处理"最容易被忽略。多数厂商在攻击超过防护峰值时会触发黑洞路由(Blackhole / 流量牵引丢弃)——你的 IP 会被整个互联网丢弃,业务彻底不可达,且通常要等 30 分钟到数小时才解除。签合同前务必问清阈值与解除时长。

三、第一道防线:用 CDN 隐藏源站 IP(最重要的一条)

结论:如果只能做一件事,那就隐藏源站 IP。 只要攻击者不知道你的真实 IP,所有针对源站的流量型、协议型攻击都无法发起;他们只能打 CDN 的边缘节点,而那正是 CDN 厂商用海量带宽和 Anycast 架构专门准备的部分。

标准做法是三段式:

  1. 源站 IP 绝不对外暴露,域名解析指向 CDN 提供的 CNAME。
  2. 源站防火墙只放行 CDN 回源 IP 段,其余来源一律丢弃。这样即便 IP 泄露,直接打源站的流量也会被丢弃。
  3. 定期核查 IP 是否泄露(DNS 历史记录、邮件头、SSL 证书透明日志、子域名、图片 EXIF 等)。
bash
# 源站只放行 CDN 回源 IP(iptables 示例,IP 段换成厂商公布的实际段)
iptables -I INPUT -p tcp --dport 80  -s 203.0.113.0/24 -j ACCEPT
iptables -I INPUT -p tcp --dport 443 -s 203.0.113.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 80  -j DROP
iptables -A INPUT -p tcp --dport 443 -j DROP

# firewalld 写法(Rocky Linux 9 / CentOS Stream 9)
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" port port="443" protocol="tcp" accept'
firewall-cmd --permanent --remove-service=http
firewall-cmd --permanent --remove-service=https
firewall-cmd --reload

# 验证:从非 CDN 节点直连源站应超时
curl -sv -m 5 --resolve www.example.com:443:你的源站IP https://www.example.com/

源站 IP 泄露的常见途径表

这是实战中最容易"功亏一篑"的地方——你配好了 CDN,却因为一个细节把 IP 送了出去。

泄露途径具体表现修复方式
DNS 历史记录子域名曾用 A 记录直接指向源站,被 DNS 历史库收录改 CDN 后同时更换源站 IP;用 SecurityTrails/DNSDB 自查
邮件头(最常见)网站发出的注册/通知邮件,Received 头含源站 IP邮件走第三方 SMTP/API,禁止本机直接发信
SSL 证书透明日志证书签发记录暴露了 IP 对应的域名定期查 crt.sh,撤销并重新签发证书
子域名与主站分离api.、test.、admin. 等未走 CDN全部子域名接入 CDN,或独立部署并限制来源
程序直连 IP客户端、App、API 回调里硬编码了源站 IP全部改为域名,禁止硬编码
备份/探针/监控phpinfo、探针文件、zabbix-agent 被动探测暴露 IP删除探针,监控走内网
未接管的历史解析被攻击后临时切回 A 记录直连源站,忘了切回来切换操作纳入变更记录,事后复查

关键动作:一旦确认 IP 已泄露,唯一可靠的修复是更换源站 IP(或换一台机器),仅靠防火墙封堵只是权宜之计。

四、高防 IP 与高防服务器怎么选

CDN 解决了"隐藏源站",但当攻击规模超过 CDN 的边缘承载,或者你的业务不适合走 CDN(如实时游戏、非 HTTP 协议的 TCP 业务),就需要高防产品。三种形态的区别:

形态原理适用协议优点局限
高防 IP(防护包)把业务 IP 换成高防 IP,流量先到清洗中心再回源TCP/UDP/HTTP 全协议可挂载任意源站、切换灵活、支持非 Web 业务需换 IP,回源要配白名单
高防服务器机房自带清洗能力,服务器本身在高防机房全协议上线即用、带宽与防护一体迁移成本高、扩容不灵活
CDN 高防(边缘防护)边缘节点吸收 + WAF + CC 防护HTTP/HTTPS 为主隐藏源站、加速与防护兼得、成本最低非 HTTP 业务不适用

选型建议(截至 2026 年,价格以官网实时报价为准):

  • 纯 Web 业务:优先 CDN + WAF,成本最低且顺带隐藏源站。
  • Web 业务但经常被 CC:CDN + 高防 IP 组合,把 CC 交给高防的人机校验。
  • 游戏/音视频/私有 TCP 协议:只能选高防 IP 或高防服务器,CDN 帮不上忙。
  • 合规要求数据不出境/不出省:确认清洗节点的地理位置,选择境内清洗的厂商。

配置高防时的两条硬性要求:回源 IP 白名单必须配(否则别人绕过高防直打源站),源站禁止对外暴露任何未走高防的入口(包括 IPv6、备用端口、SSH 之外的管理口)。

五、源站自身加固:Nginx 限流与连接限制

上游拦截之外,源站必须能兜住漏过来的 CC 与小规模攻击。Nginx 1.26 提供两个核心模块:limit_req(请求速率)与 limit_conn(并发连接)。

nginx
# /etc/nginx/nginx.conf —— http 段中定义限流区域
http {
    # 按客户端 IP 限请求速率:rate=10r/s,突发放行 20 个
    limit_req_zone $binary_remote_addr zone=req_perip:10m rate=10r/s;
    # 按客户端 IP 限并发连接数
    limit_conn_zone $binary_remote_addr zone=conn_perip:10m;
    # 按 Server 维度限总并发,防止单机连接表打满
    limit_conn_zone $server_name zone=conn_perserver:10m;
    # 日志级别设为 warn,被限流的请求会记录 "limiting requests"
    limit_req_log_level warn;
    limit_conn_log_level warn;
    limit_req_status 429;
    limit_conn_status 429;

    server {
        listen 443 ssl;
        server_name www.example.com;

        location / {
            limit_req zone=req_perip burst=20 nodelay;
            limit_conn conn_perip 20;
            limit_conn conn_perserver 2000;
            proxy_pass http://backend;
        }

        # 静态资源放宽(图片/css/js 请求量大但成本低)
        location ~* \.(jpg|jpeg|png|gif|css|js|woff2)$ {
            limit_req zone=req_perip burst=50 nodelay;
            expires 7d;
            root /data/www;
        }

        # 登录、短信、支付等敏感接口单独严格限流
        location ~ ^/(api/login|api/sms|api/pay) {
            limit_req zone=req_perip burst=5 nodelay;
            limit_conn conn_perip 5;
            proxy_pass http://backend;
        }
    }
}

参数要点:

  • rate=10r/s 是令牌桶的平均速率,burst=20 是允许的突发量,nodelay 表示突发请求立即处理(不加 nodelay 则会排队延迟)。
  • zone=req_perip:10m 中 10 MB 内存约可记录 16 万个 IP($binary_remote_addr 每个键约占 64 字节),内存不足会返回 503。
  • 限流阈值必须基于真实业务基线设定:先用 awk '{print $1}' access.log | sort | uniq -c | sort -rn | head 统计单 IP 最高请求数,取日常峰值的 1.5~2 倍作为 rate,避免误杀正常用户(尤其是移动端 NAT 出口会共享 IP)。
  • 被限流返回 429 而不是 503,便于在监控中区分"限流"与"后端故障"。

六、内核与防火墙层:SYN Cookie 与限速

协议型攻击(SYN Flood)消耗的是连接表,靠 SYN Cookie 机制可以在半连接队列打满时仍能正常建连。

bash
# /etc/sysctl.d/99-ddos.conf —— 协议型攻击加固
net.ipv4.tcp_syncookies = 1              # 半连接队列溢出时启用 SYN Cookie(多数发行版已默认开启)
net.ipv4.tcp_max_syn_backlog = 8192      # 半连接队列长度,默认 256 太小
net.core.somaxconn = 65535               # 全连接队列上限,需配合应用 listen backlog
net.ipv4.tcp_synack_retries = 2          # SYN+ACK 重试次数,默认 5 太浪费(默认约 180 秒)
net.ipv4.tcp_syn_retries = 3
net.ipv4.tcp_abort_on_overflow = 0       # 队列满时发 RST(1)还是丢弃(0),建议 0
net.ipv4.tcp_fin_timeout = 15            # FIN_WAIT_2 超时,默认 60 秒
net.ipv4.tcp_tw_reuse = 1                # 允许复用 TIME_WAIT 套接字(仅对客户端生效)
net.ipv4.ip_local_port_range = 1024 65535
net.netfilter.nf_conntrack_max = 1048576 # 连接跟踪表上限(注意内存占用,每条约 300 字节)
net.netfilter.nf_conntrack_tcp_timeout_established = 600
net.ipv4.icmp_echo_ignore_broadcasts = 1 # 防 Smurf 放大
net.ipv4.icmp_ignore_bogus_error_responses = 1

# 应用生效
sysctl -p /etc/sysctl.d/99-ddos.conf
# 验证
sysctl net.ipv4.tcp_syncookies net.core.somaxconn
cat /proc/sys/net/ipv4/tcp_syncookies

防火墙层限速(针对尚未被打满的小规模攻击,且必须有 nf_conntrack 支持):

bash
# 单 IP 每秒最多 20 个新建 SYN,突发 50
iptables -N ANTI_DDOS 2>/dev/null
iptables -A INPUT -p tcp --syn -j ANTI_DDOS
iptables -A ANTI_DDOS -p tcp --syn -m hashlimit \
  --hashlimit-name syn_rate --hashlimit-mode srcip \
  --hashlimit 20/second --hashlimit-burst 50 -j RETURN
iptables -A ANTI_DDOS -j DROP

# 单 IP 并发连接数上限(防 CC 建连)
iptables -A INPUT -p tcp --syn --dport 443 -m connlimit --connlimit-above 30 -j REJECT

# 屏蔽非常见_flags 组合(防 Xmas/NULL 扫描型 Flood)
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL  -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP

# 限制 UDP 流量(DNS 等业务需先放行必要端口)
iptables -A INPUT -p udp --dport 53 -m hashlimit \
  --hashlimit-name udp_dns --hashlimit-mode srcip --hashlimit 50/second -j ACCEPT
iptables -A INPUT -p udp -m limit --limit 100/second -j ACCEPT
iptables -A INPUT -p udp -j DROP

重要提醒:本机防火墙限速只能防小规模攻击。 当入向流量已把机房带宽打满时,数据包根本到不了你的 iptables,规则写得再好也无用。这就是为什么"上游清洗"不可替代。另外 nf_conntrack_max 调大会显著增加内存占用(100 万条约 300 MB),小内存机器不要盲目调高。