注:本文絕大部分內容來自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
同樣提供了一種隔離系統資源的方式,但由於網絡是相對來說更加敏感、更易出現安全問題的領域,因此提供多種隔離網絡的方式尤爲重要。