手机连上接入点、拿到地址,隧道一建立就什么都访问不到。此时 hostapd 通常仍然正常,OpenVPN 也是;坏掉的是默认路由,它要么从未出现在网桥上,要么被隧道替换却没有留下通往 VPN 服务器本身的路由。本文把那条路由放回原处,并从客户端而不是树莓派本身来验证结果。每一步都可以回退,而且在弄清要在隧道里放哪些流量之前,这里不会改动隧道配置。

动手修改之前先盘点接口

常见布局把无线网卡和有线网口放进 br0,让 hostapd 绑定网桥,由 dnsmasq 分发租约,同时 OpenVPN 客户端创建 tun0。于是三个彼此独立的要求看起来像一个:接入点客户端需要树莓派作为网关,树莓派需要一条通往互联网的路由才能连上服务器,网桥则需要一个客户端可用的网关地址。

修改之前先读取当前状态,因为这四条命令能把接口问题和路由问题区分开。

ip -br addr
ip route show
ip link show master br0
bridge link show

如果 br0 有地址却没有默认路由,客户端只能到树莓派,再往外就不通了。如果隧道断开时默认路由指向 tun0,树莓派就完全没有可用路径,客户端的症状看起来一模一样。两种情况从手机上看完全相同,所以必须直接读取路由表。

给网桥一条属于它自己的默认路由

当网桥是在接口文件写完之后才出现的,Raspberry Pi OS 常常不给它默认路由。这段配置应放在 /etc/dhcpcd.conf 中,并且应当写上游路由器,而不是树莓派自己。

interface br0
static ip_address=192.168.50.2/24
static routers=192.168.50.1
static domain_name_servers=192.168.50.1

在这个例子里 192.168.50.1 是现有路由器,192.168.50.2 是同一子网内树莓派的网桥地址,所以请换成你自己的方案,而不是照抄这些数字。网桥成员也不应再请求路由器,否则树莓派会留下互相竞争的默认路由,胜负取决于度量值和时序而不是意图。

执行 systemctl restart dhcpcd 之后,ip route show default 应当只列出一次 br0,并且没有来自有线网口的重复项。要确认的是查询结果而不是路由表,因为过期条目可能与生效条目并存:ip -4 route get 203.0.113.10 必须指向 br0。该地址来自 TEST-NET-3 文档网段,所以在你阅读时它不会与真实服务器冲突。

别让隧道劫持通往它自己服务器的路径

接受 redirect-gateway 的 OpenVPN 客户端会接管默认路由并把它指向隧道。当所有接入点客户端都该走 VPN 时这是对的,当只有部分目标该走时就是错的。无论如何,树莓派自身到服务器的连接都不能走在那条尚未建成的隧道里。OpenVPN 在重定向默认路由时,会通过原来的网关为远端添加一条主机路由,这正是让传输保持存活的行为;如果缺少这条路由,隧道一旦建立就会崩塌。

连接前后快速对比这条传输路径,值得花那十秒钟。ip -4 route get 203.0.113.10 在两种状态下都应指向底层设备,变化的只是度量值。如果隧道建立后它指向 tun0,说明主机路由从未安装,下一次重连就会失败。

当只有选定的前缀需要穿过隧道时,使用 route-nopull 并手动添加需要的路由,或者由服务器下发更窄的集合。那样网桥保留默认路由,DNS 就成了下一个决定:把 dnsmasq 转发到家庭解析器,只对真正住在那里的名字有意义。

决定转发与 NAT 的做法

完整隧道需要在树莓派上开启转发,并且对端网关愿意为接入点子网做路由。先检查转发,因为值为零会让所有路由改动都失去意义。

sysctl net.ipv4.ip_forward
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -s 192.168.50.0/24 -o tun0 -j MASQUERADE

NAT 规则是服务器不接受接入点前缀时的捷径,代价是远端日志里每个客户端都显示成树莓派的隧道地址。不做 NAT 而为该前缀做路由可以保留地址可见性,并且依赖家庭侧为 192.168.50.0/24 配置回程路由。

把选择写在防火墙规则旁边,因为设计里看不见的 NAT 规则半年后就变得无法解释。IPv6 要放进同一个决定;在浏览器里,坏的 IPv6 路径旁边的可用 IPv4 路径仍然会被读成半坏。

从客户端验证,然后干净地回滚

在接入点上用手机或笔记本按这个顺序测试:从 dnsmasq 取得租约、ping 网桥地址、再访问隧道另一侧的目标。每一步只隔离一层,而不是给出一个毫无帮助的失败。

ip -4 route get 203.0.113.10
ping -c 3 -I br0 203.0.113.10

然后确认树莓派自己仍有出口:ip route get 203.0.113.10 应指向底层设备,服务器允许 ICMP 时 ping -c 3 -I br0 203.0.113.10 应有回应。如果客户端前两步通过而第三步失败,问题在转发或 NAT。如果第二步失败,网桥或 DHCP 仍不完整。

回滚是一次文件修改加两条命令:删掉那段配置、重启 dhcpcd,并用 ip route replace default via 192.168.50.1 dev br0 显式替换默认路由。要在维护窗口关闭之前做,而不是之后,因为丢失默认路由的树莓派,无法从你打算用来修复它的网络访问。

相关文章