Debian 12 Bookworm下基于GID配置iptables实现指定用户组流量走VPN接口并限制物理接口的问题求助
Debian 12 Bookworm下基于GID配置iptables实现指定用户组流量走VPN接口并限制物理接口的问题求助
首先,你的问题根源在于VPN启动后修改了系统默认路由,导致所有流量都默认走tun9,而你的iptables规则既存在语法错误,也缺少关键的阻止规则,同时没通过路由策略从根源区分不同用户组的流量走向。下面是具体的分析和修复方案:
一、先修正iptables规则中的错误和缺失
你的现有规则里有无效的语法写法(/!是错误格式),且没有阻止非watchers组用户使用VPN接口。替换你的/etc/openvpn/protonvpn/routing.sh为以下内容(记得给脚本加执行权限:chmod +x /etc/openvpn/protonvpn/routing.sh):
#!/bin/bash # 清空现有规则、自定义链和计数器 iptables -F iptables -X iptables -Z NET=192.168.0.0/24 GROUP=watchers IFACE_INTERNAL=enp2s0 IFACE_VPN=tun9 ALLOW_PORT_FROM_LOCAL=2000 # 允许所有用户的本地回环流量 iptables -A OUTPUT -o lo -j ACCEPT # 允许watchers组的流量走VPN接口,包含指定端口的内网流量 iptables -A OUTPUT -d $NET -p tcp --sport $ALLOW_PORT_FROM_LOCAL -m owner --gid-owner $GROUP -o $IFACE_VPN -j ACCEPT iptables -A OUTPUT -d $NET -p udp --sport $ALLOW_PORT_FROM_LOCAL -m owner --gid-owner $GROUP -o $IFACE_VPN -j ACCEPT iptables -A OUTPUT -m owner --gid-owner $GROUP -o $IFACE_VPN -j ACCEPT # 严格阻止watchers组使用物理接口 iptables -A OUTPUT -m owner --gid-owner $GROUP -o $IFACE_INTERNAL -j REJECT # 允许非watchers组使用物理接口 iptables -A OUTPUT -m owner ! --gid-owner $GROUP -o $IFACE_INTERNAL -j ACCEPT # 阻止非watchers组使用VPN接口 iptables -A OUTPUT -m owner ! --gid-owner $GROUP -o $IFACE_VPN -j REJECT # 允许入站流量 iptables -A INPUT -i $IFACE_VPN -j ACCEPT iptables -A INPUT -i $IFACE_INTERNAL -j ACCEPT iptables -A INPUT -i lo -j ACCEPT # 可选:设置默认策略增强安全性(需要确保已有规则覆盖必要流量) iptables -P OUTPUT DROP iptables -P INPUT DROP iptables -P FORWARD DROP
二、添加基于用户组的路由策略(关键步骤)
仅靠iptables过滤还不够——因为VPN启动后会把默认路由指向tun9,非watchers组的流量会先尝试走这个路由再被iptables拦截,体验不佳。我们需要用路由策略让不同用户组的流量直接走对应路由表:
- 先创建一个专门给
watchers组用的路由表:
echo "100 vpn" >> /etc/iproute2/rt_tables
- 修改你的OpenVPN配置文件(
.ovpn),注释掉原有的up/down脚本,添加自定义路由处理逻辑:
# 注释掉原有的这两行: # up /etc/openvpn/update-resolv-conf # down /etc/openvpn/update-resolv-conf # 添加以下内容 route-noexec up /etc/openvpn/protonvpn/up-custom.sh down /etc/openvpn/protonvpn/down-custom.sh
- 创建
up-custom.sh脚本(同样加执行权限):
#!/bin/bash # 将VPN路由写入专门的vpn路由表 ip route add default via $route_vpn_gateway dev $dev table vpn # 添加路由规则:给watchers组的流量打标记,让它们走vpn路由表 ip rule add fwmark 0x1 table vpn iptables -t mangle -A OUTPUT -m owner --gid-owner watchers -j MARK --set-mark 0x1 # 保留原有的DNS配置逻辑(如果需要) /etc/openvpn/update-resolv-conf "$@"
- 创建
down-custom.sh脚本(加执行权限):
#!/bin/bash # 清理路由规则和标记 ip rule del fwmark 0x1 table vpn ip route flush table vpn iptables -t mangle -D OUTPUT -m owner --gid-owner watchers -j MARK --set-mark 0x1 # 保留原有的DNS清理逻辑(如果需要) /etc/openvpn/update-resolv-conf "$@"
三、验证配置效果
- 重启ProtonVPN服务:
systemctl daemon-reload systemctl restart proton.service
- 用非
watchers组用户测试:
curl icanhazip.com # 应该返回你的物理接口公网IP
- 用
watchers组用户测试:
sudo -u <你的watchers组用户名> curl icanhazip.com # 应该返回VPN的公网IP
- 测试
watchers组是否被限制使用物理接口:
sudo -u <你的watchers组用户名> curl --interface enp2s0 icanhazip.com # 应该被拒绝连接
为什么原有配置不生效?
- VPN启动后覆盖了系统默认路由,所有流量默认走
tun9,你的规则没有阻止非watchers组使用这个接口; - 规则中的
/!是无效语法,正确写法是!; - 缺少路由策略层面的区分,导致非目标用户组的流量会先尝试走VPN路由,再被iptables拦截,无法从根源上分流。
备注:内容来源于stack exchange,提问作者Jim
相关产品推荐
相关产品推荐

