pwnat

pwnat

我想在我的周末小屋里部署一个 Raspberry Pi。Raspberry Pi 可以记录温度并将其发送到具有固定 IP 的远程服务器,保存数据并将其显示在一个简单的网站上。

然而,有时我想在 Raspberry Pi 上做些更改。例如系统更新或更改将数据发送到服务器的程序等。

使用建议的设置,我将无法从其 LAN 外部连接到 Raspberry Pi。

笔记:我不想改变网络,现有的路由器没有端口转发、dynDNS 或 VPN 功能。

我最近读了 UDP 打洞技术。基本思想是,客户端将 UDP 包发送到已知服务器地址(即启用了公共 IP 或 dynDNS)。想要连接到客户端 A 的客户端 B 向服务器询问客户端 A 的公共 IP 和端口号。

然后它可以直接通过其动态的公共 IP 和端口连接到客户端 A。由于客户端 A 首先通过现在使用的端口连接到服务器,因此 NAT 会将数据包转发给客户端 A。

我希望我或多或少正确地总结了这个想法......

这一切听起来不错,但问题是,这不能保证与 TCP 连接一起工作,因为路由器能够“理解” TCP 连接的握手,如果没有正确建立,它将不会转发数据包。

那么,我如何才能打开从客户端 B 到客户端 A 的 SSH 会话,而客户端 A 无需位于具有 dynDNS、固定公共 IP 或端口转发功能的路由器后面?使用具有公共、固定 IP 或域名的中央服务器可能会很困难。

答案1

pwnat


“...建立与NAT 后面的对等体。

“..几乎全部NAT实现拒绝转发入站流量这并不对应于最近匹配的出站请求。


“..这pwnat工具是一种仅限 GNU/Linux,独立实施自主 NAT 穿越。联系NAT 后面的服务器,它建立了一个渠道TCP 语义,使用UDP 数据包。它支持两者NAT 后面的客户端和服务器(如果其中一个 NAT 允许假[自定义] ICMP发送消息)。此实现以最终用户为目标。


  
用法:./pwnat <-s | -c> <args>

  -c 客户端模式
    <args>: [本地 ip] <本地端口> <代理主机> [代理端口 (def:2222)] <远程主机> <远程端口>

  -s 服务器模式
    <args>: [本地 ip] [代理端口 (def:2222)] [[允许的主机]:[允许的端口] ...]

  -6 使用 IPv6  
  -v 显示调试输出(最多 2 个)  
  -h 显示帮助并退出  

例子:  

    服务器端允许任何人代理:
      ./pwnat -s

    客户端想要连接到 google.com:80:
      ./pwnat -c 8000 <pwnat.server.com> google.com 80
    然后,浏览http://localhost:8000 访问google!  


pwnat;网络信号流图


“实现服务器了解客户端的 IP 地址是为了服务器定期向固定的、已知的 IP 地址发送消息。最简单的方法是使用 ICMP ECHO REQUEST 消息未分配的 IP 地址,例如 1.2.3.4。由于 1.2.3.4 未分配,因此 ICMP 请求没有默认路由的路由器将不会对其进行路由。

“由于向 1.2.3.4 发送了消息,NAT 将启用回复路由,作为响应对此请求。连接然后客户端就会伪造这样的回复。具体来说,客户端将发送一个 ICMP 消息,表明TTL_EXPIRED。任何互联网路由器都可以合法地发送这样的消息,并且发送方地址预计与服务器的目标 IP 不匹配。

服务器监听(假的)ICMP回复收到后,启动与发送方 IP 的连接ICMP 回复中指定。如果客户端使用全局可路由的 IP 地址,这完全没有问题,而且TCP 或 UDP 可用于建立双向连接如果客户倾听预先约定的港口。

“(在没有预先商定港口的情况下,大多数情况下,端口号可以作为有效载荷的一部分进行通信的 ICMP ECHO RESPONSE)。


来源:http://samy.pl/pwnat.pdf
https://github.com/samyk/pwnat

答案2

以下是几个解决方案:

您可以设置您的 Raspberry Pi 以重新连接到 OpenVPN 服务器,并且您将可以随时访问它。

您可以查看 PageKite。检查https://pagekite.net/wiki/Howto/SshOverPageKite/

答案3

这是一个有点肮脏但简单的解决方案,但是使用 netcat 怎么样?在 Raspberry Pi 上,您可以创建一个循环执行以下命令的脚本:

nc <public_ip> <port1> | sh | nc <public_ip> <port2>  

在本地主机上执行以下操作:

nc -l <port1>

和:

nc -l <port2>  

您将能够在第一个实例中键入命令,并在第二个实例中看到响应。

相关内容