某些网站上的随机TCP RST,这是怎么回事?


34

短版:连接到某些网站时,我网络上的一台Windows Server 2012计算机正在出现持久性但间歇性的TCP RST。他们来自哪里的邓诺。查看wireshark日志以获取我的分析和问题。

长版:

我们在其中一台服务器上运行缓存Web代理,以为我们的小型办公室提供服务。一位同事报告说,连接到某些站点时出现很多“连接重置”或“页面无法显示”错误,但是刷新通常可以解决此问题。

我验证了浏览器的行为,然后通过尝试在服务器本身上使用未代理的浏览器来更直接地进行验证。但是到麻烦站点的ping和traceroutes没有显示任何问题,问题似乎仅限于TCP连接。

然后,我编写了一个脚本来测试受影响的站点,方法是直接通过cURL向它们发送HTTP HEAD请求并检查它们成功的频率。典型的测试如下所示:(这是未代理的,直接在不良服务器上运行)

C:\sdk\Apache24\htdocs>php rhTest.php
Sending HTTP HEAD requests to "http://www.washingtonpost.com/":
20:21:42: Length: 0     Response Code: NULL (0%)
20:22:02: Length: 0     Response Code: NULL (0%)
20:22:22: Length: 0     Response Code: NULL (0%)
20:22:42: Length: 0     Response Code: NULL (0%)
20:23:02: Length: 3173  Response Code: HTTP/1.1 302 Moved Temporarily (20%)
20:23:22: Length: 3174  Response Code: HTTP/1.1 302 Moved Temporarily (33.33%)
20:23:43: Length: 0     Response Code: NULL (28.57%)
20:24:03: Length: 3171  Response Code: HTTP/1.1 302 Moved Temporarily (37.5%)
20:24:23: Length: 3173  Response Code: HTTP/1.1 302 Moved Temporarily (44.44%)
20:24:43: Length: 3172  Response Code: HTTP/1.1 302 Moved Temporarily (50%)
20:25:03: Length: 0     Response Code: NULL (45.45%)

从长远来看,只有大约60%的请求成功,其余请求均不返回任何内容,其卷曲错误代码为:“ cURL错误(56):从对等方接收数据时失败”对于我我的网站而言,不良行为是一致的测试(从来没有一个站点能够“变得更好”),并且它非常持久,我已经进行了一周的故障排除,并且同事报告说问题已经存在了几个月。

我在网络上的其他计算机上测试了HEAD请求脚本:没问题,所有连接都通向测试列表中的所有站点。然后,我在个人桌面上设置了一个代理,当我从有问题的服务器运行HEAD请求时,所有连接都会通过。因此,无论问题出在哪里,它都非常特定于此服务器。

接下来,我试图隔离哪些网站表现出连接重置行为:

  • 我们的Intranet站点(192.168.xx)均未断开连接。
  • 我测试过的ipv6站点均未断开连接。(我们是双堆栈)
  • 互联网ipv4站点中只有一小部分断开连接。
  • 每个将cloudflare用作CDN(我已经测试过)的站点都会断开连接。(但问题似乎并非仅是cloudflare网站所独有)

