DDoS攻击早已不是流量大不大的问题,而是攻击者能不能用极低成本让业务瞬间不可用的问题。现在很多攻击资源已经工具化、服务化,攻击者花几十块钱就能发起一次足以压垮中小型网站的攻击。真正需要关注的不是“会不会被打”,而是“被打的时候业务能不能继续跑”。

先从最容易被忽视的一点说起:很多网站瘫痪并不是因为攻击流量真的有多大,而是因为入口处没有做任何资源隔离。比如一个电商网站,搜索接口、登录接口、下单接口、静态资源全部走同一个域名、同一套服务器集群,攻击者只需要针对搜索接口打每秒几万次请求,整站数据库连接池就会被耗尽,首页都打不开。所以第一件事是把静态资源和动态接口分离,把高消耗接口和普通接口做路径级限流,而不是等攻击来了再想怎么办。

先搞清楚攻击类型,才能谈防护

DDoS不是单一攻击,常见的有三类:流量型、协议型、应用层型。流量型就是纯粹用带宽淹没你,比如UDP flood、ICMP flood,这种攻击的特点是数据包大、来源广,目标是把你机房入口带宽占满。协议型攻击主要利用TCP握手缺陷,比如SYN flood,服务器收到大量伪造源地址的SYN包,每个都要分配半连接资源,很快内存就满了。应用层型最隐蔽,比如HTTP flood、慢速攻击,每个请求看起来都正常,但频率极高或者连接拖得极长,普通防火墙根本识别不出来。

如果你连自己主要面临哪类攻击都不清楚,买再贵的防护设备也是浪费。建议先用流量分析工具把正常业务峰值摸清楚,比如平时每秒请求量是多少、单个IP平均请求频率是多少、哪些接口最耗资源。有了基线,才能设置合理的阈值,不然误杀正常用户和漏放攻击流量都是常态。

网络层防护:别把希望全放在一台设备上

网络层防护的核心思路是分层过滤。第一层是运营商级别的清洗,适合大流量攻击,但成本高、响应慢,适合预算充足的企业。第二层是机房入口的硬件防火墙或高性能软件网关,比如用DPDK技术做的抗D设备,能扛住几十Gbps的流量。第三层是服务器本地的iptables或nftables规则,只放行必要端口,其他全部丢弃。

这里有一个非常实用的配置思路:在服务器上开启SYN Cookie,能有效缓解SYN flood。Linux系统下可以通过sysctl调整:

net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_max_tw_buckets = 2000000
net.ipv4.tcp_tw_reuse = 1

这几行配置的意义在于:开启SYN Cookie后,服务器不再为每个SYN包分配完整的半连接资源,而是用算法生成一个Cookie,只有完成三次握手的连接才真正占用资源。同时调低SYN+ACK重试次数,减少半连接队列的停留时间。很多中小服务器被打挂,就是因为这些默认参数太保守,攻击者用很小的流量就能占满半连接队列。

另外,UDP flood的防护思路完全不同。如果业务不需要UDP,直接在入口防火墙把UDP全部丢弃,这是最干净的。如果必须用UDP,比如做DNS或游戏加速,那就要做限速和源验证,不能无脑接收。很多反射放大攻击就是利用开放的UDP服务,比如DNS、NTP、Memcached,攻击者伪造受害者IP发小请求,服务器回大包,放大倍数能到几十倍甚至上百倍。

应用层防护:最容易被突破的一层

应用层攻击之所以难防,是因为它走的是正常HTTP协议,请求内容看起来完全合法。攻击者可以用真实浏览器内核、真实IP池、甚至模拟正常用户行为,传统基于IP频率的限制很容易误伤。比如一个公司出口IP后面有几百个员工同时访问网站,如果按IP限频,正常用户直接被封。

更有效的做法是结合多种维度做行为分析。比如:同一个IP在短时间内请求的URL分布是否异常、请求间隔是否过于均匀、是否总是命中缓存穿透的路径、User-Agent是否与正常浏览器指纹匹配、是否携带正确的Cookie和Referer。把这些信号组合起来,比单纯看请求频率准确得多。

