我正在配置 OpenVPN 网关以允许 LAN 通过隧道访问互联网。该网关在 PC Engines APU 平台上运行 OpenBSD 5.5-stable amd64。
LAN 包含re1
、re2
、 和ral0
接口。它还包含vether0
本地网络的主机192.168.2.0/24
。这些接口通过 进行链接,bridge0
以提供公共网关、子网和 DHCP dhcpd
。
VPN已建立并tun0
开通。网关本身可以正常访问VPN。
问题在于,默认情况下,主机使用其本机192.168.2.0/24
地址访问 VPN。需要 NAT 将本地网络转换为位于 的 VPN 网络10.0.1.0/24
。
我尝试过以下pf.conf
配置:
# pf.conf -- 10.0.1.10 is my tun0 gateway
set skip on lo
block return
pass in quick on { vether0 re1 re2 ral0 } from 192.168.2.0/24 to !10.0.0.0/8 nat-to 10.0.1.10
pass
我使用这些规则得到了类似的结果:
# pf.conf
...
pass in from any nat-to 10.0.1.10
pass out from tun0 to any
tun0
这允许 LAN 流量通过源地址进行传递10.0.1.10
,并且返回流量将传回相应的主机。新问题是返回流量似乎仍然没有正确路由。
例如,我可以从任何 LAN 主机 ping8.8.8.8
和google.com
,但是第一个回复总是在tun0
返回接口之间被丢弃。dig
、nslookup
、traceroute
和等工具ping
通常运行缓慢,并且花费的时间比应有的时间长得多。尽管仍有一些流量通过,但浏览器和其他应用程序无法使用。
tcpdump
证明损失:
# 192.168.2.103 is a LAN host
# 74.125.131.139 is google.com
# on ral0
20:59:35.668251 192.168.2.103 > 74.125.131.139: icmp: echo request <-- no reply
20:59:40.651184 192.168.2.103 > 74.125.131.139: icmp: echo request
20:59:40.736748 74.125.131.139 > 192.168.2.103: icmp: echo reply
20:59:41.656101 192.168.2.103 > 74.125.131.139: icmp: echo request
20:59:41.741251 74.125.131.139 > 192.168.2.103: icmp: echo reply
20:59:42.661071 192.168.2.103 > 74.125.131.139: icmp: echo request
20:59:42.802410 74.125.131.139 > 192.168.2.103: icmp: echo reply
# on tun0
20:59:35.668359 10.0.1.10 > 74.125.131.139: icmp: echo request
20:59:35.764052 74.125.131.139 > 10.0.1.10: icmp: echo reply <-- here's the missing reply, it didn't get to ral0
20:59:40.651221 10.0.1.10 > 74.125.131.139: icmp: echo request
20:59:40.736721 74.125.131.139 > 10.0.1.10: icmp: echo reply <-- but the of the replies rest did
20:59:41.656138 10.0.1.10 > 74.125.131.139: icmp: echo request
20:59:41.741226 74.125.131.139 > 10.0.1.10: icmp: echo reply
20:59:42.661107 10.0.1.10 > 74.125.131.139: icmp: echo request
20:59:42.802372 74.125.131.139 > 10.0.1.10: icmp: echo reply
我知道这几乎肯定是 NAT 问题,pf.conf
但经过多次配置尝试后,我无法找到传递流量的正确方法。
当我使用 DD-WRT 和 时iptables
,这是我的配置:
iptables -D FORWARD -i tun1 -j logaccept
iptables -D FORWARD -o tun1 -j logaccept
不过,我不确定如何将其“移植”到pf
。任何建议将不胜感激!
答案1
事实证明这是一个pf.conf
问题。花一些额外的时间学习OpenBSD PF NAT页面引导我发现以下规则,该规则允许流量正确通过接口tun0
:
# /etc/pf.conf
pass out on tun0 inet from 192.168.2.0/24 to any flags S/SA nat-to (tun0) round-robin
这实质上是这样的:传递来自本地网络的流量,目的地是 上的任何地址tun0
(特别是 IPv4),仅查看syn
和ack
标志,并使用 执行出站 NAT tun0
。括号(tun0)
表示pf
当接口更改其地址时自动更新规则。如果您的 VPN 支持多个对等点并且您进行故障转移,则可能会发生这种情况,因此无需手动重新加载规则集。
有一段时间在OpenBSD PF 过滤页面帮助我完善了规则:
# /etc/pf.conf
pass out on $vpn_if inet proto { $protos } from $lan_net to any flags S/SA modulate state nat-to ($vpn_if) round-robin
pass in on $vpn_if inet proto { $protos } from $vpn_gw to any flags S/SA modulate state
该modulate state
标志允许pf
替换更强的初始序列号,这可能有助于保护网络上的某些操作系统。
网关现在工作得很好,我正在进行更复杂的pf.conf
配置。