我目前正在尝试在 Linux 下使用网络命名空间来模拟网络。我已经设置了节点并连接了它们,它们可以互相 ping 通,一次一跳。但我真的很难尝试启用 IP 转发。
我使用的是 Ubuntu Server 21.04,我的系统上的网络由 systemd-networkd 控制。 systemd的版本是247.3-3ubuntu3.4。net.ipv6.conf.all.forwarding
并且net.ipv4.ip_forward
已经启用。由于使用了networkd,因此还需要在配置文件中启用转发。对于我的命名空间之一,如下所示:
/etc/systemd/network/router1i.network:
[Match]
Name=router1i
[Network]
IPForward=yes
和/etc/systemd/network/router1i2.network:
[Match]
Name=router1i2
[Network]
IPForward=yes
这些 (router1i
和router1i2
) 都是 veth 接口,也是命名空间中唯一的 2 个接口。
如果我在命名空间中使用该命令ip -6 route get to fe80::1:0:200 iif router1i2
,我会得到正确的答案fe80::1:0:200 from :: dev router1i2 proto kernel metric 256 iif router1i2 pref medium
,因为该路由不涉及转发。如果我使用类似的命令ip -6 route get to fe80::1:0:200 iif router1i
,从另一个界面启动,答案突然是RNETLINK answers: Network is unreachable
。显然,转发未启用。
networkctl reconfigure router1i
我已经尝试通过使用名称空间内的方式进行网络更新,但它说Failed to reconfigure network interface router1i: No such device or address
.这很奇怪,因为当我使用 时networkctl status router1i
,它正确列出了所有信息。也已经尝试过完全重新加载networkctl reload
,并且不会改变任何内容。
老实说,我已经无计可施了。我什至不一定需要让它与网络一起工作。任何想法或解决方法将非常感激。
编辑:
我现在已按照 dirkt 的建议将链接本地地址与唯一本地地址交换。根据 的输出判断,现在已正确选择路线ip -6 route get
。但我仍然无法 ping 其他网络接口。我将在下面添加详细信息,因为老实说我找不到错误。
接口配置:
ubuntu@ubuntu:~$ sudo ip netns exec Router1 ip addr show
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
valid_lft forever preferred_lft forever
6: router1i@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether be:fc:8e:30:e4:18 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fd00:0:0:1000::1/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::bcfc:8eff:fe30:e418/64 scope link
valid_lft forever preferred_lft forever
8: router1i2@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether d6:3f:e9:9a:93:f3 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fd00:0:0:1001::1/63 scope global
valid_lft forever preferred_lft forever
inet6 fe80::d43f:e9ff:fe9a:93f3/64 scope link
valid_lft forever preferred_lft forever
IPv6 路由表:
ubuntu@ubuntu:~$ sudo ip netns exec Router1 ip -6 route
fd00:0:0:1000::/64 dev router1i proto kernel metric 256 pref medium
fd00:0:0:1000::/63 dev router1i2 proto kernel metric 256 pref medium
fe80::/64 dev router1i proto kernel metric 256 pref medium
fe80::/64 dev router1i2 proto kernel metric 256 pref medium
default via fd00:0:0:1001::2 dev router1i2 metric 1024 pref medium
输出ip netconf
:
ubuntu@ubuntu:~$ sudo ip netns exec Router1 ip netconf
inet lo forwarding on rp_filter loose mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
inet router1i forwarding on rp_filter loose mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
inet router1i2 forwarding on rp_filter loose mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
inet all forwarding on rp_filter loose mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
inet default forwarding on rp_filter loose mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
inet6 lo forwarding on mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
inet6 router1i forwarding on mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
inet6 router1i2 forwarding on mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
inet6 all forwarding on mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
inet6 default forwarding on mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
现在可以正常工作了:
ubuntu@ubuntu:~$ sudo ip netns exec Router1 ip -6 route get to fd00:0:0:1001::2 iif router1i
fd00:0:0:1001::2 from :: dev router1i2 proto kernel metric 256 iif router1i pref medium
但是当我尝试从 router1i 实际 ping 该地址时,它显示:
ubuntu@ubuntu:~$ sudo ip netns exec Router1 ping6 fd00:0:0:1001::2 -I router1i
ping6: connect: Network is unreachable
转发已经打开,并且选择了正确的路由,为什么还是不行呢?
编辑2:
我让它工作了!感谢所有试图提供帮助的人。
显然我错误地判断了带有 -I 选项的 ping 的作用。这让我很困惑,而我的经验不足并没有帮助...最后,我发现最后一个缺失的部分是外部命名空间之一中的错误路由,阻碍了它应答 ping。我应该早点找到这种方法,但我太沉迷于转发问题了......
不管怎样,再次感谢,祝你有美好的一天!
答案1
fe80::/10
是链接本地地址。我认为这些是不可路由的(尽管可能有一些技巧可以使它们可路由,但我从未尝试过)。
如果您想尝试 IPv6 路由,请不要使用这些;相反,分配唯一的本地地址fc00::/7
除了接口的链路本地地址(通常是自动配置的)之外,还有es (ULA, range )。
并且您还可以用于ip -6 route get from ... to ...
调试。
ip route add ...
在玩耍时像往常一样设置路线。
记住需要设置路线全部沿着数据包路径的节点(或者在您的情况下是命名空间),而不仅仅是“转发”节点(忘记这一点是典型的初学者错误)。
如果你不会因为尝试“从一个接口到另一个接口”(我假设使用-I
)而使你的生活变得困难,那么完成这项工作会更容易。
设置三个命名空间A、B、C。将A和B用veth对连接,将B和C用veth对连接。将 ULA 地址(具有正确的子网、A/B 一个子网、B/C 一个子网)放置在所有四个网络接口上。在 A 和 C 上设置默认路由(通过相应的 B 接口)。在 B 中启用转发。然后,在 A 中尝试 ping B 中近端接口上的地址,然后是 B 中“远”接口上的地址,然后是 C。只需使用 plain 即可ping <addr>
。查看它在哪里停止工作(如果它不能立即工作)。
要进行调试,请tcpdump
在所有四个接口上的四个终端中运行。在网络命名空间中运行一个xterm
(或多个),这使得调试和设置变得更加容易。
如果仍然不起作用,请提出一个新问题,包括您在上述设置中进行的所有命令,包括有效的 ping,对于无效的 ping,包括 tcpdump 输出。 (每个问答的远程调试是 PITA)。