2

内网访问第三季:在运营商的CGNAT网络下

 1 year ago
source link: https://blog.heysh.xyz/2023/05/10/through-nat/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

内网访问第三季:在运营商的 CGNAT 网络下

是的,在这次这次之后,在酒店里百无聊赖的现在,我又开始折腾起 VPN 来了。

是的,在酒店里仍然没有 IPv6 地址。

正如前文所述,无论是 Tailscale/Headscale、Nebula 或 Netmaker,原理均大同小异,都是在 Wireguard 基础上,用类 STUN 协议来穿越 NAT,或利用 TURN(DERP)服务器进行转发。在国内家庭宽带网络环境下,一般存在路由器、光猫、运营商三重 NAT 防火墙,STUN 需要跨越多重阻碍,自动穿越希望渺茫;另一方面,公开转发服务多在国外,延迟高居不下,而国内私有云价格亦是高不可攀,自建服务并非经济的选择。

然而,三重 NAT 也并非坚不可摧。光猫一级,只要改为桥接,便可迎刃而解;路由一级,可以通过端口映射来绕过;而运营商级多为 NAT1,通过 Natternatmap,可以获得近似公网的效果。这样,使用纯粹的 Wireguard,也能够直接回到家庭网络内部,免去国外中转的烦恼。

从广东联通到北京联通。

从广东联通到北京联通。

从广东联通经北京联通到甘肃移动。个人觉得,在这种延迟下追求Full Mesh也不再重要了。

从广东联通经北京联通到甘肃移动。个人觉得,在这种延迟下追求 Full Mesh 也不再重要了。

在开始之前,首先检查是否满足以下要求:

  1. 一台长期开启的设备。

    既然有远程访问的要求,远处有一台服务器是很自然的吧。

  2. 光猫处于桥接状态。
  3. 主路由是 OpenWRT,或者内网里有 DMZ 主机。

    或者,你是端口转发专家,可以从光猫外侧一路转发到最内部。

  4. 没有公网 IPv4,但在路由器处测试 NAT 类型为 NAT1。

    这里可以用 Natter 自带的功能来测试。如果你有公网 IPv4 的话,直接打开端口就好,而且我会很羡慕你。

  5. 一个自己的域名,最好是在 Cloudflare 上托管的。

    需要 DDNS 功能实时更新域名。如果没有域名的话,可能需要一些别的手段来实时得到端口。

具体配置部分已经有人写的很详细了。首先按照 WireGuard Point to Site Configuration 设置点到站点的连接,然后按照 natmap Wiki 设置 NATMap 即可。注意,在路由器上操作的时候,一定要记得在防火墙中打开对应端口

完成以上步骤之后,应该已经可以从移动网络访问内网的 Wireguard Peer 了。

由于运营商网关不受我们控制,外网的 IP 和端口号都是随机分配的,每当地址变化时,NATMap 将执行自定义脚本。在上面的 Wiki 中,利用 DDNS,把 IPv4 地址和端口编码进 IPv6 的 AAAA 记录中。这并不是一种标准的技术,不过既然 2001:: 就是给 teredo 使用的,在这里随便用用也无所谓。

对于 Windows 下的 Wireguard 客户端,我(和 ChatGPT 一起)写了一个 PowerShell 脚本,能够自动修改配置文件的 Endpoint 并调用 wireguard.exe 进行连接。

使用方法:

  1. 安装 wireguard-windows,用客户端连接测试成功。
  2. 在文件夹 C:\example 下建立 wg.ps1nat.conf,粘贴 Gist 内容。
  3. 按照实际情况修改 nat.conf,以及 wg.ps1$Hostname 部分。Endpoint 不必修改。
  4. 以管理员身份运行 PowerShell
  5. 设置 ps1 脚本运行权限:Set-ExecutionPolicy RemoteSigned(或 Unrestricted)
  6. 启动、重启 Wireguard:C:\example\wg.ps1 -up
  7. 停止 Wireguard:C:\example\wg.ps1 -down

在 Windows 11, Powershell 5.1.22621.963 测试通过,也可以配合 Windows 下的 sudo 使用。

另外,在 Android 下,也可以用 termux 运行 nm-echo.sh 来获得 IP 地址,手动修改 Wireguard 官方客户端中的 IP。

我这里最近一次分配的端口坚持了18天,所以应该不必时常刷新。

我这里最近一次分配的端口坚持了 18 天,所以应该不必时常刷新。

如果需要更为稳定的访问,可以参考 reresolve-dns.ps1,这个脚本可以在上一次握手时间过久时刷新 DNS,但是因为要添加计划任务,有一点过于复杂了。

Bonus

Natmap 的另一种用法是映射 BT 客户端,从而使外来连接能够主动发起连接,获得所谓的 High ID。见 wits-fe/bittorrent-NAT-hole-punching。在 PT 站做种的时候应该会很有用。

附:性能测试

随便找了一个公共 WiFi,用手机(一加 7T)上 Termux 中的 iperf3 测速。

由于多层 NAT 的限制,Nebula 类组网工具必须部署在路由器位置。可以看出,对路由器(万元级,K3)带来的压力还是比较大的。

WireGuard for Android

WireGuard for Android

NB4A提供的Wireguard Outbound

NB4A 提供的 Wireguard Outbound

Nebula,对端部署在路由器上

Nebula,对端部署在路由器上

很难想象,对于访问内网这样一个简单的需求,我居然花费了如此多的精力。不过,这次应该算是当前比较满意的方案,应该能坚持到下次水逆开始。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK