我有一个物理网络,上面有一个 Linux 服务器(Ubuntu 16.04,内核 4.13)和几个小工具。每个小工具都有相同的不可更改的静态IP,例如192.168.0.222/24。我想通过任意 IP 协议(例如 ICMP ping 或自定义 UDP 协议)与所有这些小工具进行通信
幸运的是,我有一个连接服务器和小工具的托管网络交换机。我已将交换机配置为具有用于服务器的中继端口和每个小工具的访问端口,每个小工具位于不同的 VLAN(VID 11、12 等)上。
我已添加8021q
到 /etc/modules 并在 /etc/network/interfaces 中设置 VLAN 条目:
auto eno2 # For switch management interface
iface eno2 inet static
address 192.168.2.2/24
auto eno2.11 # Gadget 1 (only)
iface eno2 inet static
address 192.168.0.1/24
#auto eno2.12 # Gadget 2 - disabled
#iface eno2 inet static
# address 192.168.0.1/24
通过如上所示的条目,我可以与小工具 1 进行通信(例如ping 192.168.0.222
),并且看不到来自小工具 2 的任何流量。
但我希望能够同时与所有小工具进行通信,并能够区分其中一个。他们不需要互相交谈。我想为每个小工具创建一个唯一的主机 IP 和子网,例如
Host IP & subnet "Fake" gadget IP Actual gadget IP VLAN Interface
192.168.101.1/24 192.168.101.222 192.168.0.222 eno2.11
192.168.102.1/24 192.168.102.222 192.168.0.222 eno2.12
我会使用iptables
ornftables
来处理每个方向的翻译。然后我可以ping 192.168.101.222
到达小工具 1,并ping 192.168.102.222
到达小工具 2。从每个小工具的角度来看,它自己的 IP 仍然是 192.168.0.222,并且它会看到来自 192.168.0.1 的 ICMP 回显请求。
这似乎是 NAT 上的一个不寻常的变体。请注意,带有“假”IP 的流量不需要(也不应该)离开服务器 - 我们不会转发到网络上的其他地方。
- 这是解决问题的合理方法吗?
- 如何设置 /etc/network/interfaces 和 iptables 或 nftables 来实现此目的?
答案1
是的,这是合理的。
不幸的是,Linux DNAT(“目标重写 NAT”)仅限于预路由链。对于您的情况来说,这是一个 PITA,因为这意味着您:
(A)。在您的服务器上进行 DNAT,但是您只能使用这些地址外部服务器,而不是服务器本身;或者
(b).你人为地创建了上述情况,通过创建一个网络命名空间,使用 veth-pair 将网络命名空间连接到服务器主命名空间,然后在网络命名空间内进行 DNAT。这意味着您的所有 VLAN 接口也会进入网络命名空间。
我不知道为什么 Linux 网络人员要这样做,但事实就是如此。重写数据包的通用方法会非常方便......
谷歌搜索“网络命名空间”和“iptables DNAT”,这应该足以让你开始(除非其他人比我有更多的时间写一个逐步的答案......)
答案2
我能够通过以下nftables
规则集实现这一点(我必须nft
从源代码构建,因为 Ubuntu 16.04 附带的 v0.5 不支持数据包字段修改):
table ip mytable {
chain prerouting {
type filter hook prerouting priority -300; policy accept;
iifname "eno2.11" ip saddr 192.168.0.222 ip saddr set 192.168.101.222
iifname "eno2.12" ip saddr 192.168.0.222 ip saddr set 192.168.102.222
iifname "eno2.13" ip saddr 192.168.0.222 ip saddr set 192.168.103.222
}
chain output {
type filter hook output priority -300; policy accept;
ip daddr 192.168.101.222 ip daddr set 192.168.0.222
ip daddr 192.168.102.222 ip daddr set 192.168.0.222
ip daddr 192.168.103.222 ip daddr set 192.168.0.222
}
}
以及以下条目/etc/network/interfaces
:
auto eno2 # For switch management interface
iface eno2 inet static
address 192.168.2.2/24
auto eno2.11
iface eno2.11 inet static
address 192.168.101.1
netmask 255.255.255.0
auto eno2.12
iface eno2.12 inet static
address 192.168.102.1
netmask 255.255.255.0
auto eno2.13
iface eno2.13 inet static
address 192.168.103.1
netmask 255.255.255.0
这不会“解开”传出数据包的源 IP,即小工具仍然将来自服务器的请求视为来自 等192.168.101.1
,192.168.102.1
而不是192.168.0.1
- 在我的应用程序中,这并不重要,但可能可以通过中的附加规则来解决output
链。