DoS攻击核心逻辑很简单:想方设法让目标服务器没法正常给真实用户提供服务。它不会窃取数据,也不会控制你的设备,单纯就是堵塞服务入口。入口被堵住,正常用户无法访问,服务也就瘫痪了。
最早的攻击方式,是发送海量垃圾数据包占满服务器带宽。早年常见的UDP Flood,就是持续向目标IP发送大量UDP数据包,服务器处理这些数据包会耗尽上行带宽,正常HTTP请求无法传输进去。这类攻击实现门槛低,但到现在依旧有效,只要攻击流量足够大,任何带宽都存在被打满的可能。
SYN Flood会稍微精巧一点。TCP建立连接需要三次握手流程:客户端发送SYN包,服务器回复SYN-ACK,同时开辟内存保存这条半连接状态,客户端再回复ACK,连接才算建立完成。攻击者只发送第一步的SYN包,后续不再回复ACK,服务器就会持续保留大量半开连接。每一条半连接都会占用系统资源,积累到一定数量,服务器连接表就会占满,新的正常连接请求直接拒绝。这种攻击的特点是单个数据包体积很小,消耗带宽不多,但消耗服务器内存与运算资源。

还有一类攻击针对应用层,不靠大流量硬冲击,而是消耗服务器自身运算资源。比如HTTP Flood,攻击者模拟真实用户,反复请求资源开销大的页面,像是搜索接口、数据库查询页面、大型报表生成页面。每一条请求服务器都要完整执行业务逻辑,占用CPU和数据库连接。正常用户访问频次有限,攻击者通过脚本每秒发起数千次请求,服务器很快负载超限。慢速攻击Slowloris手段更隐蔽,建立连接之后,以极慢速度发送HTTP请求头,服务器判定请求还没有传输完毕,会持续保持连接等待。单条连接占用资源很低,但同时维持数千条这类连接,服务器并发处理能力就会耗尽。
放大攻击是另一种思路。攻击者不直接攻击目标主机,伪造目标IP向第三方服务器发送查询请求。DNS、NTP、Memcached这类服务有个特性,接收一条小请求,就能返回体积很大的响应包。攻击者把请求源IP伪装成目标地址,第三方服务器收到请求后,会把大容量响应包全部发送给目标。攻击者自身只需要很小的上行带宽,就能让目标承受放大几十倍甚至上万倍的流量。2018年Memcached放大攻击爆发的时候,单次攻击峰值流量最高达到1.3 Tbps。
很多人会把DoS和DDoS混在一起说。严格区分的话,DoS是单一来源发起攻击;DDoS属于分布式攻击,攻击者控制大量分散的肉鸡设备,也就是被入侵的电脑、服务器、物联网设备,从各个地点同时发起攻击。DDoS防御难度更高,流量来源分散,不能简单封禁单个IP解决。目前具备实际威胁的大多是DDoS,单机DoS受带宽和连接数限制,很难形成有效打击。
防御DoS没有一劳永逸的方案,只能分层部署防护。最外层依靠带宽与基础设施,如果服务部署在云平台,云厂商一般自带基础DDoS防护,可以清洗一定量级的攻击流量。但流量清洗存在副作用,攻击流量规模过大时,正常流量也可能被误拦截,表现为部分地区访问卡顿或者间歇性无法访问。
网络设备层面属于中间防护层。防火墙可以配置SYN Cookie,服务器收到SYN包的时候不会立刻分配资源,依靠加密Cookie校验客户端真实性,确认是合法连接之后再分配资源。路由器可以设置速率限制,对单个IP或者网段的并发连接数量设置上限。这类手段应对中小规模攻击效果不错,面对大规模分布式攻击就很难抵挡。
应用层防护里,CDN是目前最常用的缓解方案。流量被分发到各地边缘节点,攻击流量也分摊到不同节点,单个节点承受压力降低。同时CDN厂商一般配套WAF网页应用防火墙,可以识别拦截恶意HTTP请求,过滤脚本类异常流量。反爬虫机制和验证码也能起到作用,检测异常流量时弹出验证,真实用户可以完成验证继续访问,自动化脚本会被拦截。
还有一个手段是隐藏源站IP。如果服务器真实IP直接暴露在公网,攻击者就能绕过CDN直接攻击源站。可以把源站部署在仅CDN能够访问的内网环境,或者使用高防IP转发流量,攻击者获取不到真实IP,攻击难度大幅提升。但这个方案前提是CDN配置没有泄露源站地址,不少站点配置不当,通过历史DNS记录或者子域名扫描,依旧能扒出源站IP。
说到底,DoS防御本质是成本博弈。攻击者付出很低成本就能制造巨量攻击流量,防御方想要承接同等规模攻击,往往需要投入更多资金扩容带宽、采购防护服务。所以实际防护策略不是追求百分百拦截攻击,而是抬高攻击者的攻击成本,让投入超出攻击者预期,同时保证遭受攻击时核心服务还能维持基础可用。