![将一个接口转换为隧道接口](https://linux22.com/image/743895/%E5%B0%86%E4%B8%80%E4%B8%AA%E6%8E%A5%E5%8F%A3%E8%BD%AC%E6%8D%A2%E4%B8%BA%E9%9A%A7%E9%81%93%E6%8E%A5%E5%8F%A3.png)
我有一台带有 2 个 WAN 接口的服务器,eth1
以及eth2
。每个接口都连接了一个路由器,路由器为它们提供了以下 IP:192.168.3.101
和192.168.1.101
。
事情是这样的,我想完全避免流量通过eth1
,而是创建一个tun0
将所有流量eth1
应该接收的隧道。
我可以完全控制程序应该使用哪个接口(MPTCP 将使用可以到达服务器的所有接口),因此我准备了一个简单的 OpenVPN 客户端/服务器配置(绑定到local 192.168.3.101
),其中包含服务器 IP192.168.99.1
和客户端 IP 192.168.99.2
。这样我就有了一个可以正常工作的接口,可以192.168.99.1
毫无问题地向其发送/接收数据。
现在,当我想ifconfig.co
使用接口发送/接收数据时,问题就出现了tun0
。我原以为它会将数据发送eth1
到我的服务器,然后我的服务器将流量重定向到ifconfig.co
,但事实并非如此。它只是断开了连接:
如果我尝试使用接口eth1
,eth2
一切都会按预期进行。
我已经连续 7 个小时阅读/尝试了很多东西,现在我真的迷路了。我不确定发生了什么,也不知道我做错了什么。
我认为这是一个路由问题,因为当我尝试上述命令时,tcpdump 在服务器上没有显示任何内容。零数据包接收。这是我目前所得到的:
我看到一切都彼此平等,但是eth0
/eth1
正在工作,但tun0
事实并非如此。
为了以防万一,这是我的 OpenVPN 配置(简单的点对点配置):
;SERVER
dev tun
ifconfig 192.168.99.1 192.168.99.2
secret /etc/openvpn/static.key
keepalive 10 60
ping-timer-rem
persist-tun
persist-key
;CLIENT
dev tun
remote XXXXXXXXXXXX
resolv-retry infinite
local 192.168.3.101
lport 0
ifconfig 192.168.99.2 192.168.99.1
secret /etc/openvpn/static.key
keepalive 10 60
ping-timer-rem
persist-tun
persist-key
注意:我知道 VPN IP 的约定是10.*
,但我将其改为 ,192.168.*
以便拥有与其他 2 个接口类似的配置。
所有这些的原因是为了解决这个问题:https://github.com/Ysurac/openmptcprouter/issues/670#issuecomment-533816813
答案1
您正在尝试实施基于路由隧道模式的解决方案,但您的问题描述在我看来非常适合桥接分接模式。
OpenVPN 不仅可以对 IP 数据包进行隧道传输,还可以对整个以太网数据包进行隧道传输。简而言之,您可以将“mode tun”替换为“mode tap”,并删除 OpenVPN 配置中的所有 IP 地址分配。还可以删除所有非默认路由规则。然后,借助操作系统,您可以在 eth1 和 tap 接口之间建立桥梁。
在 Debian 中(/etc/network/interfaces):
iface eth1 inet manual
auto br0
iface br0 inet manual
bridge_ports eth1
bridge_stp off
bridge_fd 0
接下来,我们需要指示 OpenVPN 在启动后将 tapX 添加到 br0(这将进入 OpenVPN 配置):
script-security 2
up up.sh
为什么需要脚本安全请参阅https://community.openvpn.net/openvpn/wiki/OpenVPNBridging
up.sh脚本:
#!/bin/sh
bridge=br0
brctl addif "$bridge" "$1"
ip link set "$1" up
它使用 bridge-utils brctl,因为这个配置是在 debian 7 上完成的。现代系统应该使用现代 iproute2 套件中的 ip 实用程序,而不是过时的 bridge-utils、iputils 等等;我将把它留作家庭作业,如何使用 ip 向网桥添加接口,这并不难。
你看,我甚至没有配置任何 IP 地址。这是因为我的 OpenVPN 盒只会将以太网数据包从物理接口桥接到虚拟接口并返回。在 OSI 网络模型中,这算作第 2 层桥接,也就是说,就像你有一个以太网交换机一样。
运行 OpenVPN 的远程系统(“客户端”)将具有其 tap 接口,就像插入“服务器”的 eth1 所插入的同一以太网交换机一样:
(LAN) - [switch] ---ethernet-cable--- [eth1 tapX] ---virtual-ethernet-cable--- [tapY]
"switch" OpenVPN tunnel remote system
您可以在远程系统 (“客户端”) 上的 Tap 上运行 DHCP 客户端,它应该从 LAN 中的 DHCP 服务器接收 IP 地址。您也可以在那里进行桥接,这就像您使用以太网电缆连接远程站点一样。想象一下,您从一个站点到另一个站点运行一条长光纤线路,并用它来连接这些网络。
如果您希望“SERVER”也参与该网络,您可以在 br0 本身上配置 IP 地址,为此您将“手动”替换为“静态”甚至“dhcp”,这根本不会影响其切换功能。
Linux Netfilter 设置(防火墙)有特殊注意事项。前段时间有一个 sysctl 变量,用于控制桥接数据包是否通过“filter FORWARD”链,net.bridge.bridge-nf-call-iptables=1。据我所知,在现代系统中,默认情况下该变量为 0。如果有该变量,请将其设置为 0(在 /etc/sysctl.conf 中),或者制定在交换机端口之间传递数据包的规则。请参阅 iptables 手册中的“physdev match”。
请注意,您为系统指定的“服务器”和“客户端”名称纯粹是表面的,并不反映它们的协议角色。从 OpenVPN 的角度来看,两个系统是平等的,因为您以“传统”点对点模式配置了 OpenVPN。OpenVPN 中还有专用的“客户端-服务器”模式,其中实际上有两个不同的角色,多个客户端可以连接到单个 OpenVPN 服务器。我在这里提出的想法也适用于该模式。
另外,请注意,对于 OpenVPN,没有始终使用 10.* 的惯例。对于任何成熟的生产级 VPN 解决方案,都不可能有这样的惯例。您始终使用网络设计所需的网络编号。
UPD:在虚拟机内测试桥接时,请确保虚拟机管理程序允许在 VM 端口使用多个 MAC 地址。在 Hyper-V 中,该功能称为 MAC 欺骗,应启用。