在流量较高的ubuntu 12 nginx服务器上忽略了SYN数据包



我有一台ubuntu 12.04服务器,端口80 上有nginx

只有一个防火墙规则,它与端口映射端口26到25 有关

nginx被设置为在端口80上侦听,最初是以一种相当默认的方式,但现在使用

listen x.x.x.x:80 backlog=5000;

nginx没有那么加载,每秒大约有50个请求显示nginx_status

Active connections: 480 
server accepts handled requests
84618 84618 143733
Reading: 0 Writing: 4 Waiting: 474                                                                                                                    

一些(极少数的百分比)用户抱怨他们的一台电脑(例如"它只发生在家里")的SYN数据包似乎被忽略了。他们可以毫无损失地打乒乓球有时他们会得到一些对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的数量,它每隔几秒钟就会找到几个(随着时间的推移,从未回复的TCP SYN数据包的累积数量稳步上升)。明显未报告SYN的比率约为1/2500。当我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

我以前从未遇到过这个问题,有相同的受众,早期的内核nginx,不同的硬件(这是一个虚拟服务器)。不同的数据中心。

我的"煤矿里的金丝雀"报告说,从他们的角度来看,他们在XP机器上看到了超时和缺少回复,但如果它通过linux机器设置作为代理,则不会。所以他们正在对此进行调查。然而,无论他们的结论是什么,我都不确定为什么我可以嗅探到端口80的传入SYN数据包,而不会在同一接口上发送后续的应答数据包。

基于此处的信息

https://serverfault.com/questions/235965/why-would-a-server-not-send-a-syn-ack-packet-in-response-to-a-syn-packet

关闭服务器上的TCP时间戳可以阻止从发送tsval设置为零的SYN数据包的Windows XP客户端丢弃SYN,并且服务器上未复制的SYN数量变为零并保持不变。

sysctl -w net.ipv4.tcp_timestamps = 0

我的理解是,启用时间戳时XP堆栈的行为是众所周知的,因为在linux列表中已经讨论过它与ipv4的关系,并且在某个时间点,启用tcp_timestamps的linux只是切换到与XP(或其他有缺陷的客户端)的非时间戳会话。这种行为似乎已经改变了,现在至少在繁忙的端口上,如果tcp_timestamps为1 ,则会丢弃tsval为0的SYN数据包

您的系统是否启用了三向同步检查?听起来像是在检查三方握手,但有些数据包没有通过检查,即使它们不是恶意的,也会被丢弃。

检查或发布所有配置和/或检查路由器/防火墙,因为此选项通常是默认设置的。

最新更新