7

我需要实现一个UDP协议。PC 必须在专用 UDP 端口上侦听传入数据包。它还发送数据包(答案)。该应用程序在 Windows XP、7、8、...上运行。

Windows 防火墙阻止传入的数据包。这可以通过 UDP 打孔来规避。所以我必须发送一些不应该伤害的东西。但我想尽量少打扰。

  • 在防火墙关闭漏洞之前,我如何确定超时?
  • 我可以检测到防火墙已关闭防火墙,以便我必须重新发送打开数据包吗?当然,当防火墙关闭时我不会收到任何东西,但这可能有其他原因。
4

3 回答 3

4

这是我使用 netcat 测量的方法:

在我的 Unix 主机(Mac OS X Darwin)上,没有防火墙(或在 Windows 机器上,Windows 防火墙允许 netcat "nc" 可执行文件侦听 UDP 端口),我运行远程客户端提供的具有可变延迟的 UDP 服务器:

WINHOST=10.116.140.69
mkfifo f
nc -u -p 2222 $WINHOST 6666 < f | \
(while read secs; do for sec in $secs; do echo sleep $sec 1>&2; sleep $sec; echo SLEPT $sec; echo SLEPT $sec 1>&2; done; done) > f

在我的 Windows 主机(Windows 7 Professional SP1 64 位)上,安装了 cygwin 以提供 shell 和 netcat 的 Windows 防火墙,我以交互方式运行 UDP 客户端:

UNIXHOST=192.168.181.1
nc -u -p 6666 $UNIXHOST 2222

您不必使用 cygwin;Windows netcat 应该可以正常工作,但命令行可能会有所不同。

然后在该客户端中输入一系列测试间隔,观察服务器睡眠然后响应,观察客户端是否得到响应。这些工作:1、2、10、60、120、180。然后失败:240。继续在 180 和 240 之间进行二进制搜索。

示例 1:在客户端,我输入:

10
60
120
180
240

并观察到 ​​180 的请求响应延迟有效,240 无效。

示例 2:在客户端,我输入:

180
181
182
182

并观察到最多 181 的请求-响应延迟有效,而 182 则无效。

示例 3:在客户端,我输入(都在同一行):

180 180 180 181 181 181 182 182 182 183 183 183

它从客户端生成一个 UDP 请求,然后是一系列以 180、181、182 或 183 秒为间隔的响应。据观察,最多 181 秒的请求-响应延迟有效,此外,间隔高达 181 秒的持续响应(没有新请求)也有效。

所以防火墙漏洞有一个不活动计时器,不管不活动是初始响应延迟,还是后续的额外流量。

多台机器上的结果:

  • 在那个 Windows 7 Professional SP1 64 位桌面上,UDP 响应漏洞打开了 181 秒。有可能我也在测量两个系统之间的网络防火墙,因为它们位于不同的网络上——但我认为它们的路由没有防火墙。无论如何,这个系统上的 Windows 防火墙漏洞至少是 181 秒。
  • 另一台 Windows 7 Professional SP1 64 位笔记本电脑,同一网段(因此绝对没有干预防火墙),UDP 响应孔打开 64 秒。

我有兴趣在不同操作系统级别和防火墙配置的其他 Windows 机器上看到类似的测量结果。

于 2014-02-20T16:58:59.993 回答
2

关于打孔的一些技巧:

  1. 在大多数防火墙(我也假设是 Windows 防火墙)上,打孔只允许特定 IP 连接。打孔会诱使防火墙/NAT 认为您正在与特定 IP 进行通信,因此它允许从该 IP 返回的数据包。如果您想收听任何 IP,那么如果没有可以协调连接的桥接计算机,您将无法使用打孔。
  2. 防火墙和/或 NAT 之间的时间可能会有所不同。您不仅需要担心软件防火墙(如 Windows 防火墙),而且如果有硬件防火墙和/或 NAT 设备,那么您还必须担心时间安排。除非您有非常特定的网络和软件设置,否则硬编码一个值是行不通的。检测防火墙已关闭漏洞听起来是个好主意,但大多数防火墙/NAT 无法让您检测到它们已关闭漏洞,据我所知,您没有好的方法程序来检测它。
  3. 要进行打孔,您将不得不发送没有功能的数据包。它们通常是没有目的的 NOP(无操作)或 KEEP_ALIVE 数据包,如果程序收到一个,它就会丢弃它。

我的建议是实现客户端程序忽略的 KEEP_ALIVE 数据包,并让服务器定期向客户端发送 KEEP_ALIVE 数据包以保持防火墙打开。这假设您知道客户端的 IP,因此您可以向其发送 KEEP_ALIVE 数据包。如果您还不知道客户端的 IP,那么您要么必须设置一个可公开访问的桥接计算机,要么为您的服务器程序禁用防火墙。Windows 防火墙有一个 COM API 或 netsh 命令,您可以使用它们让您的程序侦听连接。对于硬件防火墙/NAT,您可以尝试使用 UPNP。如果这不起作用,那么您能做的最好的事情就是请求用户为您的程序打开一个特定的端口。

于 2013-02-23T18:08:52.163 回答
1

To answer my own question: there is no way to determine the timeout. You need to experiment which timeout the Windows 7 firewall uses for UDP connections. The current experience shows a four second timeout but this may vary.

Some general tips for hole punching:

  1. Don't disturb any other host in the network. Send a packet with a content that doesn't hurt.
  2. It is not necessary to send to the host you want to be the sender of your response.
  3. It is not necessary to send to the UDP port you want to be the sender. Send to any UDP port. There is a discard port (9) that should ignore anything what you send.
  4. Make sure you packet is really sent. If you try to send to a host that has not been seen in the last time, the IP stack will use the ARP protocol to get the MAC address. If the IP stack doesn't get an ARP response, it can't send and IP packet and no hole is punched. This problem can be circumvent by sending to the network broadcast address.
  5. Make sure you punch the hole to the wanted network using the right adapters' broadcast address.
于 2013-02-23T19:25:41.697 回答