从12月22日凌晨开始,freeshell 有时不能建立 TCP 连接。原因是我在用 freeshell 爬数据,接受了外来的大量 HTTP 请求,每个请求都是一个 TCP 连接。这些 HTTP 请求是 freeshell HTTP proxy 进来的,速度稳定在 200 qps (query per second) 左右。

基于如下事实,我推测是交换机上的防火墙做了限制:

  • proxy 成功的 HTTP 请求速度稳定;
  • 没有接受大量 HTTP 请求的 freeshell 节点也有此问题;
  • ping 没有丢包;
  • freeshell syslog 中没有错误记录,/proc 相关配置也足够大。

随后在少年班学院的一台交换机上发现了防火墙配置,正是 “防止 SYN/SYN-ACK Flooding” 选项捣的鬼,它限制 SYN 包发送速率 128 kbps,按照一个包 64 字节计算,就是 256 pps (packet per second),与 HTTP 200 qps 的数据相符。取消此项限制后,网络恢复正常。此问题大约持续一整天。

顺便关闭了一些可能带来问题的防火墙选项:

  • 丢弃源端口小于1024的SYN报文
  • 防止 Ping Flooding
  • 防止 SYN/SYN-ACK Flooding(这次问题的元凶)

目前这台交换机上开启的防火墙选项包括:

  • 防止 Land 攻击(源地址和目的地址相同,可能在 loopback 接口上引起环路,漏洞存在于 Windows XP/2003 早期版本)
  • 防止 FIN, Xmas, NULL scan(透过拦截 TCP SYN 的防火墙,扫描开放端口)
  • 防止 Ping of Death 攻击(发送非法或超长 ping 包,现代操作系统已经不存在这个漏洞,不过还是防一下)
  • 防止 Smurf 攻击(伪造源地址的 ICMP 报文,反射攻击)