发起一个TCP 连接时,客户端将一个SYN包发送给服务器。作为响应,服务器将SYN + ACK 包返回给客户端。此数据包中有一个序号,它被TCP 用来重新组装数据流。根据TCP规范,由端点发送的第一个序号可以是由该端点决定的任何值。
SYN Cookies是根据以下规则构造的初始序号:
- 令t为一个缓慢递增的时间戳(通常为time()»6,提供64 秒的分辨率);
- 令m为服务器会在SYN 队列条目中存储的最大分段大小(Maximum segment size);
- 令s为一个加密散列函数对服务器和客户端各自的IP 地址和端口号以及t进行运算的结果。返回得到的数值s必须是一个24位值。
初始TCP序号,也就是所谓的SYN cookie,按照如下算法得到:
- 头五位:tmod32;
- 中三位:m编码后的数值;
- 末24位:s本身;
注:由于m必须用3位进行编码,服务器在启用了 SYN Cookie时只能为m发送八种不同的数值。
根据TCP 规范,当客户端发回ACK包给服务器以响应服务器的SYN + ACK包时,客户端必须使用由服务器发送的初始序号加1作为数据包中的确认号。服务器接着从确认号中减去 1 以便还原向客户端发送的原始 SYN Cookie。
接下来服务器进行以下检查:
- 配合现在时间t来检查连接是否过期。
- 重新计算s来确认这是不是一个有效的SYN Cookie。
- 从3位编码中解码m,以便之后用来重建SYN 队列条目。在此之后,连接照常进行。
配置项:
- net.ipv4.tcp_syncookies