OpenVPN on macOS
SNAT (pf.conf)
pf.conf
scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
nat-anchor "kugarocks_nat"
rdr-anchor "com.apple/*"
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"
anchor "kugarocks_nat"
load anchor "kugarocks_nat" from "/etc/pf.anchors/kugarocks_nat.conf"
kugarocks_nat.conf
nat on utunx from 10.8.x.x to 10.24.x.x/16 -> 10.24.x.x
Check
pfctl -nf /etc/pf.conf
Load
pfctl -f /etc/pf.conf
Enabled
pfctl -e
pfctl -s nat
Loopback Issue
Cannot ssh to 10.24.1.x
ok
nc -vz 10.8.0.x 22
fail
nc -vz 10.24.1.x 22
10.8.0.x(tun0)和10.24.1.x(本机 LAN)是同一台机器。- 当从 tun0 发往
10.24.1.x的 TCP 流量到达 macOS 内核时,macOS 内核会看到这个包的目标 IP 是本机自己的一张非 tun 接口 IP。 - macOS 内核默认会阻止这种“外部接口回环到本机另一接口”的 TCP 流量,这是内核的防止环回 TCP/IP 泄漏或意外路由的策略。
- ICMP(ping)没有这种限制,所以 ping 能通,但 TCP 不通。
解决方案:
ifconfig lo0 alias 10.24.1.x
lo0是本机回环接口(loopback),内核允许 从任何接口发往lo0的流量回环到本机。- 给
lo0添加别名 IP 之后:- 内核把 tun0 发往
10.24.1.2的 TCP 包识别为“回环流量”,可以被本机接受。 - TCP 连接正常建立,SSH 成功。
- 内核把 tun0 发往
- 本质上,你让 目标 IP 变成内核认为是回环接口 IP → TCP 不再被阻止。