这与OpenVPN 和路由。
我的服务器运行基于 racoon 的 L2TP/PPTP VPN 服务和 OpenVPN 服务。racoon 服务分配 10.0.77.0/24 范围内的地址(在 en1 接口上),OpenVPN 服务分配 10.0.88.0/24 范围内的客户端地址(在 utun0 接口上)。客户端通过 en0 接口上的公共 IP 从公共互联网连接到这两个服务,并通过同一接口(en0:0)上的另一个公共 IP 进行 NAT 回到公共互联网。
请参阅下面的 pf 规则集。我 99.9% 肯定这是我的 pf 规则的问题。
在“nat on en0...”规则生效后,所有 VPN 客户端都可以正常访问互联网。racoon 客户端还可以访问我服务器其他 IP 上的其他服务,但 OpenVPN 客户端只能通过 10.0.88.1 地址访问这些服务。这些客户端能ping 并跟踪其他 IP,但不访问它们上的任何服务。当 ping 运行时,tcpdump 显示在 utun0 接口上发生的 ping,但如果我监控 en0 接口(该接口被分配了要 ping 的 IP 地址),它不会显示 ping。
如果我禁用“nat on en0”规则,显然没有客户端可以连接到互联网,但所有客户端都可以连接到服务器的其他 IP。nat 规则、OpenVPN 如何处理隧道以及 pf 如何过滤事物,这些都扰乱了本地接口访问……但显然我对 pf 不够了解,无法弄清楚。
这是 pf 配置。有人能发现问题吗?
set block-policy drop
set fingerprints "/etc/pf.os"
scrub-anchor "/*" all fragment reassemble
nat-anchor "/*" all
rdr-anchor "/*" all
anchor "/*" all
dummynet-anchor "/*" all
table <vpn-nets> persist { 10.0.77.0/24 10.0.88.0/24 }
nat-anchor "/*" all
rdr-anchor "/*" all
pass quick on lo0 all flags S/SA keep state
anchor "/*" all
anchor "/*" all
anchor "/*" all
anchor "/*" all
nat on en0 from ! (en0) to any -> (en0:0)
table <__automatic_0> const { 127.0.0.1 10.0.88.1 10.0.77.1 }
pass inet6 from ::1 to any flags S/SA keep state
pass on lo0 inet6 from fe80::1 to any flags S/SA keep state
pass on en1 inet6 from fe80::223:dfff:fede:f372 to any flags S/SA keep state
pass inet from <__automatic_0> to any flags S/SA keep state
pass from <vpn-nets> to any flags S/SA keep state
pass on utun0 all flags S/SA keep state
pass on en1 all flags S/SA keep state
pass in on utun0 all keep state fragment
pass out on en0 from any to <vpn-nets> flags S/SA keep state
table <blockedHosts> persist file "/var/db/af/blockedHosts"
block drop in quick from <blockedHosts> to any
pass quick on lo0 all flags S/SA keep state
pass in log all flags S/SA keep state
pass out log all flags S/SA keep state
答案1
事实证明,我只需要在 nat 声明之后添加一个“rdr”规则,将来自 OpenVPN 客户端的任何发往服务器公共 IP 的内容重定向到 OpenVPN 虚拟网关:
nat on en0 from ! (en0) to any -> (en0:0)
rdr pass on utun0 inet proto { tcp udp } from 10.0.88.0/24 to en0 -> 10.0.88.1
显然 racoon 可以自行完成此操作 (?),但 OpenVPN 则不行。我仍然不明白为什么 ping 在没有规则的情况下可以工作,而 tcp/udp 却不行——但这就是为什么我只用规则重定向 tcp/udp。这个 pf 单行命令比使用水平分割 DNS 要容易得多。