<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>握手 · XB 现场笔记</title><link>https://hk.xbcatm.com/zh/tags/%E6%8F%A1%E6%89%8B/</link><description>基于 HTTP、DNS、TLS、Caddy、SSH、发布与恢复的可复现运维现场笔记。</description><generator>Hugo</generator><language>zh-CN</language><atom:link href="https://hk.xbcatm.com/zh/tags/%E6%8F%A1%E6%89%8B/index.xml" rel="self" type="application/rss+xml"/><item><title>SYN Cookie 在队列溢出时作答</title><link>https://hk.xbcatm.com/zh/posts/tcp-syn-cookies-when-syns-overflow/</link><pubDate>Sat, 30 Oct 2027 00:00:00 +0000</pubDate><guid>https://hk.xbcatm.com/zh/posts/tcp-syn-cookies-when-syns-overflow/</guid><description>SYN Cookie 减少待完成请求需要保留的状态；已建立连接仍需准入与应用处理容量。</description><content:encoded>&lt;p&gt;Linux TCP 监听端区分尚未完成的握手请求，以及已经建立但等待应用 &lt;code&gt;accept()&lt;/code&gt; 的连接，通常称为 SYN 队列和 accept 队列。两者容量限制与溢出路径不同，排查连接故障时应先确定压力发生在哪个阶段，不能把所有等待都归到同一个 backlog 数字。&lt;/p&gt;
&lt;p&gt;SYN Cookie 减少握手未完成期间需要保留的逐请求状态。服务器把可恢复信息编码到 SYN-ACK，收到有效回复后重建连接状态。节省的是待完成请求的内存，不代表处理没有开销，也不取消已建立连接的状态，更不保证一定准入或保持正常应用性能。&lt;/p&gt;
&lt;figure class="technical-diagram"&gt;&lt;img loading="lazy" src="https://hk.xbcatm.com/visuals/posts-tcp-syn-cookies-when-syns-overflow.detail.zh.svg" alt="SYN 队列涉及未完成握手，accept 队列保存已建立连接。客户端发送 SYN，收到在序号中携带 cookie 的 SYN-ACK，再发送 ACK 供校验。有效 cookie 仍需连接准入；已建立连接仍等待应用 accept()。cookie 不增加应用接受或处理能力。" width="720" height="2310"&gt;&lt;figcaption&gt;SYN Cookie 作用于握手。校验不会绕过 accept 队列，也不会增加应用接受能力。&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id="两个队列两种症状"&gt;两个队列，两种症状&lt;/h2&gt;
&lt;p&gt;普通有状态路径会保留请求，等待最后一个 ACK。Linux 文档将 &lt;code&gt;tcp_max_syn_backlog&lt;/code&gt; 描述为每个监听端记住的请求上限；随内存变化的默认值与请求大小估算，不是所有机器的分配实测。等待应用接受的已建立连接，则由 &lt;code&gt;listen()&lt;/code&gt; backlog 及 &lt;code&gt;somaxconn&lt;/code&gt; 上限约束。Linux 从 5.4 起将 &lt;code&gt;somaxconn&lt;/code&gt; 默认设为 4096，但部署值可以不同。&lt;/p&gt;
&lt;p&gt;Cookie 可以缓解未完成握手状态耗尽，却不保证连接一定完成。accept 队列满时，已建立子连接可能无法创建或准入。&lt;code&gt;tcp_abort_on_overflow=0&lt;/code&gt; 下，某些有状态路径忽略 ACK 并保留待完成请求，之后仍可能恢复。客户端可能已经报告 connect 成功，其他尝试也可能超时。本次审阅没有重现原有四百客户端说法，也未将其绑定到保留的原始结果，不能据此确定具体丢失数量。&lt;/p&gt;
&lt;h2 id="cookie-就是你拒绝保存的那份状态"&gt;Cookie 就是你拒绝保存的那份状态&lt;/h2&gt;
&lt;p&gt;启用 CONFIG_SYN_COOKIES 的 Linux 中，模式一把 Cookie 用作溢出后备措施；模式二用于无条件生成的测试。固定 Linux 6.12 的 IPv4 实现把带密钥哈希、客户端初始序列号、时间计数器和 MSS 表索引合成为序列号。返回确认号的原始高位，并不是可以直接读取的计数器，不能只按位切开就宣称完成校验。&lt;/p&gt;
&lt;p&gt;该实现每六十秒推进一次计数器，只有当前或前一个计数槽才会继续校验。七十秒前生成的 Cookie 可能已经跨过两个边界而失效，单凭经过时长不能确定结果。校验还绑定连接字段，并检查恢复出的索引。这些机制抵抗盲目伪造，但不是应用身份认证，也不能用统一的二十四位猜中概率代替完整安全论证。&lt;/p&gt;
&lt;h2 id="cookie-装不下的东西"&gt;Cookie 装不下的东西&lt;/h2&gt;
&lt;p&gt;选项支持取决于实现与本次握手。Linux 6.12 可以把窗口缩放、SACK 与 ECN 信息编码到时间戳位，再从回显时间戳恢复；缺少这条时间戳路径时，某些选项可能丢失。内核文档对扩展和性能限制发出警告，却不能据此断言每个 Cookie SYN-ACK 都没有选项，或每条获准连接必然更慢。应以对应版本的实际实现和握手内容判断。&lt;/p&gt;
&lt;p&gt;固定版本的 IPv4 实现从四个 MSS 表项中选择，不能原样保留任意通告。如果没有窗口缩放，65535 字节接收窗口可能限制长 RTT 传输；这是带条件的窗口约束，不是 Cookie 模式吞吐实测。缺少 SACK 会改变恢复信息，但不强制重传后续所有段。先捕获实际选项，再判断减速是否来自 Cookie，不能仅凭启用状态推导性能损失。&lt;/p&gt;
&lt;h2 id="坏掉的样子"&gt;坏掉的样子&lt;/h2&gt;
&lt;p&gt;Cookie 可能降低可见的待完成请求深度，但压力仍在持续。应把 &lt;code&gt;SyncookiesSent&lt;/code&gt; 增量与队列占用、连接尝试、CPU 负载、警告和应用结果一起观察。计数上涨不证明遭遇攻击，合法过载或无条件测试模式也会产生 Cookie。应用仍可能失败，相关指标仍有价值，不能断言洪泛必然没有错误日志或应用层迹象。&lt;/p&gt;
&lt;p&gt;Cookie 不增加 accept 队列或应用处理容量。选择补救办法前，应同时调查 &lt;code&gt;ListenOverflows&lt;/code&gt;、接受速率与资源限制。更大的 backlog 可以吸收部分突发，却不增加持续处理能力；更快接受或增加工作进程，只有在对应阶段确为瓶颈时才有帮助。修改 Cookie 模式不能修复停滞应用，也不能保证所有观察数字都完全不变。&lt;/p&gt;
&lt;h2 id="快速验证"&gt;快速验证&lt;/h2&gt;
&lt;p&gt;以下只读 Linux 命令检查配置、累计计数和监听队列，不会复现洪泛、验证 Cookie 或测量报文交付：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sysctl net.ipv4.tcp_syncookies net.ipv4.tcp_max_syn_backlog net.core.somaxconn
nstat -az | grep -E &amp;#39;Syncookies|ListenOverflow|ListenDrops&amp;#39;
ss -lnt
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在相关网络命名空间取可比较的快照，重点看增量。当前健康的服务也可能有非零历史计数，accept 队列短暂非空同样正常。对监听 TCP 套接字，&lt;code&gt;Recv-Q&lt;/code&gt; 表示握手完成后等待接受的连接，&lt;code&gt;Send-Q&lt;/code&gt; 表示 backlog 上限。持续接近上限的占用、新增溢出与请求失败共同出现，比任何单独累计总数更能支持接受阶段存在压力的判断。&lt;/p&gt;
&lt;h2 id="来源"&gt;来源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc4987.html"&gt;RFC 4987 TCP SYN 洪泛缓解&lt;/a&gt;，cookie 的构造方式及其取舍，已核验 2026-09-16。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc9293.html"&gt;RFC 9293 TCP&lt;/a&gt;，三次握手与 backlog 的概念，已核验 2026-09-16。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.kernel.org/networking/ip-sysctl.html"&gt;Linux 内核 ip-sysctl&lt;/a&gt;，tcp_syncookies、tcp_max_syn_backlog、somaxconn 与 tcp_abort_on_overflow，已核验 2026-09-16。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/torvalds/linux/v6.12/net/ipv4/syncookies.c"&gt;Linux 6.12 IPv4 SYN cookies&lt;/a&gt;，带密钥的 Cookie 构造、MSS 表与时间戳携带选项，已核验 2026-10-19。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raw.githubusercontent.com/torvalds/linux/v6.12/include/net/tcp.h"&gt;Linux 6.12 TCP Cookie 计时&lt;/a&gt;，六十秒计数器与两个计数槽年龄检查，已核验 2026-10-19。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/torvalds/linux/blob/v6.12/net/ipv4/tcp_minisocks.c"&gt;Linux 6.12 待完成请求处理&lt;/a&gt;，带条件的溢出处理与请求保留，已核验 2026-10-19。&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item></channel></rss>