通过 openvpn 客户端路由 LAN IP 流量

通过 openvpn 客户端路由 LAN IP 流量

我正在尝试与局域网上的其他节点共享 vpn 客户端。我的局域网上有一个运行 openvpn 客户端的 ubuntu 服务器。以下是我的网络图:

在此处输入图片描述

该服务器还运行一些需要在 WAN 上访问的 Web 服务 - 当我打开 VPN 时,此设置有效,但服务不再可访问。根据此问题,我在 openvpn 配置中添加了以下内容:

route-nopull
route 192.168.4.50 255.255.255.255

当我跑步时IP 路由列表

default via 192.168.4.1 dev enp1s0 proto static metric 100
10.175.0.69 dev tun0 proto kernel scope link src 10.175.0.70
169.254.0.0/16 dev enp1s0 scope link metric 1000
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
172.18.0.0/16 dev br-616f4053c28b proto kernel scope link src 172.18.0.1
192.168.4.0/24 dev enp1s0 proto kernel scope link src 192.168.4.199 metric 100
192.168.4.50 via 10.175.0.69 dev tun0

使用 route-nopull 时,节点可以访问互联网,但不能通过 VPN

完整的 openvpn 配置(不含密钥):

dev tun
fast-io
persist-key
persist-tun
nobind
remote XXXXXXX 1195
#script-security 2
#up /etc/openvpn/up.sh

remote-random
pull
comp-lzo no
tls-client
verify-x509-name Server name-prefix
ns-cert-type server
key-direction 1
route-method exe
route-delay 2
tun-mtu 1500
fragment 1300
mssfix 1200
verb 3
cipher AES-256-CBC
keysize 256
auth SHA512
sndbuf 524288
rcvbuf 524288
auth-user-pass /etc/openvpn/login

route-nopull
route 192.168.4.50 255.255.255.255

更新:此脚本在启用 VPN 时运行。在最后两行中,我尝试允许特定端口上的数据绕过 VPN - 但这破坏了它。

#!/bin/sh
INTIF=enp1s0  # internal interface (your LAN)
EXTIF=tun0    # external interface (WAN via OpenVPN)

#iptables -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE

iptables -A FORWARD -i $EXTIF -o $INTIF -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i $INTIF -o $EXTIF -j ACCEPT

iptables -A FORWARD -i $EXTIF -o $EXTIF -p tcp --sport 7878 --dport 7878 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i $EXTIF -o $EXTIF -p tcp --sport 7878 --dport 7878 -j ACCEPT

答案1

首先,让我们看看你尝试过的选项。你只是告诉 OpenVPN在建立连接后通过 OpenVPN 连接route添加路由。告诉 OpenVPN 忽略从服务器获取的路由。这就是为什么你会得到192.168.4.50/32route-nopull

192.168.4.50 via 10.175.0.69 dev tun0

因此在服务器上,任何数据包 192.168.4.50将通过 VPN。这不是你想要的。另一方面,

default via 192.168.4.1 dev enp1s0 proto static metric 100

说要把任何数据包发送到互联网(例如来自 192.168.4.0) 到路由器。来自互联网的任何响应都将通过路由器直接发送到客户端。

这就是为什么您的客户端可以访问互联网(传出的数据包首先到达服务器,然后到达路由器;传入的数据包直接从路由器到达客户端,永远不会看到您在服务器上设置的路由),但不能通过 OpenVPN 访问。


你真正想要的是不是忽略来自服务器的路由(因为这些路由通常是为了0.0.0.0/1能够128.0.0.0/1保留default路由)将告诉服务器通过另一端的 OpenVPN 服务器访问互联网。因此您需要让 OpenVPN 设置这些路由,因为网关不会是静态 IP 地址。

一旦有了这些路由,来自客户端的数据包就可以顺利发送到 OpenVPN 连接。

但是答案呢?另一端的 ExpressVPN 服务器以多客户端模式运行,并假设您有一个 IP 地址(您的服务器),它应该向该地址发送数据包。要告诉服务器您在该地址后面有一个完整的子网(包括您需要答案的客户端),您需要该--iroute选项。这里你可以阅读关于为什么需要这样做的解释,这里这是 OpenVPN 的具体操作说明。如您所见,您需要客户端配置目录来设置选项iroute

但你无法控制服务器,所以你无法做到这一点。所以通过 OpenVPN 进行路由是不可行的。


因此,ExpressVPN 的整个设置仅适用于您这边的单个 IP 地址。但有一种方法可以假装您只使用这个单个 IP 地址:网络地址转换 (NAT)。

互联网上有很多关于 NAT 的信息。您需要的简要信息如下:

INTIF=enp1s0  # internal interface (your LAN)
EXTIF=tun0    # external interface (WAN via OpenVPN)

iptables -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE

此规则规定,所有通过外部 OpenVPN 接口发出的数据包都会被“伪装”,方法是将源地址重写为此接口上的地址。连接跟踪器会记住这一点,并确保以相反的方式重写答案。

您还可以确保只有传出的连接(或答案)通过以下规则进行转发:

iptables -A FORWARD -i $EXTIF -o $INTIF -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i $INTIF -o $EXTIF -j ACCEPT

假设唯一暴露给 WAN 的服务是在服务器上。

有多种方法可以使其永久生效,但 Docker 安装会使此过程稍微复杂一些,因为 Docker 通常也有很多 iptables 规则,您必须小心不要意外丢弃它们。此外,理想情况下,这应该只在 OpenVPN 连接建立时发生,并在连接结束时被拆除,因此最好的方法可能是在 OpenVPN 配置文件中设置适当的脚本。

看看--up--down中的其他脚本OpenVPN 文档

相关内容