TCP报文是否可伪造?SYN洪水攻击的排查、溯源与缓解方案咨询
嘿,先直接给你把核心问题掰明白:TCP报文是完全可以被伪造的,尤其是SYN包——这正是SYN洪水攻击的核心玩法,可别被“TCP是面向连接的可靠协议”这个标签给误导了!
先解释下你遇到的情况:你说系统负载拉满但CPU没被用户态的脚本/程序占用,这完全符合SYN洪水的症状。因为攻击者发送的是伪造源IP的SYN包,你的服务器收到后会老老实实回复SYN-ACK,然后把这个未完成的连接放进半连接队列里等着对方发ACK完成握手。但这个伪造的源IP根本不会回应,服务器只能等超时才会释放这个半连接。如果攻击者发的SYN包足够多,半连接队列直接被塞满,正常用户的请求挤不进来,同时内核要不断维护这些半连接,消耗大量的系统资源,负载自然就爆了——这部分消耗的是内核态资源,所以你看用户态CPU使用率根本不高。
再看你提供的抓包记录,典型得不能再典型了:
以下是我捕获的数据包(从WireShark导出的文本格式):
8671 514.584019 15.185.242.226 {MY_SERVERS_IP} TCP 66 28199 → 80 [SYN] Seq=0 Win=14600 Len=0 MSS=1436 WS=256 SACK_PERM 18672 514.584119 {MY_SERVERS_IP} 15.185.242.226 TCP 66 80 → 28199 [SYN, ACK] Seq=0 Ack=1 Win=64240 Len=0 MSS=1460 SACK_PERM WS=128 18673 514.676551 15.185.242.226 {MY_SERVERS_IP} TCP 66 13932 → 80 [SYN] Seq=0 Win=14600 Len=0 MSS=1436 WS=128 SACK_PERM 18674 514.676652 {MY_SERVERS_IP} 15.185.242.226 TCP 66 80 → 13932 [SYN, ACK] Seq=0 Ack=1 Win=64240 Len=0 MSS=1460 SACK_PERM WS=128 18675 ...
每次来自15.185.242.226的SYN包(源端口还一直在随机变),你的服务器都回复了SYN-ACK,但对方从来没发过ACK来完成握手。亚马逊说流量是“spoofed(伪造的)”一点没错——这个15.185.242.226只是攻击者拿来当幌子的IP,真正发起攻击的主机根本不是它。
那接下来该怎么缓解呢?给你几个实打实的办法:
- 调整Linux内核TCP参数:
- 增大半连接队列上限:
sysctl -w net.ipv4.tcp_max_syn_backlog=4096(数值可以根据服务器配置调整) - 减少SYN-ACK重试次数,让半连接更快释放:
sysctl -w net.ipv4.tcp_synack_retries=2(默认是5次,调少能减少等待时间) - 开启SYN Cookie:
sysctl -w net.ipv4.tcp_syncookies=1——当半连接队列满了之后,服务器会用Cookie来代替半连接记录,不需要占用队列资源,直接就能回复SYN-ACK,等真的收到合法ACK再建立连接,这是应对SYN洪水的关键手段。
要是想让这些参数永久生效,把它们写到/etc/sysctl.conf里,然后执行sysctl -p就行。
- 增大半连接队列上限:
- 用防火墙限流:
比如用iptables设置单位时间内的SYN包上限,虽然攻击者用的是伪造IP,但能过滤掉一部分异常流量:
如果你用的是AWS,还可以用安全组(Security Groups)或者WAF来做更严格的访问控制,WAF能直接识别SYN洪水这类攻击特征,精准拦截异常流量。iptables -A INPUT -p tcp --syn -m limit --limit 10/s --limit-burst 20 -j ACCEPT iptables -A INPUT -p tcp --syn -j DROP - 启用云服务商的DDoS防护:
AWS的Shield基础版是免费的,已经能应对大部分中小规模的SYN洪水;进阶版会提供更专业的流量清洗和防护,适合更大规模的攻击。直接在AWS控制台里就能开启,不用自己折腾太多。
最后说下溯源的问题:因为攻击者用的是伪造IP,想从抓包的源IP找到真实攻击者基本不可能——那个15.185.242.226只是被冒用的。你可以看看AWS的VPC Flow Logs,分析下流量的入口和模式,但说实话,溯源难度极大,当下的重点还是放在防护上,先把服务器的负载降下来,让正常业务能跑起来。
备注:内容来源于stack exchange,提问作者OwN

