动态地通过 VPN 路由所有流量

动态地通过 VPN 路由所有流量

我刚刚在服务器和客户端上安装了 openvpn。它似乎运行良好。

现在,我想根据需要通过互联网将来自我的客户端的所有流量通过我的 VPN 服务器路由,但只是在某些情况下,并非总是如此!

my client    <->    routeur    <->    internet    <->    vpn server
192.168.5.3       192.168.5.1                            public IP
192.168.100.6        <------- vpn -------->            192.168.100.1

我能够将流量路由到一个 IP 地址(谷歌)并 ping 它:

# ip route add 142.251.209.46 dev tun0 && ping -c 4 142.251.209.46 && ip route del 142.251.209.46 dev tun0
PING 142.251.209.46 (142.251.209.46) 56(84) octets de données.
64 octets de 142.251.209.46 : icmp_seq=1 ttl=107 temps=176 ms
64 octets de 142.251.209.46 : icmp_seq=2 ttl=107 temps=176 ms
64 octets de 142.251.209.46 : icmp_seq=3 ttl=107 temps=176 ms
64 octets de 142.251.209.46 : icmp_seq=4 ttl=107 temps=205 ms

--- statistiques ping 142.251.209.46 ---
4 paquets transmis, 4 reçus, 0 % paquets perdus, temps 3004 ms
rtt min/moy/max/mdev = 175,987/183,345/204,848/12,415 ms

但当我尝试路由所有流量时,

ip route add default dev tun0

我无法 ping 通互联网上的任何内容。并且

# ip route add default via 192.168.100.1
Error: Nexthop has invalid gateway.
# ip route add default via 192.168.100.1 dev tun0
Error: Nexthop has invalid gateway.

我尝试了很多方法,但都没有成功。

# ip addr list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 brd 127.255.255.255 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host proto kernel_lo 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether a8:a1:59:53:9b:9e brd ff:ff:ff:ff:ff:ff
    inet 192.168.5.3/24 brd 192.168.5.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::aaa1:59ff:fe53:9b9e/64 scope link proto kernel_ll 
       valid_lft forever preferred_lft forever
3: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/sit 0.0.0.0 brd 0.0.0.0
6: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 500
    link/none 
    inet 192.168.100.6 peer 192.168.100.5/32 scope global tun0
       valid_lft forever preferred_lft forever
    inet6 fe80::9295:73d5:f4b0:b892/64 scope link stable-privacy proto kernel_ll 
       valid_lft forever preferred_lft forever
# ip route list
default via 192.168.5.1 dev eth0 metric 2 
192.168.5.0/24 dev eth0 proto kernel scope link src 192.168.5.3 
192.168.100.1 via 192.168.100.5 dev tun0 
192.168.100.5 dev tun0 proto kernel scope link src 192.168.100.6

重启后无vpn:

# ip route list
default via 192.168.5.1 dev eth0 metric 2 
192.168.5.0/24 dev eth0 proto kernel scope link src 192.168.5.3

如果我的请求对大家来说不够清楚,我会澄清一下。我想在决定时将所有流量从我的客户端路由到 VPN 服务器。我希望能够打开终端,输入命令ip route...并让所有流量通过 VPN,然后再次打开我的终端输入另一个ip route...命令并让所有流量再次通过我的网关。就这样。

openvpn conf服务器:

tls-server
port 12112
proto udp
dev tun
ca keys/ca.crt
cert keys/vps1.crt
key keys/vps1.key
dh keys/dh.pem
server 192.168.100.0 255.255.255.0
persist-key
persist-tun
ifconfig-pool-persist ipp.txt
keepalive 10 120
user nobody
group nobody
status openvpn-status.log
log /var/log/openvpn/openvpn.log
verb 4

openvpn conf 客户端:

client
dev tun
proto udp
remote SERVER_IP 12112
resolv-retry 30
nobind
persist-key
persist-tun
ca keys/ca.crt
cert keys/client.crt
key keys/client.key
script-security 2
log /var/log/openvpn/openvpn.log
verb 4

答案1

我怀疑您需要vpn_public_ip via original_gateway,即vpn_public_ip via 192.168.5.1。因为当您替换原始默认路由时,它就没有有效的路由到达 VPN 服务器。


