Namespaces in operation, part 7: Network namespaces

自从上次我们研究 Linux 命名空间以来已经有一段时间了。我们的系列缺少了一篇,现在补上:网络命名空间。顾名思义,网络命名空间将网络设备、地址、端口、路由、防火墙规则等的使用划分在不同的盒子,基本上是在一个单独运行的内核实例中虚拟化网络。网络命名空间在 2.6.24 版进入内核,约 5 年前;大概一年后,它们才进入黄金时段。从那以后,它们似乎在很大程度上被开发人员忽略了。

基本的网络命名空间管理

与其他命名空间一样,通过将 CLONE_NEWNET 标志传递给 clone() 系统调用可创建网络命名空间。不过,可从命令行方便地使用 ip 网络配置工具来设置和使用网络命名空间。例如:

# ip netns add netns1

此命令创建了一个名为 netns1 的新网络命名空间。当 ip 工具创建网络命名空间时,它会在 /var/run/netns 下为其创建绑定挂载;这允许命名空间一直存在,即使没有进程在其中运行,还有助于操作命名空间自身。由于网络命名空间在可用之前需要大量配置,因此这些交给了系统管理员。

# ls  /var/run/netns
netns1

“ip netns exec”命令可在命名空间中运行网络管理命令:

# ip netns exec netns1 ip link list
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

此命令列出命名空间中的可见接口。可以使用以下命令删除网络命名空间:

# ip netns delete netns1

此命令将删除引用了给定网络命名空间的绑定挂载。但是,只要有进程在命名空间内运行,该命名空间就一直存在。

# ls  /var/run/netns
#

网络命名空间配置

新的网络命名空间将有一个环回设备,但没有其他网络设备。每个网络设备(物理或虚拟接口、网桥等)只能存在于单个网络命名空间中。此外,不能将物理设备(连接到实际硬件的设备)分配给除 root 外的命名空间。相反,可以创建虚拟网络设备(例如虚拟以太网或 veth)并将其分配给命名空间。这些虚拟设备允许命名空间内的进程通过网络进行通信;配置、路由等决定它们可以与谁通信。

首次创建时,新命名空间中的 lo 环回设备被关闭,因此即使 ping 环回设备也会失败:

# ip netns exec netns1 ping 127.0.0.1
connect: Network is unreachable

打开该接口便可 ping 环回地址:

# ip netns exec netns1 ip link set dev lo up
# ip netns exec netns1 ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.051 ms

但 netns1 和根名称空间之间仍然不能通信。为此,需要创建和配置虚拟以太网设备:

# ip link add veth0 type veth peer name veth1
# ip link set veth1 netns netns1

第一个命令设置一对已连接的虚拟以太网设备。发送到 veth0 的数据包将被 veth1 接收,反之亦然。第二个命令将 veth1 分配给 netns1 命名空间。

# ip netns exec netns1 ifconfig veth1 10.1.1.1/24 up
# ifconfig veth0 10.1.1.2/24 up

然后,这两个命令为两个设备设置 IP 地址。

# ping 10.1.1.1
PING 10.1.1.1 (10.1.1.1) 56(84) bytes of data.
64 bytes from 10.1.1.1: icmp_seq=1 ttl=64 time=0.087 ms
...

# ip netns exec netns1 ping 10.1.1.2
PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.
64 bytes from 10.1.1.2: icmp_seq=1 ttl=64 time=0.054 ms
...

如上面的 ping 命令所示,可以双向通信了。

不过,如前所述,命名空间并不共享路由表或防火墙规则,可通过在 netns1 中运行 route 和 iptables -L 来证明。

# ip netns exec netns1 route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.1.1.0        0.0.0.0         255.255.255.0   U     0      0        0 veth1

# ip netns exec netns1 iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

第一行命令将简单地显示数据包到 10.1.1 子网的路由(使用veth1),而第二行命令显示没有配置防火墙。这些都意味着从 netns1 发送到互联网的数据包将收到“network is unreachable”消息。如果需要的话,有几种方法可以将命名空间连接到互联网。可以在根名称空间和 netns1 的 veth 设备中创建网桥。或者,可以在根命名空间中配置 IP 转发和网络地址转换(NAT)。其中任何一种(还有其他的配置可能性)都允许 netns1 的数据包到达互联网,并在 netns1 中收到回复。

分配给命名空间(通过clone()、unshare() 或 setns())的非 root 进程只能访问在该命名空间的网络设备和配置 — 当然,root 可以添加并配置新设备。借助 ip netns 子命令,有两种寻址网络命名空间的方法:按名称(如 netns1)或按命名空间中进程的 ID。由于 init 通常位于根命名空间中,因此可以使用如下命令:

# ip link set vethX netns 1

这将把一个(可能是新创建的)veth 设备放入根名称空间,它将为来自任何其他命名空间的 root 用户工作。如果不希望 root 用户执行网络命名空间中的此类操作,可以使用 PID 和挂载命名空间来使得其他网络命名空间无法访问。

网络命名空间的使用

正如我们所看到的,一个命名空间的网络可以完全没有(或只是环回)任何功能,也可以完全访问系统的网络。这使得网络命名空间有许多不同的用例。

通过关闭命名空间内的网络,管理员可以确保其内运行的进程无法与命名空间外建立连接。即使进程由于某种安全漏洞而受到损害,它也无法加入僵尸网络或发送垃圾邮件。

即使是处理网络流量的进程(例如,web 服务器工作进程或 web 浏览器呈现进程)也可被放置到受限制的命名空间中。一旦远程终端建立了连接或到远程终端的连接被建立,则该连接的文件描述符可被通过 clone() 创建的新网络命名空间中的子进程处理。子进程会继承父进程的文件描述符,因此可以访问连接的描述符。另一种可能是,父进程通过 Unix 套接字将连接的文件描述符发送到受限网络命名空间中的进程。不管哪种情况,子进程或工作进程都无法建立其他网络连接,因为命名空间中缺少合适的网络设备。

命名空间还可以用来在一个单独的盒子中测试复杂的网络配置。另外,可以在更为密闭、防火墙更严格的命名空间中运行敏感服务。显然,还可通过网络命名空间为每个容器提供自己的网络视图,而不受容器外部进程的影响。等等。

命名空间通常提供了一种划分系统资源并将进程组与其他资源隔离的方法。网络命名空间大体也如此,但由于网络是安全的敏感区域,因此提供各种类型的网络隔离尤其重要。当然,同时使用多个命名空间类型可以为安全性和其他需求提供更多的隔离。


原文:https://lwn.net/Articles/580893/
公众号:Geek乐园
云+社区:https://cloud.tencent.com/developer/column/4124

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值