macOS 下的 pfctl 流量转发 (nat)

2022-12-10 ⏳0.5分钟(0.2千字)

本文介绍 freeBSD(同 macOS) 下的 nat 流量转发, 等同 linux 下的 iptables 转发功能.

缘起

我在之前的 VPN 开发中碰到过 tun interface 的流量转发问题, 大致就是需要 en0 和 utun0 的交互问题. FreeBSD 已经放弃了 iptables 而采用了 pfctl . 这里介绍下区别.

历程

不管是 freeBSD 还是 linux 衍生版本都需要打开流量转发才能启用转发规则, 这里大致相同:

sudo sysctl -w net.inet.ip.forwarding=1

在 linux 以及其衍生版本里我们一般这样进行流量的转发:

iptables -t nat -A POSTROUTING -j MASQUERADE

但是 freeBSD 已经移除了 iptables 支持, 而采用 pfctl.

  1. 首先我们需要在 /usr/local/etc/ 下创建一条转发配置, 举个🌰:

假设我们的出口网卡是 en0, 而虚拟 tun 设备是 utun0.

➜  ~ cat /etc/pf.anchors/xtun
nat on en0 from utun3:network to any -> (en0)

# 这里并不是加载配置而是进行配置检测
➜  ~ sudo pfctl -vnf /etc/pf.anchors/xtun
pfctl: Use of -f option, could result in flushing of rules
present in the main ruleset added by the system at startup.
See /etc/pf.conf for further details.

nat on en0 inet from 10.0.0.0/8 to any -> (en0) round-robin
  1. 调整 /etc/pf.conf 主配置文件加载 xtun
➜  cat /etc/pf.conf

scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"
rdr-anchor "xtun-forwarding"  # 注意这里名字随便起
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"
load anchor "xtun-forwarding" from "/etc/pf.anchors/xtun" # 这里要指定路径
  1. 加载配置
➜  ~ sudo pfctl -f /etc/pf.anchors/xtun -e
Password:
pfctl: Use of -f option, could result in flushing of rules
present in the main ruleset added by the system at startup.
See /etc/pf.conf for further details.

No ALTQ support in kernel
ALTQ related functions disabled
pfctl: pf already enabled

总结

linux 不同的分支上有些行为已经不太一致, 小记一下.