Document ID: /fineweb-2-swissfilter-quality_10-filterrobots/filtered/06243.jsonl.gz/61

由于经常要从宿舍、教室等不同的 Wi-Fi 之间切换，但是 ssh 连接又总是断，所以想用 mosh 代替 ssh 。但是 mosh 也有它的问题：
- 不能滚动。这个可以在 mosh 中嵌套一层 tmux 解决。我目前写了一些自动 mosh 后打开 tmux 并且开启鼠标支持的脚本，但还是有缺陷。
- 在高端口 60000+ 监听 UDP ，这使得 NAT 后的服务器难以直接通过端口转发。如果直接转发到 NAT 后的机器，那么 NAT 后面如果有多台机器，这又失效了。
于是找了找网上的 NAT 穿透的一些文章，看到了 UPnP 的方法。大致就是，用户可以向路由器注册一个临时的转发规则，路由会自动在 iptables 上配置转发。但是，这样也会遇到一个问题：路由上的 mosh-server 不知道这个转发的存在，所以它可能会尝试监听同样的端口。解决方案下面会提到。
需求：
Server <---> NAT Router <---> My Laptop On NAT Router, port 8022 is forwarded to Server:22 1. mosh router # works 2. mosh --ssh="ssh -p 8022" router # works
首先在 NAT Router 上配置 miniupnpd （以 Debian 为例）
sudo apt install miniupnpd # you will get a dialog upon installation # input your wan interface and listening ip accordingly sudo vim /etc/default/miniupnpd # edit START_DAEMON=0 to START_DAEMON=1 sudo vim /etc/miniupnpd/miniupnpd.conf # edit ext_ifname, listening_ip accordingly # set secure_mode=yes # add 'allow 60000-60023 internal_ip/prefix 60000-60023' # before the last line 'deny 0-65535 <ip-pii>/0 0-65535' sudo systemctl enable --now miniupnpd
现在，复制 我修改的mosh-wrapper.js 到用户的 home 目录下，在 Server 安装
miniupnpc 然后通过：
mosh --ssh="ssh -p 8022" --server=~/mosh-wrapper.js user@router
这样， mosh 首先会通过 ssh 和 Server 协商一个 AES 的密钥和 UDP 端口（如 60001 ），之后的通信都通过 UDP 端口走加密后的流量。我的
mosh-wrapper.js 通过
miniupnpc 向路由器请求把该 UDP 端口转发到 Server 上，这样，
mosh-server 就能通过 NAT 路由穿透到后面的 Server 上。
等会！问题来了：
mosh 默认的 IP 范围是
60000-61000 ，根据我的观察，它会从 60001 开始尝试监听本机地址，如果已经被占用，则 60002, 60003, … 但是！Router 和 Server 实际上占用了相同的端口空间，并且
mosh 只知道本机哪些端口被占用了，而不知道 Router 和 Server 共同占用了多少端口。
我想到了一些可能的解决方案：
- 在 Router 上让 miniupnpd 监听对应的端口，占住这个坑。这样，Router 上的
mosh-server就不会用和 Server 相同的端口
- 如果有多个 Server ，则会出现抢夺相同端口的情况。我目前的想法是，让
upnpc去询问 Router 找空闲的端口，然后再传给
mosh-server使用。另一种方法则是，给不同的 Server 划分不同的端口范围，比如 Router 用 60001-60005, 然后 Server1 用 60006-60010, Server2 用 60011-60015 如此下去。
然后，新的问题又发现了：
当我在和 Server 同一个子网的时候，由于
miniupnpd 配置的
iptables 规则中来源只有 WAN interface ，所以我在内网发的包是不会被转发的。当然，既然在内网了，为啥不直接用内网 IP 呢，不知道
mosh 有没有提供设置备用 IP 的功能。
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.