DDoS攻击早已不是单纯比拼带宽的洪水,如今应用层的慢速攻击、针对HTTPS握手阶段的SSL洪水,才是让运维人员半夜惊醒的真正噩梦。Debian作为服务器操作系统的常青树,其稳定性和包管理机制为构建防御体系提供了绝佳基座。问题的核心在于,仅靠Nginx自身的请求限制远远不够,必须让Nginx与系统防火墙netfilter(通过iptables或nftables交互)形成联动,在流量到达Web应用之前就完成第一轮清洗。下面直接进入配置实战,不绕弯子。

内核参数调优:打好地基

在安装任何工具前,必须调整Debian的内核网络参数,否则再好的应用层防御也会被SYN队列塞满而瘫痪。编辑/etc/sysctl.conf文件,加入以下关键参数:

# 启用SYN Cookie,防止SYN队列满
net.ipv4.tcp_syncookies = 1

# 缩短SYN_RECV状态的重试次数,默认5次,改为2次
net.ipv4.tcp_synack_retries = 2

# 减少TIME_WAIT状态的连接,加快回收
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 10

# 增大半连接队列长度,配合syncookies使用
net.ipv4.tcp_max_syn_backlog = 8192

# 忽略所有ICMP Echo请求,防止Ping洪水
net.ipv4.icmp_echo_ignore_all = 1

# 禁止源路由,防止IP欺骗
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0

执行sysctl -p让配置生效。这些参数直接决定了服务器在遭受SYN Flood攻击时,系统调用层面能撑多久。特别注意tcp_syncookies,它在队列满时会用加密Cookie验证客户端,几乎不消耗内存,是抗SYN洪水性价比最高的内核级方案。

nftables基础防御框架

Debian较新版本默认使用nftables取代了传统的iptables,但语法更简洁,性能也更好。先建立nftables的基础规则集,创建一个专门用于防御的表。新建/etc/nftables.conf,写入以下规则:

#!/usr/sbin/nft -f

flush ruleset

table inet filter {
    # 定义动态黑名单集合,超时自动清除
    set blacklist {
        type ipv4_addr
        timeout 1h
        flags dynamic
    }

    # 定义白名单集合,放行可信IP
    set whitelist {
        type ipv4_addr
        elements = { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 }
    }

    chain input {
        type filter hook input priority 0; policy drop;

        # 允许回环接口
        iif lo accept

        # 允许已建立和相关连接
        ct state established,related accept

        # 白名单直接放行
        ip saddr @whitelist accept

        # 黑名单直接丢弃
        ip saddr @blacklist drop

        # 限制新连接速率,每秒最多10个新连接,突发20个
        ct state new tcp dport { 80, 443 } meter ratelimit { ip saddr timeout 30s limit rate over 10/second burst 20 packets } add @blacklist { ip saddr } drop

        # 允许HTTP和HTTPS
        tcp dport { 80, 443 } accept
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}

这套规则的核心在于利用nftables的meter机制做速率限制。当某个IP的新建连接速率超过每秒10个,立即被丢进blacklist集合,并自动封禁30秒。这比单纯限制并发连接更有效,因为DDoS往往就是靠新建连接速率打垮服务器。执行nft -f /etc/nftables.conf加载规则,并设置开机自启systemctl enable nftables。

Nginx动态限流与反向代理加固

防火墙处理了网络层的异常流量,但应用层的请求仍需要Nginx来精细控制。在Nginx的http块中配置限流区域:

http {
    # 定义请求频率限制区域,按客户端IP,每秒10个请求
    limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;

    # 定义连接数限制区域,每个IP最多20个并发连接
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

    # 定义慢速攻击防护
    client_body_timeout 10s;
    client_header_timeout 10s;
    send_timeout 10s;

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

        # 请求频率限制,突发20个,超出返回503
        limit_req zone=req_limit burst=20 nodelay;
        limit_conn conn_limit 20;

        # 限制请求体大小,防止POST洪水
        client_max_body_size 10m;

        # 关闭不需要的HTTP方法
        if ($request_method !~ ^(GET|HEAD|POST)$ ) {
            return 444;
        }

        # 针对特定URL的精细化限流
        location /api/ {
            limit_req zone=req_limit burst=5 nodelay;
            proxy_pass http://backend;
        }

        # 静态资源缓存,减少后端压力
        location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
            expires 1y;
            add_header Cache-Control "public, immutable";
        }
    }
}

这里的limit_req_zone和limit_conn_zone是Nginx防御DDoS的核心指令。burst参数允许短时突发流量,避免误伤正常用户的批量请求,nodelay则让超出burst的请求立即返回503,不排队等待。对于登录接口或搜索接口等高风险路径,可以单独设置更低的速率限制,形成分层防御。

SSL洪水防御与TLS优化

针对HTTPS的SSL/TLS握手攻击,攻击者会发送大量无效的ClientHello报文消耗服务器CPU。Nginx需要配合SSL参数进行加固:

