我有一个家庭网络,它由 192.168.1.0/24 子网中的多台机器组成。
我的朋友也有一个家庭网络,使用192.168.1.0/24子网。
如果我使用 OpenVPN(tap,而不是 tun)连接到我的家庭网络并尝试访问我的机器(例如)192.168.1.197,我很确定我的客户端不知道将这些数据包路由到哪里,因为两个网络都使用相同的子网,并且该 IP 也可以在两个网络中使用。
无论我从哪里连接到家庭 VPN,我该如何可靠地解决这个问题?
我是否必须更改我的家庭网络以使用不同的子网?或者我应该在 OpenVPN 上使用“推送路由”?最佳解决方案是什么?
答案1
这是一个常见的抱怨。
对于点对站点连接,即单个工作站通过 VPN 连接到远程网络,只要您禁用拆分隧道并强制所有流量通过隧道,您就可以使其工作,这意味着您只能在连接时使用远程网络。您的 VPN 客户端必须具有本地虚拟适配器,并且可以配置为所有流量都直接进入隧道。有些客户端可以这样配置,但有些则不能。通过连接到远程站点,您将失去访问本地网络的能力。如果网络 ID 冲突,则无法同时访问它们。
对于站点到站点连接,您无法使用标准家庭网络设备解决此问题。对于预算不多的非企业用户来说,唯一可用的选项是将其中一个网络更改为使用另一个 IP。这就是为什么在定义 /24 网络时最好避免在第 3 个八位字节中使用常见网络 ID。特别是避免使用 .0.、.1.、.254. 等。
答案2
是的,这是一个众所周知的问题,因此它有一个非常简单的解决方案。重新编号其中一个网络以使它们不会发生冲突。这是迄今为止最推荐的解决方案,如果你没有足够强烈的反对理由(你当然不要,你应该走这条路。
对于那些可能对其他解决方案感兴趣的人,我记得有关 OpenVPN 的主要可靠信息来源是man openvpn
。它列出了所有功能及其使用方法。阅读它时,您可能会发现一个选项client-nat
,它基本上是由 OpenVPN 程序执行的无状态一对一 NAT。在这种情况下,它使每个人都将另一侧视为其他网络。这非常令人困惑。让我们添加以下内容作为示例:
...
push "client-nat snat 192.168.1.0 255.255.255.0"
push "client-nat dnat 192.168.2.0 255.255.255.0"
...
到服务器上这个有故障的客户端CCD文件。然后,客户端将在IP 192.168.2.x下看到服务器的资源192.168.1.x。
使用verb 6
OpenVPN 在其日志中解释它正在做什么。
另一种方法是在一侧的操作系统中运行类似的 NAT(例如,使用 Linux 的NETMAP
iptables 目标或其路由引擎无状态 NAT 功能)。我再次警告,这是极其令人困惑,除非迫不得已,否则不应使用此功能。每次运行这样的配置时,都会有一只无辜的小猫突然在某处死去。不要这样做。
答案3
如果我使用 OpenVPN(tap,而不是 tun)连接到我的家庭网络并尝试访问我的机器(例如)192.168.1.197,我很确定我的客户端不知道将这些数据包路由到哪里,因为两个网络都使用相同的子网,并且该 IP 也可以在两个网络中使用。
通常你的客户将要“知道”,因为它的路由表为每个子网路由设置了优先级——/24 路由之一将始终具有更高的优先级,通常是 VPN 路由。因此,一旦您连接到 VPN,整个 /24 都会通过 VPN 进行路由。
换句话说,它不会尝试了解每个地址的路由,它只关心一次路由整个子网。(这类似于连接到两个不同的 192.168.1.x 以太网网络;操作系统将始终优先考虑其中一个网络。)
这做意味着一旦您连接到 VPN,您就无法再访问“本地” 192.168.1.197 - 它将始终转到“VPN” 192.168.1.197 - 但通常这是可以接受的。
[如果您的“本地”子网小于 VPN(例如,如果本地子网是 /25 或 /26),则可能会出现问题……但对于 192.168.x 网络来说,这种情况不太可能发生。]
无论我从哪里连接到家庭 VPN,我该如何可靠地解决这个问题?
在家庭网络上设置 IPv6。不一定是 ISP 提供的完整 IPv6 – 只需 VPN 内部使用的“本地”IPv6 范围即可。
fd00::/8
是 IPv6“本地”地址前缀,类似于三个“本地”IPv4 前缀。但与 IPv4 不同,家庭网络通常从 192.168.0.0/16 中挑选出一个 /24(因此只有 256 个选项可供选择),而在 IPv6 中,你应该挑选一个随机生成/48 与 fd00::/8 的冲突概率只有 1/2 40。如果您将整个 /64 随机化(即添加随机子网 ID),则冲突概率将增加到1/2 56 。
因此,如果你按照规则行事,并随机生成它,你的主 fdXX/64 将几乎从不与您可能访问的任何其他人的 fdXX/64 冲突。(当然,不要因为输入方便就选择 fd00:0:0:0::/64...)