SYN洪水攻击和ACK Flood攻击是DDoS防护中最常见的两种TCP层攻击方式,它们的核心区别在于:SYN洪水利用TCP三次握手的第一步,通过大量伪造源IP发送SYN包耗尽服务器半连接队列;而ACK Flood则是利用大量无状态的ACK包冲击防火墙或服务器的连接跟踪表,消耗系统资源。应对策略上,SYN洪水主要靠SYN Cookie、SYN Proxy和连接速率限制来防御,ACK Flood则需要依赖状态检测防火墙、ACK包频率限制和深度包检测(DPI)技术。下面我把这两种攻击的原理、区别、检测方法和防御手段一次性讲透。
一、SYN洪水攻击的核心原理
SYN洪水是最经典的DDoS攻击手法之一。正常的TCP连接需要三次握手:客户端发SYN,服务端回SYN-ACK,客户端再回ACK,连接建立。攻击者利用这个机制,用大量伪造源IP地址的机器同时向目标服务器发送SYN包。服务器收到后会分配资源、回发SYN-ACK,然后等待客户端的最终ACK。但因为源IP是假的,这个ACK永远不会来。服务器的半连接队列(syn queue)被迅速填满,正常用户的连接请求就无法被处理了。
SYN洪水攻击的特点非常明显:攻击流量大、源IP随机伪造、目标端口通常是80、443、22等常用服务端口。一个中等规模的SYN洪水攻击就能达到每秒数十万甚至上百万个SYN包,足以让普通服务器瘫痪。
二、ACK Flood攻击的核心原理
ACK Flood攻击的逻辑完全不同。它不利用握手过程,而是直接向目标发送大量TCP ACK包。这些包本身不建立连接,但会触发服务器或防火墙的连接状态检测机制。服务器需要检查每个ACK包是否属于某个已有连接,如果属于则放行,如果不属于则丢弃。问题在于,当ACK包数量极大时,防火墙和服务器的连接跟踪表(conntrack table)会被撑爆,CPU和内存资源被大量消耗在无效的包检测上。
ACK Flood还有一个变种叫"伪ACK攻击",攻击者故意构造源端口和目的端口都随机的ACK包,让防火墙无法快速匹配到已有会话,只能逐个检查,进一步加剧资源消耗。这种攻击的隐蔽性更强,因为单个ACK包看起来很"正常",不像SYN包那么容易被简单规则拦截。
三、SYN洪水与ACK Flood的关键区别对比
从攻击层面看,两者有几个本质差异。第一,攻击目标不同:SYN洪水攻击的是服务器的半连接队列和TCP协议栈本身,ACK Flood攻击的是防火墙和服务器的连接状态跟踪机制。第二,攻击包特征不同:SYN洪水的包里只有SYN标志位,ACK Flood的包里只有ACK标志位。第三,伪造难度不同:SYN洪水必须伪造源IP才能达到效果,ACK Flood对源IP的伪造要求没那么高,因为它不依赖握手回应。第四,检测难度不同:SYN洪水因为特征明显,传统防火墙较容易识别;ACK Flood因为每个包看起来都像正常流量的一部分,检测难度更大。
从资源消耗角度看,SYN洪水主要消耗服务器的内存和连接队列资源,ACK Flood主要消耗防火墙的CPU和连接跟踪表资源。实际攻击中,两者经常组合使用,形成混合型DDoS攻击,让防御难度成倍增加。
四、如何检测这两种攻击
检测SYN洪水相对直接。如果你发现服务器的半连接数(可以用netstat -an | grep SYN_RECV查看)突然飙升到几千甚至上万,同时SYN包的入站速率远超正常值,基本可以判定是SYN洪水。Linux系统下可以通过以下命令实时监控:
netstat -n -p | grep SYN_RECV | wc -l ss -s
检测ACK Flood则需要更精细的手段。你需要观察防火墙的连接跟踪表使用率、CPU占用率,以及入站ACK包的速率和分布。如果发现大量ACK包的源端口和目的端口组合非常随机,且没有对应的已建立连接,就要高度警惕。使用tcpdump抓包分析是最直接的方法:
tcpdump -i eth0 'tcp[tcpflags] & (tcp-ack) != 0' -c 1000
这条命令会抓取1000个带ACK标志的TCP包,你可以分析其中有多少是属于正常会话的,有多少是孤立的无效包。如果无效ACK占比超过80%以上,基本可以确认是ACK Flood攻击。
五、SYN洪水的防御策略
防御SYN洪水有多个层次的手段。第一层是SYN Cookie技术。这是Linux内核自带的功能,开启后服务器不再为每个SYN请求分配内存,而是通过加密算法生成一个特殊的初始序列号作为SYN-ACK的回应。只有客户端回传正确的ACK(包含正确的序列号+1),服务器才会分配资源建立连接。开启方法很简单:
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
第二层是SYN Proxy。在服务器前面部署一个代理(比如HAProxy、Nginx的stream模块),由代理先完成三次握手,确认客户端是真实的之后再转发给后端服务器。这样后端服务器根本不会收到大量半连接请求。
第三层是调整内核参数。把半连接队列的大小调大,同时缩短半连接的超时时间,让无效连接更快被清理:
echo 2048 > /proc/sys/net/ipv4/tcp_max_syn_backlog echo 2 > /proc/sys/net/ipv4/tcp_synack_retries
第四层是使用专业的DDoS防护设备或云清洗服务。当流量超过本地防御能力时,把流量牵引到清洗中心进行过滤,是最稳妥的方案。
六、ACK Flood的防御策略
ACK Flood的防御比SYN洪水更具挑战性,因为它更隐蔽。第一招是启用防火墙的状态检测功能,并且配置严格的规则:只允许属于已建立连接的ACK包通过,其他一律丢弃。在iptables中可以这样配置:
iptables -A INPUT -p tcp --tcp-flags ACK ACK -m state --state ESTABLISHED -j ACCEPT iptables -A INPUT -p tcp --tcp-flags ACK ACK -j DROP
这两条规则的意思是:只有状态为ESTABLISHED(已建立连接)的ACK包才允许通过,其他所有ACK包直接丢弃。这是最基础也最有效的防御手段。
第二招是限制ACK包的速率。在防火墙上设置每秒允许通过的ACK包数量上限,超过阈值的直接限速或丢弃。第三招是使用具备深度包检测(DPI)能力的下一代防火墙(NGFW),它能分析ACK包的上下文,判断是否真的属于合法会话。第四招是调整连接跟踪表的大小和超时策略,避免表被撑爆:
echo 262144 > /proc/sys/net/netfilter/nf_conntrack_max echo 120 > /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established
七、混合攻击场景下的综合防护方案
现实中的DDoS攻击很少只用一种手法。攻击者往往同时发起SYN洪水、ACK Flood、UDP Flood等多种攻击,目的是让你的防御顾此失彼。综合防护需要做到几点:首先,在网络边界部署高防IP或高防CDN,把大流量攻击在边缘就清洗掉;其次,服务器端开启SYN Cookie和严格的状态检测规则;第三,建立实时监控告警机制,当半连接数、连接跟踪表使用率、CPU占用率等指标异常时自动触发防护策略;第四,定期做压力测试,验证防护方案的有效性。
另外有一个很多人忽略的点:ACK Flood攻击有时候不是单独发起的,而是作为SYN洪水的"辅助攻击"。攻击者先用SYN洪水占满连接队列,同时用ACK Flood冲击防火墙的状态检测模块,让防火墙忙于处理无效包而无法有效拦截SYN包。所以防御时不能只盯着一种攻击类型,必须建立多维度的检测和防御体系。
八、选择DDoS防护方案的实用建议
如果你是中小企业,预算有限,优先做好这几件事:开启Linux的SYN Cookie、配置iptables状态检测规则、使用云服务商提供的基础DDoS防护。如果你是中大型企业或在线业务,建议采购专业的硬件防火墙或接入云清洗服务,同时建立7x24小时的安全运营团队。不管哪种规模,都不要忽视日志分析和攻击溯源,只有了解攻击者的手法,才能持续优化防御策略。
最后说一句实话:没有任何单一技术能100%防御所有DDoS攻击。SYN洪水和ACK Flood只是冰山一角,真正的安全防护是一个持续迭代的过程。把基础防护做扎实,把监控告警做完善,把应急响应流程跑通,比追求某个"银弹"方案靠谱得多。
