注:本文绝大部分内容来自Linux Namespaces实践part 7,原文系列文章详细描述了Linux Namespace相关内容,英语过关的建议阅读原文,本文内容主要用来记录学习内容,如有不当之处还请评论区指正。
Network Namespace
隔离了系统中的网络设备、地址、端口、路由以及防火墙等。
基础网络Namespace管理
- 通过
CLONE_NEWNET
标志创建,需要root权限 ip netns
命令提供了更便捷的Network Namespace
操作,需要root权限ip netns add netns1
: 创建名为netns1
的Network Namespace
- 该命令会在
/var/run/netns
下创建一个bind mount,因此即便netns1
中的进程都结束该Namespace也会保留
- 该命令会在
ip netns exec netns_name cmd
: 在netns_name
指定的Namespace中执行cmd
中的命令,例如如下命令root@jeffrey:/home/eric# ip netns add netns1 root@jeffrey:/home/eric# ip netns exec netns1 ip link list 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
ip netns delete netns1
: 该命令会移除指向netns1
的bind mount,但是该Namespace本身并不会移除,其内部的进程都结束后会自动结束
Network Namespace 配置
- 新创建的
Network Namespace
只会有一个本地环回(loopback)设备,但第一次创建时环回设备未启用,需要使用ip netns exec netns_name ip link set dev lo up
命令启用,如下命令展示了这一情况:root@ubuntu-server:/home/eric# ip netns exec netns1 ping localhost connect: Network is unreachable root@ubuntu-server:/home/eric# ip netns exec netns1 ip link set dev lo up root@ubuntu-server:/home/eric# ip netns exec netns1 ping localhost PING localhost (127.0.0.1) 56(84) bytes of data. 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.108 ms ^C --- localhost ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4035ms rtt min/avg/max/mdev = 0.063/0.086/0.108/0.022 ms
- 连接到硬件的物理设备只能存在于
root namespace
中,每个虚拟网卡或桥接设备可以分配给其它namespace
,但只能分配给单个namespace
中 - 若要使
netns1
与root namespace
通信,需要建立虚拟网络设备:root@ubuntu-server:/home/eric# ip link add veth0 type veth peer name veth1 # 添加一对相连的虚拟设备 veth0 veth1 root@ubuntu-server:/home/eric# ip link set veth1 netns netns1 # 将 veth1 分配到 netns1 中 root@ubuntu-server:/home/eric# ip netns exec netns1 ifconfig veth1 10.1.1.1/24 up # 配置并启用 netns1 中的 veth1 root@ubuntu-server:/home/eric# ifconfig veth0 10.1.1.2/24 up # 配置并启用 veth0 root@ubuntu-server:/home/eric# ping 10.1.1.1 # root namespace 中可以访问 veth1 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.058 ms ^C ... root@ubuntu-server:/home/eric# ip netns exec netns1 ping 10.1.1.2 # netns1 中可以访问 veth0 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.042 ms ^C ...
Network Namespace
不共享主机的路由表与防火墙规则:root@ubuntu-server:/home/eric# 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 root@ubuntu-server:/home/eric# ip netns exec netns1 iptables -L # ip表 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
- 若要使
netns1
中访问网络,可以- 配置桥接设备(bridge)
- 配置 IP forwarding + NAT
ip netns
命令可以通过名字或者PID标识一个Network Namespace
- 一个
Namespace
的非root用户只能访问分配给该Namespace
的网络设备- 如下命令将
vethX
设备分配给root namespace
中,并且其它namespace
的root用户都可以访问 - 通过配合使用
PID Namespace
或者Mount Namespace
可以使其它Network Namespace
对上述设备不可见
- 如下命令将
Network Namespace的用途
- 保证
namespace
中的进程无法访问外部网络资源- 即使一个处理网络请求的进程(例如web服务器)也可以被放入受限制的
namespace
中,这种情况下,打开的socket文件描述符fd依然能够访问 - 或者通过
Unix socket
将一个打开的文件描述符发送给受限制的namespace
中的进程 - 上述两种情况都保证进程无法访问除了打开的文件描述符外的网络资源
- 即使一个处理网络请求的进程(例如web服务器)也可以被放入受限制的
总结
Network Namespace
同样提供了一种隔离系统资源的方式,但由于网络是相对来说更加敏感、更易出现安全问题的领域,因此提供多种隔离网络的方式尤为重要。