我有一台安装了 nginx 的 Ubuntu 12.04 服务器,端口为 80。只有一个防火墙规则,将端口 26 映射到 25 端口。nginx 设置为监听端口 80,最初是使用相对默认的设置,现在已做了修改。
我写了一个Perl脚本,用于监视tcpdump并查找/报告悬空SYN的数量。每隔几秒钟它会发现一些悬空SYN(随着我们累积的从未回复的TCP SYN数据包计数稳步上升)。显然未回复SYN的速率约为2500中的1个。当我ping这些IP时,假设它们是可ping通的,没有丢包,也没有与它们通信的问题。
内核日志中没有有用的信息(例如“发送syncookies”)。
nginx有
我以前从未遇到过这个问题。虽然受众相同,内核版本较早,硬件不同(这是一个虚拟服务器),数据中心也不同。
我的“煤矿中的金丝雀”报告显示,从他们的角度来看,他们在他们的Windows XP电脑上看到了超时和无回复,但如果通过设置为代理的Linux机器进行,则不存在这种情况。因此,他们正在调查这个问题。然而,无论他们得出什么结论,我都不确定为什么我可以嗅探来自端口80的入站SYN数据包,但没有在同一接口上发送出去的后续回复数据包。
listen x.x.x.x:80 backlog=5000;
nginx并不那么繁忙,nginx_status显示大约每秒50个请求。
Active connections: 480
server accepts handled requests
84618 84618 143733
Reading: 0 Writing: 4 Waiting: 474
有些用户(占很少一部分)抱怨他们的某台电脑(比如说“只在家里出现这个问题”)似乎忽略了它的SYN数据包。他们可以进行无丢失的ping测试,有时候他们会收到一些TCP请求的响应。例如在pop服务器上可以得到静态端口的响应。但是通常情况下他们会经历长时间的超时。我从他们那里拿到了数据包转储,证实了这一点。
在我的端口,我也可以看到一些IP地址被忽略了。
例如,在这里,从2010端口发送到80端口的多个SYN数据包没有回复,而服务器正在通过2031端口处理先前的连接。
02:21:46.950979 IP 72.38.0.37.2010 > 64.91.255.98.80: Flags [S], seq 3835139709, win 65535, options [mss 1460,nop,wscale 3,nop,nop,TS val 0 ecr 0,nop,nop,sackOK], length 0
02:21:49.887320 IP 72.38.0.37.2010 > 64.91.255.98.80: Flags [S], seq 3835139709, win 65535, options [mss 1460,nop,wscale 3,nop,nop,TS val 0 ecr 0,nop,nop,sackOK], length 0
02:21:55.923151 IP 72.38.0.37.2010 > 64.91.255.98.80: Flags [S], seq 3835139709, win 65535, options [mss 1460,nop,wscale 3,nop,nop,TS val 0 ecr 0,nop,nop,sackOK], length 0
02:22:24.950448 IP 72.38.0.37.2031 > 64.91.255.98.80: Flags [S], seq 4138069869, win 65535, options [mss 1460,nop,wscale 3,nop,nop,TS val 0 ecr 0,nop,nop,sackOK], length 0
02:22:24.950488 IP 64.91.255.98.80 > 72.38.0.37.2031: Flags [S.], seq 248034551, ack 4138069870, win 14480, options [mss 1460,sackOK,TS val 240617577 ecr 0,nop,wscale 7], length 0
02:22:24.982809 IP 72.38.0.37.2031 > 64.91.255.98.80: Flags [.], ack 1, win 50112, options [nop,nop,TS val 372774 ecr 240617577], length 0
02:22:24.982852 IP 72.38.0.37.2031 > 64.91.255.98.80: Flags [P.], seq 1:526, ack 1, win 50112, options [nop,nop,TS val 372774 ecr 240617577], length 525
02:22:24.982869 IP 64.91.255.98.80 > 72.38.0.37.2031: Flags [.], ack 526, win 122, options [nop,nop,TS val 240617585 ecr 372774], length 0
02:22:25.016783 IP 64.91.255.98.80 > 72.38.0.37.2031: Flags [P.], seq 1:265, ack 526, win 122, options [nop,nop,TS val 240617594 ecr 372774], length 264
02:22:25.190570 IP 72.38.0.37.2031 > 64.91.255.98.80: Flags [.], ack 265, win 50079, options [nop,nop,TS val 372777 ecr 240617594], length 0
02:22:45.017288 IP 64.91.255.98.80 > 72.38.0.37.2031: Flags [F.], seq 265, ack 526, win 122, options [nop,nop,TS val 240622594 ecr 372777], length 0
02:22:45.049437 IP 72.38.0.37.2031 > 64.91.255.98.80: Flags [.], ack 266, win 50079, options [nop,nop,TS val 372976 ecr 240622594], length 0
02:22:49.998299 IP 72.38.0.37.2031 > 64.91.255.98.80: Flags [R.], seq 526, ack 266, win 0, length 0
02:23:18.883263 IP 72.38.0.37.2059 > 64.91.255.98.80: Flags [S], seq 2419025537, win 65535, options [mss 1460,nop,wscale 3,nop,nop,TS val 0 ecr 0,nop,nop,sackOK], length 0
02:23:21.890861 IP 72.38.0.37.2059 > 64.91.255.98.80: Flags [S], seq 2419025537, win 65535, options [mss 1460,nop,wscale 3,nop,nop,TS val 0 ecr 0,nop,nop,sackOK], length 0
更简单地说,在20秒的开始附近,这里有一个来自一个IP的孤立数据包,它没有与任何其他数据包(发送到此主机)匹配:
2:48:05.141703 IP 96.48.197.237.1275 > 64.91.255.98.80: Flags [S], seq 2682822499, win 65535, options [mss 1460,nop,wscale 2,nop,nop,TS val 0 ecr 0,nop,nop,sackOK], length 0
我写了一个Perl脚本,用于监视tcpdump并查找/报告悬空SYN的数量。每隔几秒钟它会发现一些悬空SYN(随着我们累积的从未回复的TCP SYN数据包计数稳步上升)。显然未回复SYN的速率约为2500中的1个。当我ping这些IP时,假设它们是可ping通的,没有丢包,也没有与它们通信的问题。
内核日志中没有有用的信息(例如“发送syncookies”)。
nginx有
worker_processes 8
worker_connections 4096
开启了keepalive,使用了open_file_cache模块,但我很难看到哪些其他变量可能会默默地忽略SYN数据包,但只针对特定的IP地址进行重复操作。
除了默认的Ubuntu设置外,sysctl.conf还有:
# increased
net.ipv4.tcp_fin_timeout = 10
net.ipv4.ip_local_port_range = 1024 65535
net.core.somaxconn = 1024
# default
net.ipv4.tcp_tw_reuse = 0
# default
net.netfilter.nf_conntrack_tcp_loose = 1
net.ipv4.netfilter.ip_conntrack_tcp_loose = 1
# reduced
net.netfilter.nf_conntrack_tcp_timeout_established = 86400
net.ipv4.tcp_ecn = 0
我以前从未遇到过这个问题。虽然受众相同,内核版本较早,硬件不同(这是一个虚拟服务器),数据中心也不同。
我的“煤矿中的金丝雀”报告显示,从他们的角度来看,他们在他们的Windows XP电脑上看到了超时和无回复,但如果通过设置为代理的Linux机器进行,则不存在这种情况。因此,他们正在调查这个问题。然而,无论他们得出什么结论,我都不确定为什么我可以嗅探来自端口80的入站SYN数据包,但没有在同一接口上发送出去的后续回复数据包。