我在 UFW 中有这些规则(默认拒绝):
80 ALLOW 10.0.0.0/8
443 ALLOW 10.0.0.0/8
80 DENY Anywhere
443 DENY Anywhere
我从 10.0.0.0/8 上的一台机器连接到监听端口 80 的 Apache。我们注意到在另一台机器上运行的 nginx(这台 Apache 机器前面的负载平衡器)偶尔会抛出“连接超时”错误。我可以通过简单地在 bash 脚本中运行一个 for 循环来重现超时,该脚本从该 nginx 机器访问端口 80。在一批 1000 次测试中,我可能遇到 3 或 4 次超时。
当超时发生时,我在 /var/log/messages 中看到这些内容:
12 月 1 日 01:01:01 webserver.mydomain.com 内核:[UFW BLOCK] IN=eth0 OUT= MAC=00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd SRC=10.0.0.5 DST=10.0.0.2 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=16923 DF PROTO=TCP SPT=60064 DPT=80 WINDOW=5792 RES=0x00 SYN URGP=0
为什么 UFW 会阻止这些?如果我禁用 UFW,这些连接超时将完全消失,一切都将按预期运行。其他端口(如 22)没有这个问题,我可以运行脚本来无休止地敲击这些端口,即使激活了 ufw 也不会出现任何问题。
答案1
我花了大量时间尝试解决此问题。UFW 的介入只是实际问题的征兆,而不是原因。我找到了解决方案,所以我不想让这个问题得不到解答。
我发现由于某种我还无法解释的原因,负载均衡器后面的 Apache 服务器上的 syncookies 被禁用了:
# sysctl -a | grep syncookies
net.ipv4.tcp_syncookies = 0
我无法解释这一点的原因是它在默认的 Centos6 /etc/sysctl.conf 文件中被设置为 1。这是我需要弄清楚的另一个问题。
您可以在这里阅读有关 syn cookies 的更多信息:
http://en.wikipedia.org/wiki/SYN_cookies
这些服务器相对繁忙,需要处理大量连接。我最好的猜测是,启用 UFW(从而启用 iptables)会使速度变慢,刚好导致 syn 队列填满,并且没有 syncookies 的连接开始被拒绝。