如何在 MacOS 10.14+ 上进行 IP 伪装?

如何在 MacOS 10.14+ 上进行 IP 伪装?

我正在寻找与 Linux 等效的 Macos 命令:

sudo iptables -t nat -A POSTROUTING -o en0 -j MASQUERADE

我想要这样做的原因是我有一个具有默认路由的 VPN,但我希望某些应用程序通过物理上行链路而不是 VPN。

使用pfctl我已经完成了以下工作:

pass out route-to (en0 192.168.4.1) group skipvpn flags any

我的网关的 IP 在哪里192.168.4.1,这似乎将skipvpn组中应用程序的所有数据包路由到en0接口(而不是隧道)。我使用以下方法验证了这一点tcpdump

但是,所有已重新路由的数据包的“源 IP”仍然具有 VPN 的源 IP(范围10.0.0.0/8IP),这当然会导致事情中断(即返回的数据包永远无法找到返回的路......)

因此我尝试nat使用以下方法获取源 IP:

nat on en0 from any to any -> en0

但这确实不是似乎可以工作,但源 IP 仍然有问题,并且与我的接口的源 IP 不对应en0

我如何确保这些重新路由的数据包的源 IP 设置正确?

答案1

— Mac OS 的 Pf 不会为你做到这一点。原因如下:

如果你看一下它的手册,你会发现NAT 正在发生过滤。但是 NAT 规则并不像过滤规则那样支持各种标志。也就是说,在执行 NAT 时无法检查套接字的所有权。您可以使用源或目标 IP 来限制 NAT 规则的适用性,但不能限制所有权。

另一件值得一提的是在 NAT 处理期间,Pf 进行正常路由查找。这意味着您根本无法工作——数据包根据当时内核的路由表进行路由。在您的情况下,它们被调度通过默认路由的接口(即 VPN 接口)发送。并且它们将使用 VPN 接口的地址作为其源 IP——这对于正常的路由查找来说并不奇怪,但显然不符合您的计划。nat on en0

简单总结一下这些矛盾:

  • 如果你不做 NAT,那么route-to应用时源 IP 是错误的
  • 您的 NAT 规则应在默认路由接口 (VPN) 上设置,同时将源 IP 更改为非VPN界面,如:nat on vpn0 … -> (en0)
  • 但另一方面,您不能拥有自定义 NAT(按所有权),并且如果您无论如何都执行 NAT,那么应该通过 VPN 传输的流量将具有错误的源 IP。

PS Mac OS 的 Pf 的实际状态是更糟。NAT 完成后,所有权匹配在过滤规则中也将不起作用。

相关内容