请考虑以下情形:
VPN 服务器是 FritzBox 7590,具有最新的操作系统并将 VPN 配置为 IPSec。
我有两个位置,通过 VPN 连接,如下所示。位置 A 运行 VPN 服务器和 Internet 网关(在 上192.168.2.1
),位置 B 中的设备可以连接到该网关。位置 B 有一个简单的 Internet 网关(在 上192.168.1.1
)和一个 WiFi 网络,我的设备可以通过它连接到 Internet。
现在,我希望位置 B 中的某些设备能够正常访问互联网(即直接通过位置 B 的互联网网关)。对于其他设备,我需要确保它们(无一例外)使用位置 A 的互联网网关(即通过 VPN)访问互联网。绝对重要的是,这些设备的流量不会通过位置 B 的网关“泄漏”到互联网.我们把这些设备称为“特殊设备”。
由于我不想为所有设备配置 VPN 连接,因此我在位置 B 添加了一台 RaspberryPi,它充当(第二个)WiFi 热点(开启192.168.5.1
),同时与位置 A 的 VPN 服务器建立 VPN 连接。因此,连接到此第二个 WiFi 热点(“特殊 WiFi”)的所有设备的所有流量都会自动通过隧道传输到位置 A 的 IPSec-VPN 服务器,然后它们可以从那里访问互联网。使用以下 RaspberryPi 配置,此操作可按预期工作:
常规设置:
RaspberryPi 运行 RasberryPi OS lite 64 位(内核 6.1),通过以太网(电缆)连接到位置 B 的互联网网关,并配置了静态 IP 地址。
VPN 配置:
我用来
vpnc
建立 VPN 连接。其配置/etc/vpnc/default.conf
如下:IPSec gateway my.awesome.vpn.server.com IPSec ID username IPSec secret p4ssw0rd IKE Authmode psk Xauth username Xusername Xauth password Xp4ssw0rd
Wi-Fi 配置:
我使用 NetworkManager (
nmcli
) 设置热点:sudo nmcli device wifi hotspot ssid specialwifi password p4assw0rd
然后开始
sudo nmcli device up wlan0
现在,当我启动 VPN 连接并将任何设备连接到特殊 Wi-Fi 时,它们的流量都会按预期自动路由。
现在谈谈我的问题:
如果 VPN 连接出现任何问题,来自特殊设备的流量将“正常”通过位置 B 的网关路由,即不符合预期。我需要阻止这种情况!
具体来说,我正在考虑以下几种情况:
- VPN 连接中断
- VPN 客户端
vpnc
崩溃 - VPN 服务器崩溃
有什么好的建议可以解决这个问题吗?我原本想配置 IP 表,但不知道该如何针对所述设置正确执行此操作。不幸的是,我无法在位置 B 的“正常”网关上配置任何内容。
答案1
根据您设置中的一些细微差别,有多种方法可以处理这个问题。
我在这里假设您担心的是 VPN 失败,而不是最终客户端连接到错误的 ssid(或以太网)。
您可以将 pi 上的默认路由设置为 lo,这样默认情况下,流量永远不会通过它。然后,您需要指定一条通过 WAN 的路由,到 VPN A 的端点的流量应通过 PI 上的 WAN 接口,同时让 VPN 服务器通告两个 /1 路由以覆盖默认路由。
您可以添加 2 条 iptables 规则,首先允许转发通过 vpn 接口,然后放弃所有其他转发。这不会影响来自 Pi 的流量,只会影响通过它的流量转发。规则将根据具体情况而有所不同,但可能类似于
iptables -I FORWARD -j DROP iptables -I FORWARD -i ipsecif -j ACCEPT
您也可以设置拒绝的默认转发规则并添加 ipsec 允许规则。
答案2
您可能正在寻求建立所谓的“终止开关”,这意味着当 VPN 连接由于某种原因断开时关闭互联网。
在 OpenConnect 本身中,这是在功能请求中提出的 添加 Kill-switch 功能 但从未实施。用户 Daniel Lenski 发表了以下评论,其中包含一些实用建议:
就 OpenConnect 的设计而言,此功能超出了 OpenConnect 本身的范围。OpenConnect 二进制文件实际上根本不执行任何路由/NAT/防火墙。它将路由配置推迟到vpnc 脚本。
github 脚本位于 VPN 终止开关 可以提供帮助,具体描述如下:
一旦 VPN 连接断开,Bash 脚本就会切断网络连接。
另一个来源是文章 什么是VPN终止开关?它如何工作? 解释了概念并包含了一些脚本。特别有趣的是“使用 iptables 的 Kill switch”和“使用 ufw 的 Kill switch”部分下的脚本。
以下是文章中的 iptables 解决方案:
确保先备份当前的 iptables 规则集。你可以使用以下命令进行备份
iptables-save
创建包含以下规则集的新 shell 脚本:
iptables --flush iptables --delete-chain iptables -t nat --flush iptables -t nat --delete-chain iptables -P OUTPUT DROP iptables -A INPUT -j ACCEPT -i lo iptables -A OUTPUT -j ACCEPT -o lo iptables -A INPUT --src 192.168.0.0/24 -j ACCEPT -i wlp6s0 iptables -A OUTPUT -d 192.168.0.0/24 -j ACCEPT -o wlp6s0 iptables -A OUTPUT -j ACCEPT -d 198.51.100.0 -o wlp6s0 -p udp -m udp --dport 1194 iptables -A INPUT -j ACCEPT -s 198.51.100.0 -i wlp6s0 -p udp -m udp --sport 1194 iptables -A INPUT -j ACCEPT -i tun0 iptables -A OUTPUT -j ACCEPT -o tun0
将创建的脚本保存为iptables-vpn.sh
设置权限。
chmod +x iptables-vpn.sh
执行脚本。
./iptables-vpn.sh
将脚本中的 IP 地址替换为您自己的 IP 地址。