如何将 Raspberry Pi VPN 服务器迁移到以太网
在不改变端点名称、监听绑定、端口转发或一步回滚路径的前提下,把 Raspberry Pi VPN 服务器从 Wi-Fi 迁移到以太网。
把 Pi 从 Wi-Fi 换成网线看似五分钟的小事,但只有把这次迁移当成四项彼此独立的设置,而不是一项,它才真的只是五分钟。客户端拨号的端点名称可以完全不变,而它下面的地址却换了。真正会坏掉的是钉在旧地址上的监听器、仍指向无线租约的端口转发,或者从你以为已经退场的接口出去的返回路由。本指南在每一步都保留一条恢复路径,因此切换失败最多只花一次重启。
拔掉任何东西之前,先记下四位负责人
四项设置决定切换能否活下来:Pi 的地址、OpenVPN 的绑定地址、路由器的转发目标,以及响应所走的路径。碰网线之前把四项都写下来,因为无线租约一旦消失,你就无法再从机器上读出旧值。有线接口不会继承无线配置文件,在 Bookworm 上地址住在 NetworkManager 里,而 Bullseye 把它保存在 dhcpcd.conf 中。把无线 MAC 地址钉住的保留项,对 eth0 一无所知。请把新地址当作需要自己证据的新分配。
Old wireless lease: 10.42.7.24/24 on wlan0
New wired address: 10.42.7.31/24 on eth0
Client endpoint: vpn.lab.example:1194/udp
监听器是第二位负责人。如果服务是用某个特定绑定地址启动的,套接字会随旧接口一起死掉;如果它绑定所有地址,套接字就能活下来,路由规则就成了唯一还要修的东西。
转发目标和返回路径是人们最常跳过的负责人。仍然指向 10.42.7.24 的转发会把到达的握手发到 Pi 已经不持有的地址,于是客户端超时,而服务端一行日志都没有。当两条链路短暂同时在线时,返回路径就很关键,因为 Pi 会从路由表偏好的接口回复,而那并不总是数据包进来的接口。下面的路由查询显示内核选择哪个源地址。
相信新地址之前,先读真实的套接字
配置文件描述意图,套接字描述现实。问正在运行的服务绑在什么上,而不是相信你记得的配置。OpenVPN 2.6 手册 把 --local 定义为绑定到一个地址,并指出省略它会绑定每个接口。
sudo systemctl cat openvpn-server@server | grep -n -- '--local'
sudo ss -lunp '( sport = :1194 )'
读本地地址那一列,而不是状态列。显示 10.42.7.24:1194 的行意味着套接字钉在你马上要移除的地址上,而 0.0.0.0:1194 或 *:1194 意味着守护进程会自己跟随接口变化。如果地址被钉住,请编辑配置并重启单元,而不是手工重写正在使用的套接字,然后确认服务仍能读到它的证书和密钥文件。
按能让你保持可达的顺序走完这次迁移
这里顺序比速度更重要。在无线仍然可用时先把有线链路起来,确认新地址和返回路径,然后再让无线配置文件退场。这个顺序能让可用的会话一直开着,直到替代方案被证明。
ip -br addr show eth0
ip route get 203.0.113.10
nmcli -g ipv4.method,ipv4.addresses con show "Wired connection 1"
第一条命令回答 eth0 是否拿到了你预期的地址,第二条打印内核去往外部目标时会用的源地址,所以要在改动前后各跑一次。如果那个源地址仍是无线地址,有线链路还不是首选路径,外部测试就会因为一个与 OpenVPN 毫无关系的原因失败。碰到转发之前,先修正路由偏好。
两条链路都在线时,Pi 可能偏好无线默认路由,因为它先被配置,或因为有线链路的度量值更高。Bookworm 上受支持的开关是连接上的 ipv4.route-metric,Bullseye 上的等价物则是 metric 中针对接口的 dhcpcd.conf 行。请降低无线链路的优先级而不是禁用它,让回滚路径保持一条命令的距离。
从外部证明隧道,而不是从 LAN
从沙发上能连通的 VPN 证明的东西比看上去少。从 LAN 内部到公网地址的流量会经过路由器实现得不一致的 hairpin 或反射规则,所以 LAN 测试通过可能与外部路径损坏并存。请用蜂窝数据的手机,或网络之外的任何主机来做验收测试。LAN 的尝试留作单独的选做诊断。
然后按数据包到达的顺序读日志。什么都没有意味着握手从未到达 Pi,所以转发目标或主机防火墙不对。开始后卡住的握手指向密钥、证书或 MTU。完成然后掉线的会话通常意味着返回路径或第二条默认路由,而客户端日志行 Initialization Sequence Completed 告诉你隧道本身已建立。
sudo journalctl -u openvpn-server@server -n 40 --no-pager
sudo tcpdump -ni any udp port 1194 -c 20
如果客户端重试时服务器日志里什么都没有,别再读 OpenVPN 配置,回到转发目标。抓包几秒钟就能回答“是否到达”的问题,而没有回应的入站数据包把问题缩小到路由。
保留一步回滚,并让无线配置文件退场
在有线方案通过一次重启之前,先让无线配置文件保持安装。nmcli con show 会列出你需要的配置文件名称,而删掉的配置文件要在最糟的时刻凭记忆重建。把接口名、地址方式和度量值记在另外四个值旁边。能照着笔记敲出来的回滚,比必须重建的回滚更有价值。
让无线依赖退场是改属性,而不是删除。设置 connection.autoconnect no 会在保留凭据和地址历史的同时,阻止 Pi 重新连回你已经离开的网络。
nmcli con show
sudo nmcli con up "Wired connection 1"
sudo nmcli con mod "previously-used-wifi" connection.autoconnect no
宣布完工之前,确认四件事:转发目标与有线地址一致,监听器挺过了一次重启,外部客户端完成了握手,Pi 在重启后仍能在有线地址上响应。重启是抓住只存在于运行内核里的分配的最便宜办法。四项里任何一项失败,就用 sudo nmcli con up 把无线配置文件恢复回来,并把记录的值和实际值对比。