SYN Cookie通过让服务器在收到SYN时先不保存连接状态,而是计算一个加密序列号放入SYN-ACK回复,并在收到客户端ACK后验证该序列号,从而在传输层泛洪时零成本完成连接合法性判断。 换句话说,它把原来需要等待二次握手才完成的“记账”工作,提前压缩成一个小印章,让服务器背靠背地躲过了攻击者的虚假请求。
SYN Cookie原理是什么:从三次握手到无状态验证的转变
在TCP的三次握手里,服务器收到SYN包后,需要立刻分配一个传输控制块来记录连接状态,没有SYN Cookie的年代,攻击者可以伪造海量SYN包,把服务器内存塞满,让真正的用户挤不进来。
SYN Cookie的聪明之处在于“不记账”,服务器收到SYN包后,不分配任何资源,只根据源IP、源端口、时间戳和一个密钥,算出一个32位的Cookie值,把它写进SYN-ACK包的序列号里,客户端要完成这个握手,必须把确认号设成这个序列号加一,服务器收到ACK时,再算一遍Cookie,对得上就放行,对不上就丢弃。
整个过程中,服务器完全没有状态,攻击者的封包再多,也只是让CPU额外做几次哈希运算,而内存占用始终为零。
这里需要解释一下Cookie的组成,行业共识认为,它通常由四部分信息混合而成:客户端和服务器地址端口、服务器维护的一个随机密钥、连接发起时刻的粗粒度时间戳,以及一个散列值,这个散列值相当于服务器的私章,客户端即使拿到了Cookie,也无法反推出真实的连接信息。
用拟人化的说法:SYN Cookie就是门口保安,正常情况他记下每个访客的姓名和来意,但洪水来了访客太多,他就改发刻着“暗号”的出入口通行证,谁真的回来对暗号,他才放谁进去。
SYN Cookie和SYN代理对比:哪种防护机制更适合大流量清洗
聊到SYN Cookie,就免不了要拿SYN代理出来比比,SYN代理是防火墙或负载均衡器常用的招数:它先替服务器完成第一次握手,确认对方是真人后,再模拟客户端和真正的服务器握手。
业内专家指出,SYN代理适合部署在网络入口处,比如在IDC机房前置一台专用设备,将所有SYN包先截住,它防御效果好,但代价是设备自身成为瓶颈,一旦流量超过设备性能,照样被冲垮。
SYN Cookie则不同,它依托在服务器内核里,天然没有额外硬件成本,而且因为不需要状态表,内存占用近乎恒定,两者对比下来:
- 资源消耗:SYN Cookie在内存上几乎为零,SYN代理需要维护大量代理连接状态
- 适用位置:SYN Cookie直接在目标服务器内生效,SYN代理通常在网络边界
- 对正常连接的影响:SYN Cookie在正常低并发时并不主动介入,SYN代理则总在握手路径上
如果你的服务器是裸奔在公网上,没有防火墙,那么开启SYN Cookie是目前性价比最高的抗SYN Flood方案,但如果你有预算部署硬件防火墙,那SYN代理在防御大流量时更稳健。
攻击场景下SYN Cookie的生效流程:一场看不见的握手博弈
假设一台Linux服务器遭受了10Gbps级别的SYN Flood,在未开启SYN Cookie时,内核每收到一个SYN就分配内存,几秒钟后内存耗尽,正常用户连不上,开启后,流程变成:
- 收到SYN包,计算Cookie并填入SYN-ACK
- 不写入任何半连接队列,也不创建socket
- 等待客户端的ACK,真实客户端会立刻回ACK,因为它的IP不是伪造的
- 收到ACK后重新计算Cookie,比对确认号,如果信息一致,则真正创建连接并放入accept队列
- 如果客户端不回ACK,比如是伪造IP的攻击者,服务器根本无需理会
这个过程的精妙之处在于,攻击者必须付出真实带宽来回包,而服务器的处理成本只有一次哈希计算。攻击者的SYN包越多,服务器越从容,因为它的内存占用始终为零。
除SYN Flood外,这个逻辑还能顺带抵御部分TCP反射攻击,因为伪造源地址的包在第三步就暴露出原形。近年来的实际部署中,不少运维人员反馈,开启SYN Cookie后服务器在遭受DDoS时存活时间从几分钟延长到几小时,前提是带宽没有被完全打满。
为什么服务器只对ACK包执行完整校验
这里有个细节容易被忽略,SYN Cookie模式下,服务器在收到ACK时,会用TCP的套接字四项信息重新计算Cookie,然后检查确认号是否等于Cookie加一,这个校验过程不依赖内存表,靠的是硬算,更妙的是,如果收到合法的RST包,服务器还能主动回收Cookie生成的临时连接,不会让僵尸连接逗留超过SYN timeout时间。
在Linux服务器上开启SYN Cookie:具体操作与参数调优
实际操作层面,Linux内核默认就支持SYN Cookie,但建议显式确认开启状态,执行命令查看:
sysctl net.ipv4.tcp_syncookies
返回值为1说明已开启,0则未开启,想要主动开启,执行下面的命令:
sysctl -w net.ipv4.tcp_syncookies=1
要让设置永久生效,写入/etc/sysctl.conf文件并执行sysctl -p。
除了开和关,内核还有两个关联参数值得关注。tcp_synack_retries控制SYN-ACK的重发次数,建议设成1或2,不要默认的5次,这样能更快放弃不回ACK的僵尸客户端,另一个是tcp_max_syn_backlog,这是传统半连接队列的上限,开启Cookie后并非完全无用,它影响的是攻击结束后队列的恢复速度。
如果你使用的是云服务器,比如简米云或酷番云,控制台里往往有“DDoS防护”开关,实际上底层就会联动到内核的SYN Cookie策略,国内不少机房提供的防护产品,也默认会在源站服务器上启用该参数。
SYN Cookie的局限:为什么它不能单打独斗
SYN Cookie并不是银弹,它解决的是“伪造源地址的SYN Flood”,但挡不住以下几种情况:
- 攻击者改用真实IP发起大量完整TCP连接,这属于连接耗尽型攻击
- Cookie计算本身消耗少量CPU,超大规模流量下仍可能压垮CPU
- 某些合法的TCP选项(比如大窗口、SACK)会被cookie机制简化,导致大包传输效率下降
务实做法是把SYN Cookie作为第一道防线,再在边界部署专业的流量清洗设备,比如用BGP牵引到高防机房做流量过滤。企业级方案里,硬件防火墙配合内核调优是常见组合,整体成本从几万到几十万不等,具体看带宽大小,这也是“企业抗DDoS方案选择”中最常见的两种思路。
关于SYN Cookie防护效果的常见问题
问题1:SYN Cookie会拖慢正常用户的访问速度吗?
在正常低并发情况下,Linux内核默认不主动启用SYN Cookie,只有同步队列溢出时才自动触发,所以日常访问不受影响,当攻击发生时,真实用户的握手确实会多一次计算延迟,但通常仅在毫秒级,对网页浏览和API调用几乎无感。
问题2:为什么我开启了SYN Cookie,攻击时服务器照样挂?
常见原因是攻击流量已经占满出口带宽,SYN Cookie只是保护服务器的内存和连接表,不能放大你的带宽上限,流量扛不住时,得靠更高容量带宽或云清洗服务来吸收。
问题3:SYN Cookie和无状态防火墙是一回事吗?
不是,无状态防火墙针对的是传输层的每个包独立判断规则,SYN Cookie是专为TCP握手设计的验证机制,防火墙通常在操作系统内核之前拦截恶意流量,SYN Cookie是内核协议栈自身的防御手段,两者可以协同工作,但不能相互替代。
SYN Cookie牺牲了握手阶段的部分状态信息,换来的是极端条件下服务器不宕机、不花一分钱的生存能力,对任何直接暴露在公网上的服务器来说,它都不是可选项,而是必选项。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/787129.html


