情况是这样的:

http client ----> corporate firewall ----> http server

由于保持活动,服务器和客户端将保持TCP连接打开,并且客户端将对HTTP请求使用连接池。 。

防火墙有一个规则,可以在1小时后“杀死”长期的TCP连接。问题在于,我们的HTTP客户端无法检测到TCP连接已被破坏,并且它试图重用本质上无效的连接,而在我们这边,看起来好像客户端在一段时间后“挂起”。一个请求将挂起,然后下一个请求将起作用,大概是因为建立了新的连接。

这里的问题是防火墙以何种方式杀死HTTP连接的机制是HTTP?客户端无法检测到它们。我尝试通过以下几种方式在本地重现此行为:


在我们的vyos路由器上杀死TCP连接,客户端上的Wireshark捕获了TCP FIN-ACK。 OK
在Windows的TCPView中杀死TCP连接客户端,Wireshark在客户端检测到TCP RST。确定
与客户端防火墙建立连接后,阻止端口,导致套接字重置异常。 OK

我在服务器端进行了Wireshark转储,我尝试查找防火墙是否发送带有ip.dst==serverip && (tcp.flags.reset==1 || tcp.flags.fin==1)的FIN或RST,但未显示任何内容。

此外,Wireshark在客户端上捕获了侧面显示了该问题,原因是HTTP请求传出,然后进行了十几次TCP重传,最终都没传到任何地方。

HTTP客户端是Java本机和/或Jetty HTTP客户端(都尝试过),均失败检测无效的TCP连接。我想在本地重现该行为,但是我无法弄清楚防火墙以哪种狡猾的方式杀死了连接,因此寻找可能的答案。

评论

只需将数据包放在防火墙中即可,即不要将其转发到目标位置,也不要设置任何FIN,RST等。

您应该编辑问题以包括防火墙模型和配置(混淆所有密码和公共地址)。

“防火墙的规则是在1小时后'杀死'长期的TCP连接。”这听起来像是一个非常奇怪的防火墙规则。

@RonMaupin如果我知道它或可以访问它,我会已经

不幸的是,这里没有关于您无法直接控制的网络的问题。

#1 楼

您没有提到防火墙的种类,但是我怀疑最简单的就是丢弃数据包。


我在服务器端有一个Wireshark转储,我尝试查找是否有防火墙
使用ip.dst == serverip &&(tcp.flags.reset == 1 ||
tcp.flags.fin == 1)发送FIN或RST,但未显示任何内容。


倾向于证实这一点。

评论


不幸的是,由于防火墙是内部网络,所以我不知道有关防火墙的任何信息。有什么建议可以在本地(最好是客户端)重现吗?

–cen
17年11月28日在12:29



如果您的目标是创建测试台,则可以在PC上运行软件防火墙,或购买价格便宜的硬件防火墙。阻止连接似乎很简单。

–罗恩·托恩(Ron Trunk)
17年11月28日在14:12

#2 楼

防火墙很可能只是丢弃了该数据包而不发送RST数据包,可能是在达到某种会话超时值之后。这通常是可配置的行为。

我个人更希望发送RST数据包正是因为它可以帮助客户端正常运行,但我听到有人争辩说,不应在面向外部的防火墙上执行此操作避免向潜在的攻击者提供任何反馈。

我已经看到了很多原因,因为客户端通常不会非常优雅地处理这种情况。从本质上讲,他们会继续尝试通过原始TCP会话(现在已死),并且从不尝试重新建立一个新的TCP会话。最终,客户端超时触发,并且用户收到讨厌的错误消息。适当地为应用设置HTTP Keepalive可以帮助解决此问题。

评论


发送FIN或RST将要求防火墙实现跟踪连接上的序列号(因为它需要在FIN / RST数据包中填写该数据)。相比之下,“只是丢弃它”策略将意味着防火墙实现只需要存储4个元组并在1小时时间结束后将其杀死。

–mere3ortal
17年11月28日在16:14

我可以理解外部网络的原因,但是对于内部网络,这似乎是完全邪恶的。

–cen
17年11月28日在16:23

