AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 735931
Accepted
Oskar Stenberg
Oskar Stenberg
Asked: 2023-02-18 10:35:53 +0800 CST2023-02-18 10:35:53 +0800 CST 2023-02-18 10:35:53 +0800 CST

将流量路由到没有命名空间的网络虚拟副本

  • 772

给定下图,是否可以像这样通过 linux 内核路由流量?我希望模拟我的“内部”网络外部设备的精确副本,具有相同的 IP 范围,同时使内部和外部设备能够相互通信,而不知道对方具有与自身相同的 IP。

机器上网络接口的低级描述

例如:“内部”的设备 X 联系 192.168.3.5,这会转到中间人桥接并转发到 IP 为 192.168.2.5 的“外部”的设备 Y。然后将响应发送回中间人,并发送到 IP 为 192.168.2.5 的设备 X。

我知道这可以通过网络命名空间实现,并且可以使用它进行模拟。但是,我希望避免命名空间,而是针对不同的流量方向使用不同的路由表之类的东西。这可能吗?

如果我理解正确的话,由于重复的 IP 范围,我无法使用 NAT。它是否正确?

linux-kernel
  • 1 1 个回答
  • 21 Views

1 个回答

  • Voted
  1. Best Answer
    larsks
    2023-02-19T06:50:53+08:002023-02-19T06:50:53+08:00

    拓扑结构

    我们首先在 上配置网络接口middleman。我假设您已登录到系统控制台,或者您可以通过不涉及 或inner网络的界面进行访问outer。出于此答案的目的,我们将假设 interface middleman-eth0onmiddleman连接到“内部”网络并middleman-eth1连接到“外部”网络。这为我们提供了以下网络拓扑:

    网络拓扑图

    启用转发

    我们需要确保我们已经启用数据包转发middleman:

    sysctl -w net.ipv4.ip_forward=1
    

    我们应该从一个空的 netfilter 配置开始。运行iptables-save应该不会产生任何输出。

    接口配置

    为此, 和middleman-eth0都middleman-eth1将具有相同的网络配置:

    ip addr add 192.168.2.1/24 dev middleman-eth0
    ip addr add 192.168.2.1/24 dev middleman-eth1
    

    如果您认为这看起来很奇怪,那您是对的!目前,路由表middleman如下所示:

    192.168.2.0/24 dev middleman-eth1 proto kernel scope link src 192.168.2.1
    192.168.2.0/24 dev middleman-eth0 proto kernel scope link src 192.168.2.1
    

    这不会特别有用。

    VRF 配置

    我们将利用 Linux 对“虚拟路由和转发”(“VRF”)的支持。这允许我们在一个系统上创建多个隔离的路由域,这样传入的流量eth0将看到与传入的流量不同的路由表eth1。

    我们首先创建 VRF 接口:

    ip link add vrf-inner type vrf table 100
    ip link set vrf-inner up
    ip link add vrf-outer type vrf table 200
    ip link set vrf-outer up
    

    这些命令设置两个 VRF 设备,将每个设备与特定的路由表相关联。

    接下来,我们将每个物理接口附加到一个 VRF 设备:

    ip link set dev middleman-eth0 master vrf-inner
    ip link set dev middleman-eth1 master vrf-outer
    

    通过这些更改,主路由表现在为空:

    middleman# ip route show
    <no output>
    

    middleman-eth0在表 100 中,我们看到与(“内部”网络)相关的规则:

    middleman# ip route show table 100
    broadcast 192.168.2.0 dev middleman-eth0 proto kernel scope link src 192.168.2.1
    192.168.2.0/24 dev middleman-eth0 proto kernel scope link src 192.168.2.1
    local 192.168.2.1 dev middleman-eth0 proto kernel scope host src 192.168.2.1
    broadcast 192.168.2.255 dev middleman-eth0 proto kernel scope link src 192.168.2.1
    

    middleman-eth1在表 200 中,我们看到了(“外部”网络)的规则:

    middleman# ip route show table 200
    broadcast 192.168.2.0 dev middleman-eth1 proto kernel scope link src 192.168.2.1
    192.168.2.0/24 dev middleman-eth1 proto kernel scope link src 192.168.2.1
    local 192.168.2.1 dev middleman-eth1 proto kernel scope host src 192.168.2.1
    broadcast 192.168.2.255 dev middleman-eth1 proto kernel scope link src 192.168.2.1
    

    在这一点上,我们实际上有两个断开连接的网络,如下所示:

    显示隔离路由域的网络拓扑

    “内部”网络上的主机可以联系 192.168.2.1,他们将与middleman-eth0. “外部”网络上的主机也可以联系 192.168.2.1,但他们将与middleman-eth1.

    两人相遇的地方

    我们现在需要做的就是设置映射,这样任何一方都可以使用地址 from192.168.3.0/24来联系另一方的节点。

    首先,我们需要告诉所有节点,它们192.168.3.0/24通过 ; 路由到网络middleman;这意味着在所有节点上,在“内部”和“外部”网络上,我们需要:

    ip route add 192.168.3.0/24 via 192.168.2.1
    

    在 上middleman,我们需要 (a) 将192.168.3.0/24范围内的地址映射到范围内192.168.2.0/24,以及 (b) 确保在路由连接时使用正确的路由表。为了完成 (a),我们可以创建一些NETMAP规则:

    iptables -t nat -A PREROUTING -d 192.168.3.0/24 -j NETMAP --to 192.168.2.0/24
    iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -j NETMAP --to 192.168.3.0/24
    

    为了完成 (b),我们将首先根据入口接口标记数据包:

    iptables -t mangle -A PREROUTING -i middleman-eth0 -d 192.168.3.0/24 -j MARK --set-mark 100
    iptables -t mangle -A PREROUTING -i middleman-eth1 -d 192.168.3.0/24 -j MARK --set-mark 200
    

    然后使用这些标记来选择路由表:

    ip rule add prio 100 fwmark 100 lookup 200
    ip rule add prio 200 fwmark 200 lookup 100
    

    回想一下,表 100 具有“内部”网络的规则,表 200 具有“外部”网络的规则,因此这些规则表示“对于到达接口的数据包,使用与关联的路由表做出路由middleman-eth0决策middleman-eth1” ,反之亦然。

    随着弹跳球

    有了这一切,如果192.168.2.10“内部”网络上的节点尝试 ping 192.168.3.10:

    1. 由于192.168.3.0/24 via 192.168.2.1路由条目,数据包被路由到中间人
    2. 数据包到达middleman-eth0
    3. 数据包命中表链MANGLE并将PREROUTINGfwmark 设置为100
    4. 数据包命中NAT表链PREROUTING并将目标映射到192.168.2.10
    5. 数据包进入路由子系统,在那里它符合fwmark 100 lookup 200规则
    6. 在路由表 200 中,它命中了192.168.2.0/24 dev middleman-eth1,因此内核会将其发送到设备middleman-eth1
    7. NAT数据包到达POSTROUTING表链,它的源映射到表链192.168.3.10。
    8. 数据包到达地址为 的“外部”节点192.168.2.10。
    9. ……深吸一口气……
    10. 外节点发送回复到192.168.3.10
    11. 回复到达middleman-eth1
    12. 回复MANGLE命中PREROUTING表链并将 fwmark 设置为200
    13. 回复NAT命中PREROUTING表链并将目标映射到192.168.2.10
    14. 回复进入路由子系统,在那里它符合fwmark 200 lookup 100规则
    15. 在路由表 100 中,它命中192.168.2.0/24 dev middleman-eth0规则,因此内核将它发送到设备middleman-eth0
    16. 回复NAT命中POSTROUTING表链,它的源映射到192.168.3.10
    17. 回复到达“内部”节点192.168.2.10,它看到对其最初发出的请求的回复。

    验证

    如果在“内部”节点 0 ( 192.168.2.10) 上,我们尝试使用地址 ping“外部”节点 0 192.168.3.10,tcpdump -nn -i any icmp在内部节点 0 上运行显示:

    07:01:58.125370 innernode0-eth0 Out IP 192.168.2.10 > 192.168.3.10: ICMP echo request, id 12999, seq 1, length 64
    07:01:58.125533 innernode0-eth0 In  IP 192.168.3.10 > 192.168.2.10: ICMP echo reply, id 12999, seq 1, length 64
    

    我们看到middleman:

    07:01:58.125440 middleman-eth0 In  IP 192.168.2.10 > 192.168.3.10: ICMP echo request, id 12999, seq 1, length 64
    07:01:58.125459 middleman-eth1 Out IP 192.168.3.10 > 192.168.2.10: ICMP echo request, id 12999, seq 1, length 64
    07:01:58.125514 middleman-eth1 In  IP 192.168.2.10 > 192.168.3.10: ICMP echo reply, id 12999, seq 1, length 64
    07:01:58.125518 middleman-eth0 Out IP 192.168.3.10 > 192.168.2.10: ICMP echo reply, id 12999, seq 1, length 64
    

    在“外部”节点 0 上,我们看到:

    07:01:58.125489 outernode0-eth0 In  IP 192.168.3.10 > 192.168.2.10: ICMP echo request, id 12999, seq 1, length 64
    07:01:58.125497 outernode0-eth0 Out IP 192.168.2.10 > 192.168.3.10: ICMP echo reply, id 12999, seq 1, length 64
    

    所以我认为我们已经实现了您的目标!


    我使用mininet来测试这个配置;您可以在此处找到我的测试环境的完整资源。此处有此配置的实际操作视频。

    • 0

相关问题

  • 如何让我的帧缓冲控制台工作?

  • 阻止挂载系统调用

  • 为什么无线工具版本 30 成为永久测试版?

  • 程序堆栈大小

  • 哪些 802.11ac(或更高版本)WiFi 加密狗适用于 Linux 4.13 内核

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve