高级信息
Machines involved:
A := vpn server inet 10.9.0.1 peer 10.9.0.2 tun0
B := vpn server inet 10.8.0.1 peer 10.9.0.2 tun2
vpn client inet 10.9.0.6 peer 10.9.0.5 tun1
C := vpn client inet 10.8.0.6 peer 10.9.0.5 tun0
描述
一共有三台机器。机器 B 运行 openvpn 服务器和客户端。现在,当机器 A 推redirect-gateway def1
送到机器 B 时,机器 C 显然无法连接到机器 B 上的 openvpn-server,因为由于路由的原因,vpn-server 回复数据包被路由到机器0.0.0.0/1 via 10.9.0.5, 128.0.0.0/1 via 10.9.0.5
A。现在我需要策略路由来通过计算机的 B WAN 网关路由数据包。
尝试1失败
我尝试使用以下命令标记从 VPN 服务器发送的数据包:
iptables -t mangle -A OUTPUT -p tcp -m multiport --sports 1194 -j MARK --set-xmark 14
ip route add table 14 default via WAN_IP
ip rule add fwmark 14 table 14
但它们仍然被路由到机器 A,我可以tcpdump -i tun1
在机器 B 和tcpdump -i tun0
机器 A 上观察到。
**machine B**
eth0:
22:22:33.734511 IP machine_C_IP.54089 > machine_B_IP.1194: UDP, length 86
tun1:
22:32:42.713371 IP 10.9.0.6.1194 > machine_C_IP.34514: UDP, length 94
**machine A**
tun0:
20:47:47.769628 IP machine_A_IP.openvpn > machine_C_IP.40287: UDP, length 94
尝试2失败
我还尝试由 openvpn 进程的所有者标记数据包。我添加到[电子邮件受保护] Group = vpnserver
进而:
iptables -t mangle -A OUTPUT -m Owner --gid-owner vpnserver -j MARK --set-xmark 14 ip 路由添加表 14 默认通过 WAN_GATEWAY ip 规则添加 fwmark 14 表 14
但数据包仍然被路由到机器 A。
工作尝试
以下方法可行,但我想避免使用它,因为它不方便,因为我必须通过 IP 为每个客户端添加路由。有些客户端也有动态 IP,因此我必须使用脚本通过域名检索正确的 IP。
ip route add table 14 default via WAN_IP
ip rule add to machine_C_IP table 14
抽象的
也许标记的数据包无法正确路由,因为 iptables 的 OUTPUT 链在实际路由之后应用?或者我在标记数据包时错过了什么?是否有其他方法将传出 VPN 服务器数据包路由到我的 WAN 网关?
当前状态
航线default via WAN_GATEWAY dev eth0 table 42
0.0.0.0/1 via 10.9.0.5 dev tun1
default via WAN_GATEWAY dev eth0 onlink
10.1.1.0/24 dev veth0 proto kernel scope link src 10.1.1.2
10.8.0.0/24 via 10.8.0.2 dev tun0
10.8.0.2 dev tun0 proto kernel scope link src 10.8.0.1
10.9.0.0/24 via 10.9.0.5 dev tun1
10.9.0.5 dev tun1 proto kernel scope link src 10.9.0.6
WAN_SUBNET/26 via WAN_GATEWAY dev eth0
WAN_SUBNET/26 dev eth0 proto kernel scope link src WAN_IP
MACHINE_A_IP via WAN_GATEWAY dev eth0
128.0.0.0/1 via 10.9.0.5 dev tun1
知识产权规则
0: from all lookup local
32760: from all fwmark 0xe lookup 42
32761: from all fwmark 0xa lookup 42
32764: from all to WAN_IP lookup 42
32765: from WAN_IP lookup 42
32766: from all lookup main
32767: from all lookup default
答案1
基于线程中之前的答案,这就是我在运行 OpenVPN 2.4.3 的 Ubuntu 17.10(巧妙)计算机上解决问题的方法。
1) 禁用反向路径过滤
我们需要更改单播反向路径转发宽松模式 ( rp_filter=2
) 而不是严格模式 ( rp_filter=1
)。在严格模式下,传入数据包必须在用于转发返回数据包的同一网络接口上接收。
sysctl -w net.ipv4.conf.<if>.rp_filter=2
<if>
计算机用于连接路由器的物理以太网接口在哪里。就我而言,该命令如下所示:sysctl -w net.ipv4.conf.enp2s0.rp_filter=2
。要读取内核参数,请使用sysctl net.ipv4.conf.<if>.rp_filter
.
要使更改在重新启动后保持不变,请在以下位置添加或更改此行/etc/sysctl.conf
:
net.ipv4.conf.<if>.rp_filter=2
2) 设置OpenVPN服务器标记加密数据包
在服务器.conf
文件中添加:
mark <value>
其中<value>
是用于标记数据包的任意唯一值。这将允许重新路由 OpenVPN 服务器加密的数据包。我用了mark 9
。
重新启动 OpenVPN 服务器。
3) 使用新的 ip 规则和 ip 路由将标记的数据包重新路由到路由器
ip rule add fwmark <value> table <N>
ip route add default via <router> table <N>
其中<N>
是路由表的任意唯一编号,<router>
是我的 LAN 中的路由器 IP 地址。换句话说,我执行了这些命令:ip rule add fwmark 9 table 42
和ip route add default via 192.168.8.1 table 42
。
在重新启动后使这些更改保持不变更加棘手,特别是对于使用新的 netplan 包而不是传统/etc/network/interfaces
文件来管理网络连接的 Ubuntu 17.10。由于缺乏更好的解决方案,我在OpenVPN systemd服务文件中添加了一系列命令。这将在 OpenVPN 启动之前创建 ip 规则和路由:ExecStartPre=-/sbin/ip rule add fwmark 9 table 42
和ExecStartPre=-/sbin/ip route add default via 192.168.8.1 table 42
。我-
在命令路径之前使用减号来确保即使命令失败服务器也会启动(如果规则或路由已经存在),请参阅systemd.service 手册页了解更多信息。
提示:我在计算机上将 OpenVPN 服务器作为 systemd 服务运行,在我的情况下解决此问题的最佳方法是将文件中 OpenVPN 服务器的详细程度增加到.conf
,6
然后使用 来journalctl -fu openvpn-server@<conf_file_name>.service
查看是否可以建立连接。如果未禁用反向路径过滤,当客户端尝试连接时,您甚至可能看不到任何活动。设置rp_filter
为2
(步骤 1)后,我可以看到一些活动,但 TLS 握手会失败。一旦我设法将 OpenVPN 数据包重新路由到路由器(步骤 2-3),我的客户端就能够连接。
答案2
为什么失败
尝试1失败和尝试2失败不起作用,因为 iptables 的链在路由决策之后运行,请参阅 iptables 的图表http://inai.de/images/nf-packet-flow.png。
除此之外,尝试2失败使用错误的方法设置 VPN 服务器实例的用户/组。您需要在 /etc/openvpn/server.conf 中指定用户或组,而不是在 systemd 单元文件中。 IE:
- 创建用户或组
adduser vpnserver
- 然后将用户或组添加到/etc/openvpn/server.conf
user vpnserver
- 验证 VPN 服务器进程以该用户/组的身份运行
ps -A o pid,cmd,user,group|grep vpn
解决方案
仅当进程设置了a时,才可以标记本地进程的数据包插座选项。 OpenVPN 支持: https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage
您可以使用 /etc/openvpn/server.conf 中的选项标记数据包--mark value
,然后使用ip rule add fwmark value table 42
with ip routes default via WAN_GATEWAY table 42
。
然后,机器 C 可以连接到机器 B 的 VPN 服务器。
选择
或者,您可以为 VPN 服务器和客户端使用 netns 命名空间,然后使用 iptables 的链。