小微站点做防护,最大的痛点是“资源错配”。花几千块买高防IP,带宽还没攻击流量大;用CDN硬抗,CC攻击直接把回源带宽和服务器CPU打满,欠费停机是常态。真正落地的极简方案,核心思路不是硬抗,而是“分层丢弃”和“端口复用”。把宝贵的服务器资源留给真实用户,把攻击流量挡在最外层,甚至利用攻击者自己的逻辑缺陷反制。
认清小微站点的防护边界:别想扛,只想丢一台2核4G的轻量云服务器,带宽5Mbps,这种配置下谈抗DDoS就是天方夜谭。一个SYN Flood小包就能把带宽占满,一个简单的HTTP Flood就能让数据库连接池爆掉。所以极简方案的第一原则:不在本地做任何复杂计算。所有进入服务器的流量,必须是经过“验证”的真实用户流量。验证失败的流量,直接丢弃,连TCP连接都不要建立完整。这意味着我们需要在流量入口处做“首包丢弃”和“行为验证”,而不是等请求到了Nginx或者Apache层面再去处理。很多站长有个误区,以为装了ModSecurity或者配置了limit_req就能防CC,实际上这些模块工作时,TCP三次握手已经完成,HTTP请求已经解析,系统资源已经消耗,防护效果大打折扣。
利用XDP/BPF实现网卡驱动层丢包现代Linux内核提供的XDP(eXpress Data Path)技术,允许在网卡驱动收到数据包的第一时间,就在内核旁路进行过滤。这比iptables效率高出一个数量级,CPU占用极低。对于小微站点,可以编写一个简单的BPF程序,挂载到网卡上,实现基于IP信誉的快速丢弃。如果你不想自己写C语言代码,可以直接用现成的工具,比如xdp-tools套件里的xdp-filter。一条命令就能开启基础防护:
# 加载xdp程序到eth0网卡,开启基础防欺骗和广播过滤 xdp-filter load eth0 -f udp,tcp,icmp -p deny
更进一步的,可以结合ipset动态黑名单。当检测到某个IP在短时间内发送大量SYN包或者空载荷的ACK包,直接将其加入黑名单,由XDP程序在网卡层丢弃。这种处理方式下,攻击流量根本不会进入内核协议栈,5Mbps的小带宽也能处理几十万pps的攻击包。关键是CPU占用几乎为零,因为数据包在网卡队列里就被丢弃了,不会产生中断开销。对于UDP反射放大攻击,XDP层的过滤效果尤为明显,直接判断载荷长度和源端口特征,命中规则立即丢弃。
TCP层极简防护:SYN Cookie与tcp_backlog调优对于必须完成TCP握手的合法请求,内核参数的调整至关重要。很多默认配置是为高带宽服务器设计的,小微站点必须修改。首先是开启SYN Cookie,这是防御SYN Flood的最后一道内核防线:
sysctl -w net.ipv4.tcp_syncookies=1
但仅仅开启还不够,需要配合半连接队列和全连接队列的调整。重点参数是tcp_max_syn_backlog和somaxconn。小微站点不需要很大的队列,因为真实用户并发量很低。把tcp_max_syn_backlog设小,比如128,可以快速填满攻击者的SYN队列,触发SYN Cookie机制,同时避免内存被大量半连接占用。全连接队列somaxconn同样调小,配合应用层的backlog参数,让完成握手的连接尽快被accept取走,否则积压的连接同样消耗内存。还有一个关键参数tcp_abort_on_overflow,建议设为1。当全连接队列满时,内核直接发送RST包,而不是丢弃请求让客户端重试。这能防止攻击者利用重试机制持续占用队列资源。
应用层反代:Nginx前置的“假握手”策略很多CC攻击直接针对HTTP层面,发起大量看似正常的GET或POST请求。这类请求已经完成TCP握手,内核层无法过滤。此时需要在Nginx层面做“首请求验证”。原理很简单:对于没有携带特定Cookie的请求,不转发到后端,而是返回一个302重定向或者一段需要执行JavaScript的页面。这个思路类似Cloudflare的Under Attack模式,但我们可以用几行Nginx配置自己实现轻量版。核心是利用Nginx的map模块和if判断,检查请求中是否存在一个自定义的验证Cookie。如果不存在,返回一个302到验证页面,同时设置一个临时Cookie。验证页面可以是一个静态HTML,里面包含一段极简的JS,执行后设置Cookie并刷新页面。真实浏览器会自动处理这个过程,而攻击脚本通常不会解析JS,也就无法获得有效Cookie,后续请求直接被Nginx拦截在反向代理层,根本到不了后端应用。
# 在http块中定义map
map $cookie_verified $need_check {
default 1;
"true" 0;
}
# 在server块中使用
server {
listen 80;
server_name example.com;
if ($need_check = 1) {
return 302 /verify.html;
}
location /verify.html {
add_header Set-Cookie "verified=true; Path=/; Max-Age=3600";
return 200 "";
}
location / {
proxy_pass http://backend;
}
}
这个方案的妙处在于,验证逻辑完全在Nginx层面完成,不消耗后端资源。而且302重定向和静态HTML的传输量极小,即使攻击者持续发起请求,消耗的也只是Nginx的一点CPU和出口带宽,而Nginx处理静态返回的能力极强,单核就能扛住数万QPS。攻击者如果只是简单的HTTP库,不会处理Cookie和重定向,攻击流量就被隔离在这一步。更进一步,可以把验证Cookie的值做成动态的,比如用HMAC签名的时间戳,定期轮换,增加攻击者逆向成本。
端口敲门与单包授权:隐藏真实端口对于SSH、数据库管理等敏感服务,根本不应该暴露在公网上。但小微站点往往没有专门的VPN设备或者跳板机。此时可以用端口敲门(Port Knocking)技术,配合单包授权(SPA),实现“端口隐身”。传统端口敲门是依次访问几个指定端口,服务器检测到正确序列后,临时开放22端口。但这种方式容易被重放攻击,而且敲门包本身可能被嗅探。更安全的是单包授权,比如使用fwknop这个工具。客户端发送一个经过GPG签名的UDP包,服务器端fwknopd守护进程在网卡上捕获这个包,验证签名和内容后,动态添加iptables规则,只对客户端IP开放指定端口,默认30秒后规则自动删除。这样在攻击者扫描时,22端口是完全关闭的,根本不存在攻击面。
# 服务端安装并配置fwknopd apt install fwknop-server # 配置访问策略,定义允许的密钥和开放端口 # 客户端敲门命令 fwknop -A tcp/22 -a 客户端公网IP -D 服务器IP --key-gen --use-hmac --save-rc-stanza
这个方案把防护从“被动响应”变成了“主动隐藏”。攻击者连端口都找不到,自然无法发起针对性的DDoS或者暴力破解。对于小微站点,这是成本最低、效果最好的管理端口防护手段,完全不需要额外购买高防服务。
利用Cloudflare免费套餐的“隐身”模式这里不谈Cloudflare的具体品牌,只说这种反向代理CDN的通用防护思路。将域名的NS记录指向支持DDoS防护的CDN服务商,开启代理模式,源站IP就被隐藏起来。攻击者只能看到CDN节点的IP,所有攻击流量都由CDN的庞大网络承担。但这里有个关键细节:源站必须配置防火墙,只允许CDN的回源IP地址访问80和443端口,其他所有IP的请求直接丢弃。否则攻击者通过DNS历史记录或者全网扫描找到源站真实IP,CDN防护就形同虚设。配置方法是在iptables里添加白名单规则,只放行CDN官方公布的回源IP段,其余一律DROP。同时,源站Nginx也要配置默认虚拟主机,对于非本站域名的请求直接返回444状态码(Nginx特有,直接关闭连接不返回任何内容),防止攻击者通过IP直接访问。
日志与动态黑名单的闭环上述所有手段部署后,还需要一个简单的闭环反馈机制。通过分析Nginx访问日志,实时提取高频IP、异常User-Agent、固定URL反复请求等特征,自动加入iptables或XDP黑名单。一个简单的shell脚本配合crontab就能实现:每分钟分析一次日志,用awk统计请求次数,超过阈值的IP直接调用ipset加入黑名单。ipset配合iptables的match-set模块,匹配效率远高于逐条iptables规则。黑名单可以设置过期时间,比如600秒后自动解封,避免误伤动态IP的真实用户。
# 创建ipset黑名单,超时600秒
ipset create blacklist hash:ip timeout 600
# iptables规则引用ipset
iptables -I INPUT -m set --match-set blacklist src -j DROP
# 定时脚本示例,每分钟执行
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | while read count ip; do
if [ $count -gt 100 ]; then
ipset add blacklist $ip
fi
done
这套组合方案的核心逻辑是:网卡驱动层用XDP丢弃大流量DDoS包,内核层用SYN Cookie和队列调优处理TCP洪水,应用层用Nginx Cookie验证拦截HTTP CC攻击,管理端口用单包授权隐藏,外部用CDN隐藏源站,最后用日志分析形成动态黑名单闭环。每一层都只处理自己最擅长的那部分攻击流量,不越界、不消耗多余资源。对于一台2核4G的小服务器,部署这套方案后,完全有能力在5Mbps带宽下保持正常服务,而攻击者面对的将是一个层层过滤、几乎无法触及后端的高效防护体系。
