给定下图,是否可以像这样通过 linux 内核路由流量?我希望模拟我的“内部”网络外部设备的精确副本,具有相同的 IP 范围,同时使内部和外部设备能够相互通信,而不知道对方具有与自身相同的 IP。
例如:“内部”的设备 X 联系 192.168.3.5,这会转到中间人桥接并转发到 IP 为 192.168.2.5 的“外部”的设备 Y。然后将响应发送回中间人,并发送到 IP 为 192.168.2.5 的设备 X。
我知道这可以通过网络命名空间实现,并且可以使用它进行模拟。但是,我希望避免命名空间,而是针对不同的流量方向使用不同的路由表之类的东西。这可能吗?
如果我理解正确的话,由于重复的 IP 范围,我无法使用 NAT。它是否正确?
拓扑结构
我们首先在 上配置网络接口
middleman
。我假设您已登录到系统控制台,或者您可以通过不涉及 或inner
网络的界面进行访问outer
。出于此答案的目的,我们将假设 interfacemiddleman-eth0
onmiddleman
连接到“内部”网络并middleman-eth1
连接到“外部”网络。这为我们提供了以下网络拓扑:启用转发
我们需要确保我们已经启用数据包转发
middleman
:我们应该从一个空的 netfilter 配置开始。运行
iptables-save
应该不会产生任何输出。接口配置
为此, 和
middleman-eth0
都middleman-eth1
将具有相同的网络配置:如果您认为这看起来很奇怪,那您是对的!目前,路由表
middleman
如下所示:这不会特别有用。
VRF 配置
我们将利用 Linux 对“虚拟路由和转发”(“VRF”)的支持。这允许我们在一个系统上创建多个隔离的路由域,这样传入的流量
eth0
将看到与传入的流量不同的路由表eth1
。我们首先创建 VRF 接口:
这些命令设置两个 VRF 设备,将每个设备与特定的路由表相关联。
接下来,我们将每个物理接口附加到一个 VRF 设备:
通过这些更改,主路由表现在为空:
middleman-eth0
在表 100 中,我们看到与(“内部”网络)相关的规则:middleman-eth1
在表 200 中,我们看到了(“外部”网络)的规则:在这一点上,我们实际上有两个断开连接的网络,如下所示:
“内部”网络上的主机可以联系 192.168.2.1,他们将与
middleman-eth0
. “外部”网络上的主机也可以联系 192.168.2.1,但他们将与middleman-eth1
.两人相遇的地方
我们现在需要做的就是设置映射,这样任何一方都可以使用地址 from
192.168.3.0/24
来联系另一方的节点。首先,我们需要告诉所有节点,它们
192.168.3.0/24
通过 ; 路由到网络middleman
;这意味着在所有节点上,在“内部”和“外部”网络上,我们需要:在 上
middleman
,我们需要 (a) 将192.168.3.0/24
范围内的地址映射到范围内192.168.2.0/24
,以及 (b) 确保在路由连接时使用正确的路由表。为了完成 (a),我们可以创建一些NETMAP
规则:为了完成 (b),我们将首先根据入口接口标记数据包:
然后使用这些标记来选择路由表:
回想一下,表 100 具有“内部”网络的规则,表 200 具有“外部”网络的规则,因此这些规则表示“对于到达接口的数据包,使用与关联的路由表做出路由
middleman-eth0
决策middleman-eth1
” ,反之亦然。随着弹跳球
有了这一切,如果
192.168.2.10
“内部”网络上的节点尝试 ping192.168.3.10
:192.168.3.0/24 via 192.168.2.1
路由条目,数据包被路由到中间人middleman-eth0
MANGLE
并将PREROUTING
fwmark 设置为100
NAT
表链PREROUTING
并将目标映射到192.168.2.10
fwmark 100 lookup 200
规则192.168.2.0/24 dev middleman-eth1
,因此内核会将其发送到设备middleman-eth1
NAT
数据包到达POSTROUTING
表链,它的源映射到表链192.168.3.10
。192.168.2.10
。192.168.3.10
middleman-eth1
MANGLE
命中PREROUTING
表链并将 fwmark 设置为200
NAT
命中PREROUTING
表链并将目标映射到192.168.2.10
fwmark 200 lookup 100
规则192.168.2.0/24 dev middleman-eth0
规则,因此内核将它发送到设备middleman-eth0
NAT
命中POSTROUTING
表链,它的源映射到192.168.3.10
192.168.2.10
,它看到对其最初发出的请求的回复。验证
如果在“内部”节点 0 (
192.168.2.10
) 上,我们尝试使用地址 ping“外部”节点 0192.168.3.10
,tcpdump -nn -i any icmp
在内部节点 0 上运行显示:我们看到
middleman
:在“外部”节点 0 上,我们看到:
所以我认为我们已经实现了您的目标!
我使用mininet来测试这个配置;您可以在此处找到我的测试环境的完整资源。此处有此配置的实际操作视频。