我想连接位于远程建筑物上的多个 LAN。
“中央”站点有一台运行 OpenVPN 的 Linux 计算机。每个远程站点还运行 OpenVPN。
- 中心站点有一个编号为 192.168.0.0/24 的 LAN
- 几个远程站点也编号为 192.168.0.0/24
- 我不能/不会/不想/无论如何修改 LAN 编号
- 我无法控制大多数远程 OpenVPN
然后我需要:
1. 定义虚拟 LAN
2. 为每个站点配置 1:1 NAT
3. 必须在中央路由器上配置 1:1 NAT
。
因此每个站点都可以看到有一个 10.10.x.0/24 LAN。
例如,当计算机想要访问站点 12 上的 192.168.0.44 时,它只需向 10.10.12.44 发送一个数据包
操作VPN对我来说不是问题。我目前连接了 60 多个站点。但我没有找到一种简单的方法来执行 1:1 NAT。
以下是从中央站点发送到远程站点的数据包及其响应数据包的示例:
我用 iptables NETMAP 做了一些测试,但我无法使其工作,因为我找不到在路由决策后修改源+目标的方法。
我宁愿避免使用新的--client-nat
OpenVPN 功能。
也许我必须强制路由ip route
?或者使用 循环两次进入网络堆栈veth
?
注意:我不想使用伪装。只有 1/1 NAT。
编辑:
常规的 openVPN 设置是不可能的。因为来自远程站点的数据包与来自另一个站点的数据包无法区分:两者都具有相似的源地址和目标地址,并且都来自相同的 tun(或 tap)接口。所以不可能对其进行源 NAT。
解决方案 1:在远程站点上进行 NAT。在我的情况下不可能。我必须只在中央站点上执行此操作。
解决方案 2:为每个远程站点设置一个 VPN。所以我会给每人一吨。我想这还可以。内存效率不是很高,但还可以。
解决方案 3:在 VPN 内为每个站点设置一条(未加密)隧道。这将为每个提供一个接口。简单的隧道不是跨平台的(据我所知)。例如GRE或ipip或sit对于Linux来说是可以的,但是一些远程站点只运行一台Windows计算机,所以在上面安装了openVPN。所以不可能建立一个简单的隧道。其他选择是使用更复杂的隧道(哪个?),但系统和系统管理员的开销可能比拥有多个 VPN 更大
解决方案4:编译最新的openVPN,因为它包含1:1 NAT功能。我这周测试一下。
答案1
一个非常基本的解决方案是:
1. 对服务器 + 客户端使用 OpenVPN 2.3 或更高版本(当前最新的是 2.3-alpha)
2. 使用下面的 OpenVPN 配置选项
3. 不要使用其他任何东西(没有 ipfilter,没有技巧)
在服务器端,您需要手动分配VPN地址(因此没有server
选项,您必须使用ifconfig
或ifconfig-push
):
# /etc/openvpn/server.conf
ifconfig 10.99.99.1 10.99.99.2
route 10.99.99.0 255.255.255.0
push "route 10.99.99.0 255.255.255.0"
push "client-nat dnat 10.99.99.11 255.255.255.255 10.10.111.11"
push "client-nat dnat 10.99.99.12 255.255.255.255 10.10.112.12"
push "client-nat dnat 10.99.99.13 255.255.255.255 10.10.113.13"
如果您想在路由器之间直接通信(通过 VPN 从远程站点),则需要route
和push route
和线路。否则你可以丢弃它们。 client-nat
ping 10.99.99.1
。
。
现在您必须选择一个虚拟网络地址。我保留了您在示例中使用的相同内容:10.10.0.0/16
您允许为此进行路由:
# /etc/openvpn/server.conf
route 10.10.0.0 255.255.0.0
push "route 10.10.0.0 255.255.0.0"
。
。
您现在必须指示客户端使用 1:1 NAT :
# /etc/openvpn/ccd/client_11
ifconfig-push 10.99.99.11 10.99.99.1
push "client-nat snat 10.99.99.11 255.255.255.255 10.10.111.11"
push "client-nat snat 192.168.0.0 255.255.255.0 10.10.11.0"
push "client-nat dnat 10.10.10.0 255.255.255.0 192.168.0.0"
iroute 10.10.11.0 255.255.255.0
iroute 10.10.111.0 255.255.255.0
第一行设置远程路由器地址。请注意需要特殊地址的 Windows 驱动程序。
第二行和最后一行允许远程路由器通过其 10.99.99.x 接口进行通信。
第三行和第四行执行源和目标 1:1 NAT
第五行告诉 OpenVPN 如何处理相应的数据包。
此方法允许连接具有相同(或不同)LAN 地址的站点,而无需任何影子主机。
答案2
我已经对真实接口做了类似的事情,但我不明白为什么它不适用于 VPN 接口。
这个想法是,当您在该路由器上的不同接口上使用相同的子网时,它会使路由变得复杂。基本上,当 10.10.13.123 的数据包进入路由器时,它会在路由到 192.168.0.123 之前进行 DNATed,因此您必须能够告诉路由它是用于 192.168.0.123在VPN13接口上。
这可以通过使用防火墙标记和使用这些标记的路由规则来完成。 SNAT 和 DNAT 将通过 NETMAP 防火墙目标完成。对于 SNAT,这是同样的问题,在 POSTROUTING 中,您丢失了数据包来自这个或那个接口的信息,并且它们都有源地址 192.168.0.x。因此,您还需要一个标记来将该信息从 mangle-PREROUTING 传送到 nat-POSTROUTING。您可以使用相同的标记,但这意味着这些数据包将使用备用路由表,因此您需要复制所有数据包的全局路由表。
对于每个网络,您需要执行以下操作:
lnet=192.168.0.0/24
if10=eth0 if11=tun0 if12=tun1 if13=tun2
n=0
for site in 10 11 12 13; do
table=$site
net=10.10.$site.0/24
n=$(($n + 1))
eval "interface=\$if$site"
inmark=$(($n * 2)) outmark=$(($n * 2 + 1))
iptables -t nat -A PREROUTING -d "$net" -j NETMAP --to "$lnet"
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -m mark --mark "$inmark"/0xf -j NETMAP --to "$net"
iptables -t mangle -A PREROUTING -i "$interface" -j MARK --set-mark "$inmark"/0xf
iptables -t mangle -A PREROUTING -d "$net" -j MARK --set-mark "$outmark"/0xf
ip rule add fwmark "$outmark"/0xf table "$table"
ip route add "$lnet" dev "$interface" table "$table"
done
上面,我们使用了前 4 位标记,允许最多 7 个网络以这种方式路由。