我有 3 个 Linux 虚拟机,连接如下:
/ server1 \
| ens19 2001:1::2 |
\ /
|
/ \
| ens19 2001:1::1 |
| server2 |
| ens20 2001:2::1 |
\ /
|
/ \
| ens19 2001:2::2 |
\ server3 /
我在 server1 上运行这些命令:
ip link set dev ens19 up
ip -6 address add 2001:1::2/96 dev ens19
ip -6 route add default via 2001:1::1
然后在 server3 上这些:
ip link set dev ens19 up
ip -6 address add 2001:2::2/96 dev ens19
ip -6 route add default via 2001:2::1
然后在 server2 上这些:
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
ip link set dev ens19 up
ip link set dev ens20 up
ip -6 address add 2001:1::1/96 dev ens19
ip -6 address add 2001:2::1/96 dev ens20
如果我尝试从 server1 ping server3,它会起作用:
root@server1:~# ping6 2001:2::2
但是如果我将 server2 上的接口移动到网络命名空间内:
ip netns add net1
ip link set dev ens19 netns net1
ip link set dev ens20 netns net1
ip netns exec net1 ip link set dev ens19 up
ip netns exec net1 ip link set dev ens20 up
ip netns exec net1 ip -6 address add 2001:1::1/96 dev ens19
ip netns exec net1 ip -6 address add 2001:2::1/96 dev ens20
从 server1 到 server3 的 ping 操作不再有效。不再转发数据包。
为什么? (注:IPv4 的流程相同)
答案1
有两个步骤最初已完成但未完成再次在新的网络命名空间中:
echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
IPv4 和 IPv6 之间的行为恰好不同,如允许更改此默认行为的相对较新的网络切换中所述:devconf_inherit_init_net
:
[...]
默认情况下,我们保留当前行为:对于 IPv4,我们从 init_net 继承所有当前设置,并且对于 IPv6,我们将所有设置重置为默认值。
所以在新的网络命名空间中:
IPv4 转发继承自初始网络命名空间。由于它刚刚
echo 1 > /proc/sys/net/ipv4/ip_forward
在初始网络命名空间中运行启用,因此新的网络命名空间也被设置为 IPv4 路由器。所以它适用于 IPv4。
IPv6 重置为主机默认值而不是路由器在初始网络命名空间中所做的任何事情(除非例如运行前创建新的网络命名空间
sysctl -w net.core.devconf_inherit_init_net=1
:)
只需添加缺少的步骤,即可在新的网络命名空间中运行(/proc/sys/net/
是网络命名空间感知的)。如果没有一些体操,使用 stdout 重定向将无法正常工作,因此最好使用专用命令:sysctl
。
ip netns exec net1 sysctl -w net.ipv6.conf.all.forwarding=1