当您配置时default via vpn_internal_gateway,它将尝试通过 VPN 发送所有没有更具体路由的流量。这会成为一个小问题,因为 VPN 客户端本身需要能够与其服务器(或 Wireguard 情况下的其他对等方)进行通信。

让我们举个例子:

假设您的 VPN 服务器托管在203.0.113.5。我们还假设您的 VPN 为其客户端分配地址192.168.100.6,为其服务器/内部网关分配地址192.168.100.1

假设你将此作为你的路由表:

default via 192.168.100.1
192.168.100.0/24 dev tun0 scope link src 192.168.100.6

198.51.100.123如果您尝试向(目标网站/等)发出请求,则会发生以下情况:

  1. 要将数据包发送到198.51.100.123(目标网站/等),会选择路由表中最具体的匹配项。在这种情况下,因为default没有更具体的匹配项,所以它会将数据包转发到192.168.100.1

  2. 为了到达目的地,192.168.100.1它会发现该192.168.100.0/24子网位于本地网络上,因此不需要路由。它可以直接通过相关接口将该数据包发送出去。

  3. 该接口实际上是一个由 VPN 软件处理的软件 NIC(tun设备)。因此数据包到达 VPN 软件,然后 VPN 软件意识到需要将其发送到 VPN 隧道的另一端。

  4. 您的 VPN 软件将数据包封装在另一个数据包中,这次数据包的地址是 VPN 服务器:203.0.113.5。然后,该数据包将被发送到 VPN 服务器进行进一步处理。

  5. 所以现在我们需要向203.0.113.5(VPN 服务器)发送一个数据包。再次选择路由表中最具体的匹配项。同样是default,即通过192.168.100.1

你看到这里的问题了吗?你的 VPN 服务器现在正尝试发送198.51.100.123封装在另一个数据包(目标203.0.113.5,VPN 服务器)中的原始数据包(目标),但它是通过192.168.100.1(VPN 网关)发送的,然后到达 VPN 软件,该软件封装数据包并尝试将其发送到 VPN 服务器203.0.113.5,然后...

是的,我们陷入了循环。因为它试图将封装的数据包发送到 VPN 服务器,但却到达了客户端软件,而客户端软件只知道封装收到的任何数据包,并通过刚到达自身的相同方法将其发送出去。

那么我们该如何解决这个问题呢?

default via 192.168.100.1
192.168.100.0/24 dev tun0 scope link src 192.168.100.6
203.0.113.5 via 192.168.5.1
192.168.5.0/24 dev eth0 scope link src 192.168.5.3

请注意有两个附加条目。

第一个新行非常重要:它告诉系统203.0.113.5应该通过发送(VPN 公共 IP)192.168.5.1,即(可能)直接通向公共互联网的原始默认网关,并且不是通过 VPN。这可确保 VPN 客户端始终能够到达 VPN 服务器,并且不会尝试通过自身发送封装的数据包(目的地为 VPN 服务器)。由于此规则更具体,因此它优先于上一条规则default

最后一行应该默认存在,它有效地告诉系统您的 LAN 是本地网络,应该可以直接访问而无需路由。此行对于系统定位网关是必需的192.168.5.1


作为补充,有一种更方便的方法来添加高优先级的“默认”路由,而不必删除并稍后重新创建原始默认路由。考虑这个路由表:

default via 192.168.5.1
192.168.100.0/24 dev tun0 scope link src 192.168.100.6
203.0.113.5 via 192.168.5.1
192.168.5.0/24 dev eth0 scope link src 192.168.5.3
0.0.0.0/1 via 192.168.100.1
128.0.0.0/1 via 192.168.100.1

请注意,我们保留了default原样。但这仍然会通过 VPN 路由所有内容(VPN 公共 IP 除外)!怎么做到的?

default实际上相当于0.0.0.0/0,它涵盖了所有地址。还记得我们之前说过最具体的匹配获胜吗?原来空间0.0.0.0/0可以分成两半。网络对0.0.0.0/1128.0.0.0/1标识了这两半。它们一起覆盖了整个0.0.0.0/0网络,但由于它们是单独的条目,因此单独来看它们被认为更具体。

长话短说,这两行:

0.0.0.0/1 via 192.168.100.1
128.0.0.0/1 via 192.168.100.1

有效地覆盖了default路由。但这种方法的优点是您不需要删除实际的default,您可以让您的脚本简单地添加或删除两个新行,而其他所有内容保持不变。

相关内容