我想使用虚拟接口测试 NAT 表。我有连接到互联网的 enp1s0 接口,并已将 NAT 表配置为 MASQUERADE 数据包,如下所示。
random@debian:~$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host noprefixroute
valid_lft forever preferred_lft forever
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:54:00:4d:63:c0 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.10/24 brd 192.168.122.255 scope global enp1s0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe4d:63c0/64 scope link
valid_lft forever preferred_lft forever
3: dummy0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
link/ether 5e:81:f3:78:47:c0 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.10/24 scope global dummy0
valid_lft forever preferred_lft forever
inet6 fe80::5c81:f3ff:fe78:47c0/64 scope link
valid_lft forever preferred_lft forever
random@debian:~$ ip route
default via 192.168.122.1 dev enp1s0 onlink
10.0.0.0/24 dev dummy0 proto kernel scope link src 10.0.0.10
192.168.122.0/24 dev enp1s0 proto kernel scope link src 192.168.122.10
random@debian:~$ sudo sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
random@debian:~$ lsmod | grep dummy
dummy 16384 0
random@debian:~$ ipt
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
random@debian:~$ sudo iptables -t nat -A POSTROUTING -j MASQUERADE -s 10.0.0.0/24 -o enp1s0
random@debian:~$ ipt -t nat
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- any enp1s0 10.0.0.0/24 anywhere
有了这些 ip 配置。使用 ping 进行测试
random@debian:~$ ping -I 10.0.0.10 8.8.8.8
PING 8.8.8.8 (8.8.8.8) from 10.0.0.10 : 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=114 time=28.3 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=114 time=30.9 ms
^C
--- 8.8.8.8 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 28.302/29.583/30.865/1.281 ms
random@debian:~$ ping -I dummy0 8.8.8.8
PING 8.8.8.8 (8.8.8.8) from 10.0.0.10 dummy0: 56(84) bytes of data.
^C
--- 8.8.8.8 ping statistics ---
5 packets transmitted, 0 received, 100% packet loss, time 4095ms
通过虚拟接口发送数据包不起作用。可以使用 wireshark 观察到在虚拟接口 dummy0 中可以看到数据包,但数据包并未转发到 enp1s0。
虚拟接口不存在“另一端”(可能除了空之外)。换句话说,它与 并没有什么不同
lo
,只是人们通常会从除环回块之外的块配置地址(127.0.0.0/8
)。(坦率地说,我不确定现在在任何情况下人们是否真的需要虚拟接口。在我看来,它的存在更多的是出于历史原因。)无论如何,这里真正的问题并不完全是关于 dummy 的,而是关于
-I
in 的ping
。我见过很多人都有类似的误解,但我只能勉强看出/猜测它来自哪里,所以我只能希望以下解释能帮助你摆脱它:您可以将接口用作“源接口”这一事实并不意味着您可以模拟/仿真“源主机”,就像您从不同的网络 ping 时一样。这里的句子实际上只是意味着“忽略具有不同接口(
dev
)的路由”,或者换句话说,“无论如何都要确保流量仅通过此接口传出”。 (似乎如果目的地不在该接口的任何路由覆盖范围内,则目的地将被视为“onlink”。)换句话说,“源接口”并不意味着“入口接口”。
因此,当您
-I
在虚拟接口上使用时,唯一有意义的目的地将是虚拟接口本身上配置的 IP,这将导致环回流量。此类流量显然永远不会通过另一个接口(如)从主机传出enp1s0
。(显然环回流量甚至无法DNAT
进入PREROUTING
。)目的地为 eg 的流量8.8.8.8
实际上不会去往任何地方(而只是空洞)。(注意:事实上,准确地说,环回流量根本不会从主机中流出,因此我想至少在某种意义上,您可以将其视为通过
-I
相应路由“实现”的“例外”local
,因为虚拟接口仍然是它的路由接口,即使它导致流量环回并通过“进入”主机lo
。)话虽如此,仅与源地址(块)(例如)匹配的(
SNAT
非)规则将“适用于”此类环回流量。只是我看不出进行此类“测试”有什么意义。MASQUERADE
-o enp1s0
-s 10.0.0.0/24
要“测试”
MASQUERADE
规则,您需要通过特定接口(例如)传出enp1s0
的流量。因此,您需要(嗯,有点;请参阅最后一节)另一台“主机”作为“源主机”,该主机将与此主机形成一个网络,因此其源 IP 来自某个 IP 子网,该子网与接口(例如 )所连接的网络所使用的子网不同enp1s0
,因此需要伪装(如果该“另一侧”没有此子网的返回路由)。目前,“创建”网络/(网络方面)主机的最简单方法是 netns + veth 对。
请注意,
-I
当使用 IP 地址而不是接口作为参数时,工作方式会有很大不同。据我所知,在这种情况下它不会影响路由决策。基本上它只是预先设置流量的源 IP 地址,而不是不设置它并让系统根据路由决策/在路由决策之后为其选择一个。
因此,
MASQUERADE
规则实际上是必要的,并且可以“适用于”:但问题是,当您没有使用实际的东西进行测试时(我甚至没有谈论“测试网络”),该
MASQUERADE
规则最终应该服务于什么?这到底意味着什么?