如何使用mosh连接位于NAT后面的服务器

7
我希望通过mosh连接到我的在NAT后面的服务器。我不能接触路由器以设置它为upnp支持,但我已申请UDP端口转发9807->60000和ssh端口转发。

那么,有没有办法在客户端和/或服务器端通过命令行参数或配置文件指定服务器端口?

注意:以下方法不起作用!

mosh -p 9807 user@my_server

编辑:

我首先尝试通过ssh连接到我的服务器,然后在另一个终端中手动运行mosh-server -p 60000,再运行mosh -p 9807 my_server。这导致了一个错误:

Error binding to IP my_server_ip: bind: Address already in use

话虽如此:

  1. 端口转发正在工作。
  2. MOSH试图在60000端口安装mosh-server。

谢谢。

2个回答

7
你遇到的问题出在端口重定向上。路由器上的NAT转发将发送到<domain>:9807的入站流量发送到<internal-ip>:60000。当你使用-p选项启动mosh时,客户端通过ssh连接到服务器并告诉服务器要开始监听指定的端口。然后,mosh-server会将打开的端口号(在本例中是您指定的端口)传递回客户端,客户端关闭ssh连接并尝试连接到<domain>:<port>。客户端正在尝试与服务器侦听的相同端口进行通信。问题在于你的NAT路由器正在将来自WAN侧的一个端口的流量重定向到NAT'd机器上的另一个端口。这样做是行不通的。
最好的方法是获得直接的翻译,例如请求路由器将WAN侧的端口9807转发到mosh-server机器的端口9807。
如果这不是一个选择,我能想到的下一个最好的方法是使用iptables在服务器机器上操纵流量。
iptables -t nat -A PREROUTING -p udp --dport 60000 -j REDIRECT --to-port 9807

执行您所描述的客户端
mosh -p 9807 user@my_server

所发生的是:
1.您机器上的mosh客户端打开了一个ssh连接(可能通过NAT路由器转发到您的机器),连接到在端口9807上监听的mosh服务器。 2.mosh服务器退出,告诉通过ssh连接的客户端要连接的UDP端口是9807。 3.mosh客户端关闭ssh连接,并尝试在端口9807上连接服务器。 4.NAT路由器看到这个进入端口9807的流量,并将其发送到您服务器的端口60000。 5.您的机器通过UDP在端口60000接收到数据包,匹配iptables规则并被重定向到其目标(在此情况下为服务器IP),但在端口9807上。 6.客户端流量的源端口未受到NAT路由器的更改,因此mosh-server将数据包回传到客户端正在侦听的端口,从而正确接收到数据包。

这对我没有用。我该如何撤销您提供的iptables命令? - Bunny Rabbit
-A 标志用于追加规则,而相反的是使用 -D 删除规则。请尝试执行 iptables -t nat -D PREROUTING -p udp --dport 60000 -j REDIRECT --to-port 9807 命令。 - MeanderingCode

3

让我提出以下用于连接NAT后面的mosh服务器的概念验证方法。假设我们有以下计算机:

  • client_host 位于NAT后面,我们想要从中连接到mosh服务器
  • server_host 位于另一个NAT后面,mosh服务器正在运行。请注意,在这种方法中,client_host仍然需要直接访问server_host来启动mosh服务器。服务器上的ssh -R ... relay_host可能会有所帮助。
  • relay_host 具有公共可见的IP地址,并且可以由我们控制。

所以我们进行以下操作:

  1. On relay_host install and run udprelay tool. It repeats everything it receives from one port to another and vice versa.
    relay_host> udprelay 0.0.0.0 34730 34731
    

    Port numbers mentioned above are hardcoded into the client script, but they could be easily changed. Also note, that udprelay is dramatically insecure at the moment.
  2. On server_host install mosh-nat-server.sh, just put it to any folder mentioned in PATH. Make sure that popular socat tool is also installed there.
  3. Finally, on the client, run mosh-nat-client.sh as follows
    client_host> mosh-nat-client.sh SERVER_SSH_NAME RELAY_IP
    

    This script calls server_host with ssh SERVER_SSH_NAME <mosh-nat-server.sh ARGS>, records the key and uses it to run the mosh-client. The tricky part of it is to punch a hole in server's NAT and let both sides met at udprelay.

请参考这篇不错的博客文章,它描述了稍微不同的情况。在上述术语中,它展示了如何从relay_host连接到server_host。作者没有使用UDP中继,但仍然需要笨重的LD_PRELOAD机制。出人意料地,它完成了它的工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接