这个角度并没有真正起任何作用,因此接下来我安装了wireshark来查看请求失败时的情况。失败的HEAD请求看起来像这样:(此处的更大屏幕截图:http : //imgur.com/TNfRUtX

127 48.709776000    192.168.1.142   192.33.31.56    TCP 66  52667 > http [SYN, ECN, CWR] Seq=0 Win=8192 Len=0 MSS=8960 WS=256 SACK_PERM=1
128 48.728207000    192.33.31.56    192.168.1.142   TCP 66  http > 52667 [SYN, ACK, ECN] Seq=0 Ack=1 Win=42340 Len=0 MSS=1460 SACK_PERM=1 WS=128
129 48.728255000    192.168.1.142   192.33.31.56    TCP 54  52667 > http [ACK] Seq=1 Ack=1 Win=65536 Len=0
130 48.739371000    192.168.1.142   192.33.31.56    HTTP    234 HEAD / HTTP/1.1 
131 48.740917000    192.33.31.56    192.168.1.142   TCP 60  http > 52667 [RST] Seq=1 Win=0 Len=0
132 48.757766000    192.33.31.56    192.168.1.142   TCP 60  http > 52667 [ACK] Seq=1 Ack=181 Win=42240 Len=0
133 48.770314000    192.33.31.56    192.168.1.142   TCP 951 [TCP segment of a reassembled PDU]
134 48.807831000    192.33.31.56    192.168.1.142   TCP 951 [TCP Retransmission] http > 52667 [PSH, ACK] Seq=1 Ack=181 Win=42240 Len=897
135 48.859592000    192.33.31.56    192.168.1.142   TCP 951 [TCP Retransmission] http > 52667 [PSH, ACK] Seq=1 Ack=181 Win=42240 Len=897
138 49.400675000    192.33.31.56    192.168.1.142   TCP 951 [TCP Retransmission] http > 52667 [PSH, ACK] Seq=1 Ack=181 Win=42240 Len=897
139 50.121655000    192.33.31.56    192.168.1.142   TCP 951 [TCP Retransmission] http > 52667 [PSH, ACK] Seq=1 Ack=181 Win=42240 Len=897
141 51.564009000    192.33.31.56    192.168.1.142   TCP 951 [TCP Retransmission] http > 52667 [PSH, ACK] Seq=1 Ack=181 Win=42240 Len=897
143 54.452561000    192.33.31.56    192.168.1.142   TCP 951 [TCP Retransmission] http > 52667 [PSH, ACK] Seq=1 Ack=181 Win=42240 Len=897

我的阅读方式(如果我错了,请纠正我,这实际上不是我的专长)是:

  • 我们打开到Web服务器的TCP连接
  • 网络服务器ACK
  • HTTP HEAD请求已发送
  • 有一个RST数据包(标记为来自Web服务器IP)终止了连接。
  • Web服务器发送ACK
  • Web服务器(尝试)以有效的HTTP数据响应HEAD请求(951字节的回复包含正确的HTTP标头)
  • Web服务器重新传输(几秒钟的几次)有效的HTTP响应,但是由于连接已经是RST,所以它无法成功

因此,如果网络服务器发送了有效的RST,为什么它会继续尝试填充请求?如果Web服务器没有生成RST,那么到底发生了什么?

我尝试过的事没有任何效果:

  • 禁用NIC分组
  • 更换网络适配器(已知替换网卡正在工作)
  • 分配静态IP。
  • 禁用ipv6。
  • 禁用巨型帧。
  • 一晚上将服务器直接插入我们的调制解调器,绕过我们的交换机和路由器。
  • 关闭Windows防火墙。
  • 通过netsh重置TCP设置
  • 实际上禁用服务器上的所有其他服务。(我们通常将它用作文件服务器,但是有apache和几个DB)
  • 在桌子上敲头(反复)

我怀疑服务器上的某些东西正在生成RST数据包,但是对于我来说,我找不到它。我感觉是否知道:为什么仅此服务器?还是为什么只有一些网站?这会很有帮助。虽然我仍然很好奇,但我越来越倾向于从轨道上退出并重新开始。

想法/建议?

-谢谢


此缓存代理服务器运行什么操作系统?什么是代理服务器软件?
迈克尔·汉普顿

1
服务器正在运行Windows Server 2012,代理是通过cygwin运行的squid 3.3.3;但这会发生在计算机上的所有TCP连接上,而不仅仅是代理服务器的连接上。curl测试脚本是未代理的。
莫蒂2014年

Answers:


38

您的数据包捕获有一些异常:ECN位在传出SYN数据包中设置。

显式拥塞通知是IP协议的扩展,允许主机对网络拥塞做出更快的反应。它是15年前首次引入Internet的,但是在首次部署时却注意到了严重的问题。其中最严重的是,许多防火墙在收到设置了ECN位的SYN数据包时要么丢弃数据包,要么返回RST

因此,大多数操作系统默认情况下至少在传出连接上禁用了ECN。结果,我怀疑很多站点(和防火墙供应商!)根本就没有修复过他们的防火墙

直到Windows Server 2012发布。默认情况下,Microsoft从此操作系统版本开始启用 ECN

不幸的是,最近没有人对Internet站点对ECN的响应进行任何重大测试,因此很难评估在2000年代初仍然存在的问题,但是我强烈怀疑它们是否存在,并且您的访问量至少有时会经过此类设备。

在桌面上启用ECN并启动Wireshark之​​后,仅几秒钟,我就捕获了一个主机示例,从该主机中我获得了RST到设置了SYN和ECN的数据包,尽管大多数主机似乎都可以正常工作。也许我自己去扫描互联网...

您可以尝试在服务器上禁用ECN,以查看问题是否消除。这也将使您无法使用DCTCP,但是在小型办公室中,您这样做或有任何必要的可能性很小。

netsh int tcp set global ecncapability=disabled

4
谢谢!禁用ECN后,我看到连接到最麻烦站点的成功率是100%!在重新打开代理之前,我必须在早上进行更多测试,但是我将继续将此做为已回答的问题,并将其标记为Microsoft QA对用户的持续战争中的又一次重大胜利。
莫蒂2014年

9
公平地说,我认为某些防火墙管理员是白痴不是微软的错。ECN非常好,因为它确实有很大帮助,如果有一天大家都能开始使用它,那将是很好的。
迈克尔·汉普顿

哦,我不知道这是否可以解释我多年来从Imgur和Wikia获得的大量重置(发生于两个不同的本地ISP,但是从来没有在VPN通过另一个国家/地区时,这使我感到困惑)
令人遗憾的2014年

怀疑(但显然无法证明)某些负责此操作的机器潜伏在默认自由区域中。
迈克尔·汉普顿
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.