SYN洪水攻击直击TCP三次握手的协议缺陷。攻击者发送大量伪造源IP的SYN包,服务器响应SYN-ACK后,必须为每个半开连接分配内存资源,等待那个永远不会到来的ACK确认。当半连接队列被塞满,正常用户的请求就会被丢弃,服务器表现为无法访问。内核参数调优的核心思路很明确:缩短等待时间、扩大队列容量、尽早丢弃异常包、启用SYN Cookie机制。下面直接给出Debian系统上具体要调整的参数和操作方法。
理解半连接队列与SYN Cookie的工作机制Debian服务器的网络栈在接收到SYN包后,会先在SYN队列中创建条目,发送SYN-ACK,然后等待客户端回送ACK完成连接。这个SYN队列的大小由内核参数net.core.somaxconn和net.ipv4.tcp_max_syn_backlog共同决定。当队列满了,新的SYN包默认会被丢弃。SYN Cookie技术则提供了一条绕过队列的路径:服务器收到SYN时不立即分配资源,而是根据客户端IP、端口、时间戳和密钥计算出一个哈希值作为初始序列号发回。当客户端带着ACK返回时,服务器验证这个序列号的合法性,合法才分配连接资源。这样一来,攻击者即便发送海量SYN包,也无法消耗服务器的内存,因为根本没有为其预留任何结构体。
开启并配置SYN Cookie首先要确认SYN Cookie功能处于启用状态。编辑/etc/sysctl.conf文件,添加或修改以下参数:
net.ipv4.tcp_syncookies = 1
这个值设为1表示当SYN队列溢出时自动触发SYN Cookie。如果你想无论队列是否满都强制使用SYN Cookie,可以设为2,但通常不建议,因为正常流量下标准SYN队列的处理效率更高。执行sysctl -p让配置生效。你可以通过查看/proc/sys/net/ipv4/tcp_syncookies确认当前值。SYN Cookie有一个小代价,它会丢失部分TCP选项协商能力,比如窗口缩放和选择性确认,但在攻击场景下这点性能损失完全可以接受。
扩大SYN队列容量在SYN Cookie兜底之前,合理增大队列容量能缓冲突发流量。调整两个关键参数:
net.core.somaxconn = 65535 net.ipv4.tcp_max_syn_backlog = 65535
net.core.somaxconn是系统级限制,控制每个监听套接字的SYN队列最大长度。很多应用程序内部也有自己的backlog参数,比如Nginx的backlog指令,但应用程序能设置的最大值不会超过这个内核限制。net.ipv4.tcp_max_syn_backlog则是针对所有TCP监听端口的全局SYN队列上限。将两者都提升到65535,可以容纳更多半连接请求。需要注意的是,增大队列意味着内存消耗增加,每个SYN条目大约占用几百字节,65535个条目大约消耗几十MB内存,对于现代服务器完全可以接受。
缩短SYN-ACK重试次数与超时时间服务器发出SYN-ACK后,如果迟迟收不到客户端的ACK,会进行重试。攻击者正是利用这段时间窗口占用队列资源。缩短重试次数和重试间隔,能快速释放被攻击包占用的槽位:
net.ipv4.tcp_synack_retries = 1 net.ipv4.tcp_syn_retries = 1
tcp_synack_retries控制服务器端SYN-ACK的重传次数。默认值是5,意味着从第一次发出SYN-ACK到最后放弃,总共会等待约180秒。改为1后,只重传一次,总等待时间缩短到几秒。tcp_syn_retries控制客户端发起连接时SYN包的重传次数,降低它同样能减少攻击源占用的本地资源。对于面向公网的服务,这两个值设为1或2是合理选择,内网环境可以适当调高。
加速回收TCP连接与减少TIME_WAITSYN洪水攻击有时会伴随大量短连接,加速回收处于TIME_WAIT状态的连接可以释放更多资源:
net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 0 net.ipv4.tcp_fin_timeout = 30
tcp_tw_reuse允许将处于TIME_WAIT状态的连接用于新的出站连接,这对反向代理服务器很有用。tcp_tw_recycle在较新的内核中已经被移除,因为它对NAT环境不友好,设为0或直接忽略。tcp_fin_timeout控制FIN_WAIT_2状态的最长存活时间,默认60秒,降到30秒能更快回收连接资源。另外,调整本地端口范围也能提升高并发下的端口复用效率:
net.ipv4.ip_local_port_range = 1024 65535
这组参数将可用端口范围扩大到1024到65535,增加了约64000个端口,减少了端口耗尽风险。
启用TCP时间戳与选择性确认时间戳选项能帮助内核更精确地计算RTT,从而更快地判断一个包是否已经超时。选择性确认允许接收方告知发送方哪些数据段已经收到,避免不必要的重传。这两个选项在防御攻击时能提升协议栈的处理效率:
net.ipv4.tcp_timestamps = 1 net.ipv4.tcp_sack = 1
时间戳还会被SYN Cookie机制用来编码部分连接信息,所以开启它对Cookie验证的准确性也有帮助。
配置连接跟踪与防火墙联动如果服务器启用了iptables或nftables的连接跟踪模块,SYN洪水会导致conntrack表被塞满。调整连接跟踪参数:
net.netfilter.nf_conntrack_max = 2097152 net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 30 net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 30
nf_conntrack_max设置连接跟踪表的最大条目数,根据内存大小合理设定,一般每1GB内存可以支持约65536个条目。nf_conntrack_tcp_timeout_syn_recv和nf_conntrack_tcp_timeout_syn_sent分别控制收到SYN和发出SYN后的超时时间,默认值较长,缩短到30秒能减少跟踪条目堆积。如果你使用的是nftables,对应的超时设置在规则集里通过timeout对象定义,原理相同。
配置rp_filter与accept_source_route反向路径过滤能丢弃源地址明显伪造的数据包,这在SYN洪水攻击中非常有效,因为攻击者通常会伪造不存在的源IP:
net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1
当rp_filter设为1时,内核会检查入站数据包的源地址是否可以通过接收该包的接口路由回去。如果路由表中没有对应路径,这个包就会被丢弃。这能过滤掉大量伪造源地址的攻击流量。同时关闭源路由功能,防止攻击者利用源路由选项绕过正常路由决策:
net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0限制ICMP与SYN速率
在iptables层面配合限流规则,可以进一步减轻内核压力。使用limit模块限制每秒接受的SYN包数量:
iptables -A INPUT -p tcp --syn -m limit --limit 100/s --limit-burst 150 -j ACCEPT iptables -A INPUT -p tcp --syn -j DROP
这条规则的意思是,每秒最多接受100个SYN包,初始突发容量为150个,超出部分直接丢弃。limit-burst允许短时突发超过limit速率,避免正常流量尖峰被误杀。你需要根据服务器实际业务量调整这两个数值,监控正常情况下的SYN包速率后取1.5到2倍作为阈值比较合理。对于ICMP洪水,同样可以限速:
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 10/s -j ACCEPT iptables -A INPUT -p icmp --icmp-type echo-request -j DROP调整内存与缓冲区参数
TCP协议栈的读写缓冲区大小直接影响数据包的处理能力,在高负载下合理增大缓冲区能减少丢包:
net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216 net.core.netdev_max_backlog = 5000
rmem_max和wmem_max是单个套接字读写缓冲区的最大字节数,设为16MB可以应对大流量突发。tcp_rmem和tcp_wmem的三个值分别代表最小值、默认值和最大值,内核会根据负载自动在范围内调整。netdev_max_backlog控制网卡驱动将数据包交给内核处理之前的环形缓冲区大小,增大到5000能缓冲更多突发数据包,避免因处理不及时而丢包。
将配置持久化并验证效果所有sysctl参数写入/etc/sysctl.conf后,执行sysctl -p使其立即生效。建议在/etc/sysctl.d/目录下创建独立配置文件,比如/etc/sysctl.d/99-anti-ddos.conf,便于管理和迁移。配置生效后,使用ss -s命令查看TCP统计信息,关注syn-sent和time-wait的数量变化。用netstat -s | grep -i syncookie可以查看SYN Cookie的触发次数,如果这个计数器在攻击期间增长,说明Cookie机制正在工作。压力测试可以用hping3工具模拟SYN洪水,从另一台机器执行:
hping3 -S --flood -p 80 --rand-source 目标IP
观察服务器CPU和内存使用情况,以及服务是否仍能正常响应。注意这种测试仅在授权环境下进行。
结合应用层防护构建纵深防御内核参数调优是基础防线,但它无法完全替代应用层防护。如果攻击流量超过了网卡带宽,任何内核优化都无济于事。在生产环境中,应当将内核参数优化与负载均衡器、反向代理的速率限制、CDN的流量清洗能力结合起来。Nginx的limit_req和limit_conn模块可以在应用层限制单个IP的请求速率和并发连接数,HAProxy也有类似的连接限制功能。内核负责快速丢弃异常包,应用层负责精准识别和拦截恶意客户端,两者配合才能形成完整的防御链条。定期审计sysctl配置,确保变更记录在案,并在内核版本升级后重新验证参数兼容性,因为某些参数在不同版本中行为可能发生变化。
