语境
在我的 Debian Linux 基础架构中,我管理具有特定角色的多个网络接口。
界面 | 角色 | 子网 | 描述 |
---|---|---|---|
eth0 |
公共连接 | 192.0.2.0/24 |
用于外部公共访问。 |
wg0 |
WireGuard VPN | 10.0.0.0/24 |
通过 VPN 实现机器之间的安全通信。 |
vmbr0 |
Proxmox 桥接器 | 172.16.0.0/16 |
虚拟机的桥梁。 |
- 防火墙规则:当前未应用任何 iptables/nftables 规则。所有链均将默认策略设置为ACCEPT。
- 内核配置:IPv4 转发已禁用(
net.ipv4.ip_forward = 0
)。
目标
目标是严格限制基础设施中的网络通信:
当计算机通过wg0
接口连接到 VPN 时,它应该只能与位于vmbr0
桥上的特定虚拟机进行通信。
目标是确保接口之间完全隔离并将流量限制到此特定用例。
重现设置
WireGuard 配置(虚假信息)
为了复制环境,这里是两台 Linux 机器的基本 WireGuard 配置:
机器1:VPN服务器(虚假信息)
界面:wg0
密钥生成(示例密钥,通过
wg genkey
和生成wg pubkey
):- 私钥:
9+9N5R5Dje2dmldDtrjQoBb3AFOWhOAyZ9mfWQKn7QY=
- 公钥:
Ci4z9W+n8gfrFRRGZs3DNMHmKk1TFNG9QXGV7zg5OkE=
- 私钥:
WireGuard 配置:(虚假信息)
文件
/etc/wireguard/wg0.conf
:[Interface] PrivateKey = 9+9N5R5Dje2dmldDtrjQoBb3AFOWhOAyZ9mfWQKn7QY= Address = 10.0.0.1/24 ListenPort = 51820 [Peer] PublicKey = YdC5+zMdKj5cRW2WlAv7GDETx+gjZukOmeC+lkJZ8is= AllowedIPs = 10.0.0.2/32
要应用的命令:
sudo wg-quick up wg0 sudo systemctl enable wg-quick@wg0
机器2:VPN客户端(虚假信息)
界面:wg0
密钥生成:
- 私钥:
mWjXaRlvJjThhf9ZZpaAWwdY0Puvy0k9fGy7prlzvV8=
- 公钥:
YdC5+zMdKj5cRW2WlAv7GDETx+gjZukOmeC+lkJZ8is=
- 私钥:
WireGuard 配置:
文件
/etc/wireguard/wg0.conf
:[Interface] PrivateKey = mWjXaRlvJjThhf9ZZpaAWwdY0Puvy0k9fGy7prlzvV8= Address = 10.0.0.2/24 [Peer] PublicKey = Ci4z9W+n8gfrFRRGZs3DNMHmKk1TFNG9QXGV7zg5OkE= Endpoint = <SERVER_IP>:51820 AllowedIPs = 10.0.0.1/24, 172.16.0.0/16, 192.0.2.0/24 PersistentKeepalive = 25
要应用的命令:
sudo wg-quick up wg0 sudo systemctl enable wg-quick@wg0
这些配置在 VPN 服务器 ( 10.0.0.1
) 和客户端 ( 10.0.0.2
) 之间建立了一个简单的连接。此设置构成了测试所述要求的基础。
桥
sudo brctl addbr vmbr0
sudo ip addr add 172.16.0.1/16 dev vmbr0
sudo ip link set dev vmbr0 up
问题
当客户端通过 wg0 接口连接到 VPN 时,会观察到以下问题:
访问所有接口: 尽管不同的子网和 IPv4 转发被禁用,VPN 客户端仍可以成功 ping 所有网络接口,包括 eth0 和 vmbr0。
数据包可见性: 通过在每个接口(eth0、vmbr0 和 wg0)上运行 tcpdump,可以观察到 ping 数据包仅穿过 wg0 接口。但是,当客户端 ping 其他接口时仍会收到响应。
服务暴露: 如果某个服务在任意接口上运行,比如:
python3 -m http.server --bind 192.0.2.1
(绑定到 eth0 IP 地址 192.0.2.1/24),VPN 客户端可以访问此服务。
接口关闭场景: 如果使用以下命令关闭接口(例如 eth0):
ip link set dev eth0 down
VPN 客户端仍可成功 ping 与关闭接口关联的 IP 地址并访问正在运行的服务(例如 HTTP 服务器)。无论接口的运行状态如何,此行为都会持续存在。
受限虚拟机问题: 在 vmbr0 桥上添加虚拟机时,VPN 客户端无法 ping 通它。(正常,但为什么我可以 ping 通桥)
请求协助
鉴于上述配置和观察到的问题:
- 为什么 VPN 客户端可以访问所有接口(eth0、vmbr0),而不是受到子网和禁用转发选项的限制?
- VPN 客户端如何才能继续访问服务或者 ping 故障接口上的 IP?
任何见解或解决方案都将不胜感激!
您自己就已经回答了:)
您不是将 IP 数据包发送到接口,而是发送到系统。由于您尝试访问的 IP 已分配给接收数据包的系统,因此它不需要将其转发到配置地址的特定接口。系统在本地处理它。
为什么 ?
ip rule
(man 8 ip-rule
) 表明local
路由表是第一个用于处理数据包的表,因为它具有最低优先级 (0
)。从
man 8 ip-route
:这个答案(https://unix.stackexchange.com/a/524304/651211)也对此进行了解释,并给出了防止这种行为的解决方案。
这取决于 IPv4 地址是如何分配给系统的(以及在关闭的接口上配置的)。对于静态寻址,IPv4 地址仍然在接口上配置。只需快速执行
ip addr show
或,ip route show table local
您自己看看,该地址仍然应该在本地列出和路由。对于 IPv6,您决定要做什么。默认是删除地址(请参阅keep_addr_on_down
内核参数/proc/sys/net/ipv6/
)