有条理地这样做是很邪恶的。如果该IP范围在该端口上没有任何监听,则仅将其完全丢弃。

–约书亚
17年11月28日在18:19

@Joshua,我完全同意这是邪恶的,恰恰是因为我必须修复由此造成的混乱。不过,对于足够偏执的SecOps团队,确实会发生这种情况...

–杰里米·吉本斯(Jeremy Gibbons)
17年11月30日在2:42

#3 楼

@Ron Trunk完全正确,几乎可以肯定,断开的连接是主动断开(插入了拒绝规则)还是被动断开(从已知连接中删除,并且不允许在没有syn的情况下重新创建)。评论之一建议您自己尝试一下。这是使用linux网络名称空间进行操作的方法。它假定已在主机的内核中启用了IP转发,并且您是root用户,并且可能还有其他事情。

然后您需要三个windows / shell / screens / terminals。在不同的终端上运行以下每个命令:


开始在服务器上监听:ip netns exec three socat TCP-LISTEN:5001 STDIO

开始在客户端上传输:ip netns exec one socat STDIO TCP:3.3.3.3:5001


请注意,运行这些命令后,您在一个窗口中键入的所有内容都会反映在另一个窗口中,反之亦然(单击return后)。如果不正确,则可能需要启用ip转发。


实例化拒绝规则:ip netns exec two iptables -I FORWARD -j DROP


那么您键入的内容将不会允许通过。

您可以使用(未​​试用的)转发规则模拟不太活跃的放置方法,例如:

# Create network namespacs
ip netns add one; ip netns add two; ip netns add three
# Create interfaces between namespaces
ip link add dev i12 type veth peer name i21
ip link add dev i32 type veth peer name i23
# Bring interfaces up and assign them to respective namespaces
ip link set dev i12 netns one up
ip link set dev i21 netns two up
ip link set dev i32 netns three up
ip link set dev i23 netns two up
# Assign IP addresses
ip netns exec one ip addr add 1.1.1.1/24 dev i12
ip netns exec two ip addr add 1.1.1.2/24 dev i21
ip netns exec three ip addr add 3.3.3.3/24 dev i32
ip netns exec two ip addr add 3.3.3.2/24 dev i23
# Add routes when necessary
ip netns exec one ip route add default via 1.1.1.2
ip netns exec three ip route add default via 3.3.3.2


请参见https:// unix.stackexchange.com/questions/127081/conntrack-tcp-timeout-for-state-stablished-not-working和https://www.kernel.org/doc/Documentation/networking/nf_conntrack-sysctl.txt上的信息如何调整超时-尽管我不清楚iptables本身是否支持最大连接寿命;我相信所有超时都是空闲超时。

使用ip netns del one; ip netns del two; ip netns del three
进行清理。

评论


主机/服务器/ VM配置不在此处。

–罗恩·莫潘♦
17年11月28日在19:58

@Ron Maupin:但是是否正在创建网络测试平台来测试网络工程理论?

–塞斯·罗伯逊(Seth Robertson)
17年11月28日在20:11

有些事情很热门,例如配置网络设备(路由器,交换机等),或使用诸如Pacet Tracer或GNS3之类的东西来模拟某些东西。配置主机/服务器/ VMS不在这里。它们及其操作系统的工作方式不是网络的一部分。 OP需要包括防火墙模型和配置,以便我们查看是否可以提供帮助。

–罗恩·莫潘♦
17年11月28日在20:19

#4 楼

防火墙可以发送指示目标不可达的ICMP数据包。对于除TCP以外的任何内容,这都是唯一可能的错误指示,例如,将数据包发送到关闭的UDP端口将生成“目标不可达”消息,且原因代码设置为“端口不可达”。

也可以发送“端口不可达”消息作为对TCP数据包的响应,这也会终止连接,但是任何分析数据包转储的人都会注意到这是不寻常的,因为TCP约定是使用RST指示关闭的端口。 />
发送者应将收到的所有ICMP错误数据包映射回原始连接并进行适当处理,因此防火墙生成的错误数据包也可以用于终止TCP连接。 ICMP数据包包含有问题的数据包的标头的副本,以允许此映射。