我正在考虑使用 OpenBSD 作为 Starlink 后面的 NAT 路由器,但即使在最简单的情况下,NAT 的努力也会失败。我可能只是盯着它看得太久了,需要额外的眼睛。
这是基本设置。
[Starlink 192.168.1.1] <=> <igc0: 192.168.1.189> [OpenBSD 路由器“cerby”] igc3:172.16.16.1 <=> {LAN}
ifconfig igcN
cerby$ ifconfig igc0
igc0: flags=808843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,AUTOCONF4> mtu 1500
lladdr 7c:2b:e1:13:2f:35
index 1 priority 0 llprio 3
groups: egress
media: Ethernet autoselect (1000baseT full-duplex)
status: active
inet 192.168.1.189 netmask 0xffffff00 broadcast 192.168.1.255
cerby$ ifconfig igc3
igc3: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
lladdr 7c:2b:e1:13:2f:38
index 4 priority 0 llprio 3
media: Ethernet autoselect (1000baseT full-duplex)
status: active
inet 172.16.16.1 netmask 0xffffff00 broadcast 172.16.16.255
sysctl
cerby$ sysctl | grep -i forwarding
net.inet.ip.forwarding=1
net.inet.ip.mforwarding=0
net.inet6.ip6.forwarding=0
net.inet6.ip6.mforwarding=0
pf.conf
这是我尝试过的几十种配置之一,只是为了尝试让 NAT 转发正常工作:
ext = "igc0"
int = "igc3"
table <martians> { 0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 \
172.16.0.0/12 192.0.0.0/24 192.0.2.0/24 224.0.0.0/3 \
198.18.0.0/15 198.51.100.0/24 \
203.0.113.0/24 }
set block-policy drop
set loginterface egress
set skip on lo0
match in all scrub (no-df random-id max-mss 1440)
match out on egress inet from !(egress:network) to any nat-to (egress:0)
antispoof quick for { egress $ext $int }
# block in quick on egress from <martians> to any
# block return out quick on egress from any to <martians>
block all
pass out quick inet
pass in on { $ext $int } inet
pass in on egress inet proto tcp from any to (egress) port { 80 443 } rdr-to 172.16.16.1
我尝试过禁用所有类型的阻止等,但无济于事
pfctl -sr
cerby$ doas pfctl -sr
match in all scrub (no-df random-id max-mss 1440)
match out on egress inet from ! (egress:network) to any nat-to (egress:0) round-robin
block drop in quick on ! egress inet from 192.168.1.0/24 to any
block drop in quick inet from 192.168.1.189 to any
block drop in quick on ! igc0 inet from 192.168.1.0/24 to any
block drop in quick on ! igc3 inet from 172.16.16.0/24 to any
block drop in quick inet from 172.16.16.1 to any
block drop all
pass out quick inet all flags S/SA
pass in on igc0 inet all flags S/SA
pass in on igc3 inet all flags S/SA
pass in on egress inet proto tcp from any to (egress) port = 80 flags S/SA rdr-to 172.16.16.1
pass in on egress inet proto tcp from any to (egress) port = 443 flags S/SA rdr-to 172.16.16.1
pf2.conf
为了消除发生某种阻塞的可能性:
extIF = "igc0"
lanIF = "igc3"
table <martians> { 0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 \
172.16.0.0/12 192.0.0.0/24 192.0.2.0/24 224.0.0.0/3 \
198.18.0.0/15 198.51.100.0/24 \
203.0.113.0/24 }
lan = $lanIF:network
extIP = 192.168.1.189
set block-policy drop
set loginterface egress
set skip on lo0
pass from { lo0 $lan } to any keep state
match out on $extIF from $lan to any nat-to $extIP
pass out on $extIF from $lan to any nat-to ($extIF)
pass out quick inet
pass in on { $extIF $lanIF } inet
pass in on egress inet proto tcp from any to (egress) port { 80 443 } rdr-to 172.16.16.1
pfctl -sr
cerby$ doas pfctl -sr
pass inet6 from ::1 to any flags S/SA
pass on lo0 inet6 from fe80::1 to any flags S/SA
pass inet from 127.0.0.1 to any flags S/SA
pass inet from 172.16.16.0/24 to any flags S/SA
match out on igc0 inet from 172.16.16.0/24 to any nat-to 192.168.1.189
pass out on igc0 inet from 172.16.16.0/24 to any flags S/SA nat-to (igc0) round-robin
pass out quick inet all flags S/SA
pass in on igc0 inet all flags S/SA
pass in on igc3 inet all flags S/SA
pass in on egress inet proto tcp from any to (egress) port = 80 flags S/SA rdr-to 172.16.16.1
pass in on egress inet proto tcp from any to (egress) port = 443 flags S/SA rdr-to 172.16.16.1
route show
cerby$ doas route show
Routing tables
Internet:
Destination Gateway Flags Refs Use Mtu Prio Iface
default 192.168.1.1 UGS 5 1107992 - 8 igc0
base-address.mcast localhost URS 0 2730 32768 8 lo0
127/8 localhost UGRS 0 0 32768 8 lo0
localhost localhost UHhl 1 425 32768 1 lo0
172.16.16/24 172.16.16.1 UCn 1 0 - 4 igc3
172.16.16.1 7c:2b:e1:13:2f:38 UHLl 0 10738 - 1 igc3
172.16.16.100 a8:60:b6:2f:f6:0a UHLc 2 69 - 3 igc3
172.16.16.255 172.16.16.1 UHb 0 39 - 1 igc3
192.168.1/24 192.168.1.189 UCn 2 42319 - 4 igc0
192.168.1.1 74:24:9f:c0:80:26 UHLch 2 53063 - 3 igc0
192.168.1.35 80:ea:96:e5:c2:dc UHLc 2 42272 - 3 igc0
192.168.1.189 7c:2b:e1:13:2f:35 UHLl 0 117169 - 1 igc0
192.168.1.255 192.168.1.189 UHb 0 543 - 1 igc0
dhcpd.conf
cerby$ cat /etc/dhcpd.conf
subnet 172.16.16.0 netmask 255.255.255.0 {
option domain-name-servers 172.16.16.1;
option routers 172.16.16.1;
range 172.16.16.100 172.16.16.200;
}
观察结果
- LAN 上的主机可以毫无问题地连接到 172.16.16.1 的路由器
unbound
DNS 查找通过172.16.16.1进行,- ping 172.16.16.1 没问题,
- 局域网机器上的默认路由是172.16.16.1。
- ping 192.168.1.189 成功
- ping 192.168.1.1不是工作
一切似乎都如预期然而数据包没有被发送,即状态部分不起作用。
感觉我肯定忽略了一些显而易见的东西。
答案1
答案似乎是切换到不同的网络,例如192.168.2.x
:
hostname.igc3
cerby$ cat /etc/hostname.igc3
inet 192.168.2.1 255.255.255.0 NONE
pf.conf
cerby$ cat /etc/pf-2022-10-27.conf
extIF = "igc0"
lanIF = "igc3"
table <martians> { 0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 \
172.16.0.0/12 192.0.0.0/24 192.0.2.0/24 224.0.0.0/3 \
198.18.0.0/15 198.51.100.0/24 \
203.0.113.0/24 }
lan = $lanIF:network
extIP = 192.168.1.189
set block-policy return
set loginterface egress
set skip on lo0
pass from { lo0 $lan } to any keep state
match out on $extIF from $lan to any nat-to $extIP
pass out on $extIF from $lan to any nat-to ($extIF)
pass out quick inet
pass in on { $extIF $lanIF } inet
pfctl -sr
cerby$ doas pfctl -sr
pass inet6 from ::1 to any flags S/SA
pass on lo0 inet6 from fe80::1 to any flags S/SA
pass inet from 127.0.0.1 to any flags S/SA
pass inet from 192.168.2.0/24 to any flags S/SA
match out on igc0 inet from 192.168.2.0/24 to any nat-to 192.168.1.189
pass out on igc0 inet from 192.168.2.0/24 to any flags S/SA nat-to (igc0) round-robin
pass out quick inet all flags S/SA
pass in on igc0 inet all flags S/SA
pass in on igc3 inet all flags S/SA
显然,这些规则对于任何现实世界的情况来说可能都过于宽松,但它确实解决了 NAT 的无能为力的问题。
我现在依稀记得 20 多年前也遇到过地址空间问题172.16
。将记录到 2040 年。同时,我希望这里的配置能给遇到类似问题/设置的人一些启发。