【问题标题】:UDP hole punching timeoutUDP打孔超时
【发布时间】:2013-01-29 04:21:07
【问题描述】:

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

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

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

【问题讨论】:

    标签: windows-firewall hole-punching


    【解决方案1】:

    这是我使用 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 机器上查看不同操作系统级别和防火墙配置的类似测量结果。

    【讨论】:

    • 这太棒了!像这样的回应让 SO 如此不可思议。我本可以花相当多的时间来制作和重新创建功能等效的东西,但现在我不必这样做了。谢谢,柳德维卡斯
    • 新访问者,不要忘记禁用您的 Linux/Unix 防火墙,否则将无法正常工作。
    【解决方案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。如果这不起作用,那么您能做的最好的事情就是请求用户为您的程序打开一个特定的端口。

    【讨论】:

    • 感谢您的文字。但不幸的是,您错过了如何知道洞何时打开或关闭的问题。
    【解决方案3】:

    回答我自己的问题:没有办法确定超时。您需要试验 Windows 7 防火墙用于 UDP 连接的超时时间。目前的经验显示超时时间为 4 秒,但这可能会有所不同。

    打孔的一些一般技巧:

    1. 请勿打扰网络中的任何其他主机。发送一个内容无伤大雅的数据包。
    2. 不必发送到您希望成为响应发送者的主机。
    3. 不必发送到您想成为发送者的 UDP 端口。发送到任何 UDP 端口。有一个丢弃端口 (9) 应该忽略您发送的任何内容。
    4. 确保您的数据包确实已发送。如果您尝试发送到上次未见过的主机,IP 堆栈将使用 ARP 协议获取 MAC 地址。如果 IP 栈没有得到 ARP 响应,它就不能发送 IP 数据包,也不会打洞。这个问题可以通过发送到网络广播地址来规避。
    5. 确保使用正确的适配器的广播地址在所需网络上打洞。

    【讨论】:

    • “不必发送到您想成为发送者的 UDP 端口” - 取决于 NAT 类型。 Restricted Cone NAT 是这样,但 Port Restricted Cone NAT 不是这样。
    • @LeonidMalyshev 您已经读到问题是关于 Windows 防火墙而不是任何 NAT,不是吗? Windows 防火墙不执行地址转换,因此根本没有 NAT 类型。
    猜你喜欢
    • 2011-06-14
    • 2014-10-17
    • 2019-04-11
    • 2012-11-30
    • 2019-01-13
    • 2011-06-05
    • 2012-02-26
    • 2011-10-11
    • 2012-02-12
    相关资源
    最近更新 更多