对于关键接口,建议启用验证码或JavaScript挑战。攻击者用脚本发请求,通常不会执行JS,也不会解析验证码。给登录、搜索、下单这些高消耗接口加上一层JS跳转或滑动验证,能挡住大部分自动化攻击。但要注意,验证码不能全站加,否则正常用户体验极差,搜索引擎爬虫也会被拦。

还有一个常被忽略的点:API接口的鉴权和限流。很多网站的前后端分离架构里,API接口直接暴露在公网,攻击者不需要打开页面,直接对API发请求就行。如果API没有做严格的鉴权和频率控制,攻击成本极低。建议对每个API Key或用户Token做独立限流,而不是只按IP限流。攻击者可以换IP,但换一个有效的用户身份成本高得多。

架构层面的抗D设计

单点永远是最脆弱的。无论你买了多贵的抗D设备,只要所有流量都汇聚到一个节点,攻击者就有办法打穿。真正抗打的架构一定是分布式的。把业务部署在多个可用区、多个机房,用智能DNS或Anycast把流量分散开。攻击者要同时打垮所有节点,成本会成倍增加。

静态资源尽量走CDN,把图片、CSS、JS这些不常变的内容缓存到边缘节点。这样即使源站被打,CDN边缘节点还能继续提供静态内容,用户至少能看到页面框架,不至于完全白屏。CDN本身也有一定的抗D能力,很多CDN服务商提供免费的DDoS防护,能扛住常见的小规模攻击。

数据库层面也要做读写分离和连接池隔离。攻击者打应用层时,最容易耗尽的就是数据库连接。把读请求和写请求分开,给不同业务分配独立的连接池,避免一个接口被打导致全库不可用。对于热点数据,尽量用Redis或Memcached做缓存,减少数据库压力。缓存穿透是攻击者常用的手段,故意请求不存在的Key,让缓存失效,所有请求都打到数据库。解决办法是对不存在的Key也缓存一个空值,或者用布隆过滤器拦截明显不存在的请求。

监控和应急响应:不能等挂了才知道

很多网站被打了半天,运维还在排查为什么CPU飙高。没有实时监控和告警,等发现的时候业务已经中断很久了。至少要监控这几个指标:入口带宽、每秒请求量、连接数、半连接队列长度、数据库连接数、响应时间。设置分级告警,比如带宽超过正常峰值1.5倍就发通知,超过2倍就自动触发限流或切换高防IP。

应急响应流程要提前写好,不能临时想。比如:第一步确认攻击类型和规模,第二步切换高防线路或启用备用节点,第三步在防火墙封禁攻击源特征,第四步通知上下游和用户。每一步谁负责、用什么工具、多长时间内完成,都要明确。演练过和没演练过的团队,在真实攻击面前表现天差地别。

日志也很重要。攻击过后要复盘,找出攻击者的手法和路径,针对性地补上漏洞。很多攻击者会先做小规模试探,找到薄弱点再发起总攻。如果能在试探阶段就发现并阻断,后面的大流量攻击可能根本不会发生。

成本与收益的平衡

不是所有网站都需要上百万的高防方案。一个个人博客和一个在线支付平台,面临的攻击风险和能承受的损失完全不同。关键是算清楚业务中断一小时损失多少钱,再决定投入多少防护成本。对于中小网站,先把基础做好:系统参数调优、入口防火墙规则、应用层限流、CDN加速、数据库连接池隔离,这些成本很低,但能挡住大部分常见攻击。等业务规模大了,再考虑专业的高防IP、运营商清洗、分布式架构。

最后强调一点:DDoS防护不是一次性配置完就万事大吉,攻击手法一直在变,防护策略也要持续更新。定期检查日志、分析流量模式、更新规则库、做压力测试,这些日常工作比买一堆设备更管用。真正安全的网站,不是从来没被打过,而是被打的时候用户几乎无感知。