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

时间:2013-07-21 06:43:22

标签: tcp nginx linux-kernel

我有一个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数据包。他们可以毫无损失地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的数量,它每隔几秒就找到一些(因为我们沿着累积的从未回复的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

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

我的“煤矿中的金丝雀”报告说,从他们的角度来看,他们看到了他们的XP机器上的超时和缺乏回复,但是如果它通过Linux机器设置作为代理。所以他们正在研究这个问题。然而,无论他们的结论如何,我都不确定为什么我可以将传入的SYN数据包嗅到端口80而没有后续的回复数据包在同一个接口上发送。

2 个答案:

答案 0 :(得分:1)

基于此处的信息

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数据包

答案 1 :(得分:0)

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

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