server {
    listen 443 ssl http2;

    # 启用SSL会话缓存,减少重复握手
    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    # 仅使用TLS 1.2和1.3,禁用旧版本
    ssl_protocols TLSv1.2 TLSv1.3;

    # 使用ECDHE密钥交换,性能更好
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers on;

    # OCSP Stapling,减少客户端验证延迟
    ssl_stapling on;
    ssl_stapling_verify on;
}

这些配置让合法用户的SSL会话可以复用,攻击者则必须完成完整的握手流程。结合nftables对443端口的新连接速率限制,SSL洪水攻击的威力会被大幅削弱。实际测试中,开启ssl_session_cache后,相同硬件能承受的HTTPS请求量提升约40%。

日志分析与自动联动封禁

静态规则终究有局限性,真正的防御体系需要根据实时日志动态调整。使用fail2ban这个Debian仓库自带的工具,监控Nginx日志,自动调用nftables封禁恶意IP。安装fail2ban后,创建/etc/fail2ban/jail.local:

[nginx-req-limit]
enabled = true
port = http,https
filter = nginx-req-limit
logpath = /var/log/nginx/access.log
maxretry = 10
findtime = 60
bantime = 3600
action = nftables-allports[name=nginx-req-limit]

[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 60
bantime = 7200
action = nftables-allports[name=nginx-botsearch]

对应的过滤器文件/etc/fail2ban/filter.d/nginx-req-limit.conf内容:

[Definition]
failregex = ^ -.* "(GET|POST).*" 503
ignoreregex =

这个过滤器匹配Nginx返回503状态码的请求,也就是被limit_req限流拒绝的请求。当某个IP在60秒内触发10次503,fail2ban就会通过nftables将其封禁1小时。这种Nginx与防火墙的闭环联动,实现了从检测到阻断的自动化,不需要人工干预。

GeoIP地域限制与业务场景结合

如果业务只面向特定地区,使用GeoIP模块在Nginx层面直接拒绝境外流量,能过滤掉90%的僵尸网络攻击。Debian下安装libnginx-mod-http-geoip2,然后在Nginx中配置:

http {
    geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
        $geoip2_country_code country iso_code;
    }

    map $geoip2_country_code $allowed_country {
        default no;
        CN yes;
        HK yes;
        MO yes;
        TW yes;
    }

    server {
        if ($allowed_country = no) {
            return 444;
        }
    }
}

注意GeoIP数据库需要定期更新,Debian可以通过geoipupdate工具自动维护。这种方式虽然简单粗暴,但对于中文网站或本地化服务来说,是性价比极高的防御手段。结合前面的限流配置,境外IP连限流阶段都进不了,直接在连接建立时就被断开。

CDN回源保护与真实IP获取

如果前端使用了CDN,Nginx默认获取到的是CDN节点的IP,这会导致限流和封禁全部失效。必须配置real_ip模块,从HTTP头中提取真实客户端IP:

http {
    # 信任的CDN IP段,以Cloudflare为例
    set_real_ip_from 173.245.48.0/20;
    set_real_ip_from 103.21.244.0/22;
    set_real_ip_from 103.22.200.0/22;
    # 更多CDN IP段需要根据实际使用的服务商添加

    real_ip_header CF-Connecting-IP;
    # 或使用X-Forwarded-For,但需要确保只信任CDN的IP
    # real_ip_header X-Forwarded-For;
    # real_ip_recursive on;
}

配置后,Nginx的limit_req_zone和limit_conn_zone就能基于真实客户端IP工作。同时,在nftables层面,应该只允许CDN的IP段访问80和443端口,屏蔽所有其他来源的直接访问,防止攻击者绕过CDN直接攻击源站。在nftables的input链中添加:

# 定义CDN IP集合
set cdn_ips {
    type ipv4_addr
    flags interval
    elements = { 173.245.48.0/20, 103.21.244.0/22, 103.22.200.0/22 }
}

# 对HTTP/HTTPS端口,只允许CDN IP
tcp dport { 80, 443 } ip saddr @cdn_ips accept
tcp dport { 80, 443 } drop

这种源站隐藏策略,让攻击者根本无法直接接触到真实服务器,所有流量都必须经过CDN的清洗节点,防御效率成倍提升。

综合压测与持续监控

配置完成后,不能凭感觉判断防御效果。使用wrk或ab工具模拟并发请求,观察Nginx的访问日志和nftables的计数器。执行nft list ruleset查看各条规则匹配的报文数量,确认限流和封禁规则确实在生效。同时,部署Prometheus和Grafana监控Nginx的连接状态、请求速率和503错误比例,设置告警阈值。当攻击发生时,能第一时间从仪表盘看到流量异常,并根据数据调整burst值或速率限制参数。防御DDoS不是一次性配置,而是持续对抗的过程,攻击者的手法在进化,防御策略也必须随之迭代。