SYN 泛洪是一种 DoS 攻击的形式,攻击者向受害者的 TCP 端口发送许多 SYN 请求,但并不完成三次握手。攻击者要么使用仿冒的IP地址,要么不再继续握手的过程。通过这种攻击,攻击者可以将受害者的半连接队列塞满。半连接指的是已经完成 SYN、SYN-ACK,但还没有得到最终的ACK的连接。当这个队列满了之后,受害者没法接受新的连接请求。下图展示了该攻击过程。
半连接队列的大小是操作系统里的一个设置。在Ubuntu操作系统中,我们可以通过以下命令检查这个设置。操作系统根据系统的内存大小设置该值,内存越多,值就越大。
# sysctl net.ipv4.tcp_max_syn_backlog
net.ipv4.tcp_max_syn_backlog = 128
我们可以用 "netstat -nat" 查看队列的使用情况, 也就是半连接的数量。这种连接的状态是 SYN-RECV。如果三次握手已经完成,连接的状态将会是 ESTABLISHED。
SYN Cookie 防御机制。在默认情况下,Ubuntu 的 SYN 泛洪攻击的防御机制是打开的。这个机制被称为 SYN cookie。一旦机器检测到自己在遭受 SYN 泛洪攻击,这立即启动这个防御机制。在我们的受害者容器中,我们已经关闭了这一机制(见 docker-compose.yml 文件中的 sysctls 条目)。我们可以使用下面的 sysctl 命令来开关这一机制:
# sysctl -a | grep syncookies (显示 SYN cookie 状态)
# sysctl -w net.ipv4.tcp_syncookies=0 (关闭 SYN cookie)
# sysctl -w net.ipv4.tcp_syncookies=1 (打开 SYN cookie)
为了能在容器中使用 sysctl 改变系统变量,需要将"privileged: true"。这个配置条目添加到受害者容器中。如果没有这项配置,运行上述命令后会看到如下错误,因为容器没有权限进行修改操作。
# sysctl -w net.ipv4.tcp_syncookies=1
sysctl: setting key "net.ipv4.tcp_syncookies": Read-only file system