FreeBSD VNET Jail
FreeBSD VNET Jail是一种 虚拟化 环境,对其中运行的进程的网络资源进行隔离和控制:
通过对VNET Jail创建单独的网络堆栈,确保Jail内网络流量与主机系统和其他Jail隔离
确保高级别网络隔离和安全性
可以为VNET Jail创建成 FreeBSD Thick(厚) Jail 或 FreeBSD Thin(薄) Jail
VNET Jail是一种专门针对网络的Jail,可以补充 thick jail
和 thin jail
的不足
创建bridge
创建VNET Jail的第一步是创建一个网桥(bridge):
bridge
ifconfig bridge create
通常输出显示(如果系统中还没有创建过brideg):
bridge
输出显示生成了 bridge0
bridge0
备注
我的 MacBook Pro 15" Late 2013 使用 FreeBSD无线网络BCM43602(通过wifibox) wifibox
实际上就是一个 bridge
,所以这步创建bridge我跳过,后续的Jail网卡是 addm
到 wifibox0
这个网桥上的。
创建网桥 bridge
之后,需要使用以下命令将其附加到物理网卡上,假设物理主机的有线网卡是 em0
则执行:
bridge
附加到物理网卡ifconfig bridge0 addm em0
为了能够在操作系统重启之后自动启动网桥,需要在 /etc/rc.conf
配置:
/etc/rc.conf
中配置网桥defaultrouter="192.168.1.1"
cloned_interfaces="bridge0"
ifconfig_bridge0="inet 192.168.1.150/24 addm em0 up"
备注
由于 FreeBSD无线网络BCM43602(通过wifibox) 已经包含了上述步骤,所以我的 MacBook Pro 15" Late 2013 不需要上述步骤。
后续实践步骤将在 wifibox0 这个网桥上进行,是我的实践案例,其中网段是 10.0.0.x
配置Jail
VNET Jail 只是在网络堆栈有特殊配置,其他部分和 FreeBSD Thick(厚) Jail / FreeBSD Thin(薄) Jail 是一样的,所以这里需要配置一个 Jail 可以是Thick也可以是Thin,甚至可以结合 FreeBSD Linux Jail 。
我的实践步骤在 FreeBSD Linux Jail d2l 上进行,也就是我已经完成了 d2l
这个Linux Jail配置和运行,现在来构建VNET部分:
d2l {
# 这里 devfs_ruleset 和Linux Jail的4不同
devfs_ruleset=5;
# 去除了 ip4.addr 配置
# VNET/VIMAGE
vnet;
vnet.interface = "${epair}b";
# NETWORKS/INTERFACES
$id = "9";
$ip = "10.0.0.${id}/24";
$gateway = "10.0.0.1";
$bridge = "wifibox0";
$epair = "epair${id}";
# ADD TO bridge INTERFACE
exec.prestart += "ifconfig ${epair} create up";
exec.prestart += "ifconfig ${epair}a up descr jail:${name}";
exec.prestart += "ifconfig ${bridge} addm ${epair}a up";
exec.start += "ifconfig ${epair}b ${ip} up";
exec.start += "route add default ${gateway}";
exec.poststop = "ifconfig ${bridge} deletem ${epair}a";
exec.poststop += "ifconfig ${epair}a destroy";
# MOUNT
mount += "devfs $path/compat/debian/dev devfs rw 0 0";
mount += "tmpfs $path/compat/debian/dev/shm tmpfs rw,size=1g,mode=1777 0 0";
mount += "fdescfs $path/compat/debian/dev/fd fdescfs rw,linrdlnk 0 0";
mount += "linprocfs $path/compat/debian/proc linprocfs rw 0 0";
mount += "linsysfs $path/compat/debian/sys linsysfs rw 0 0";
mount += "/tmp $path/compat/debian/tmp nullfs rw 0 0";
mount += "/home $path/compat/debian/home nullfs rw 0 0";
}
启动Jail
现在启动
d2l
Jail:
d2l
Linux Jailservice jail start d2l
启动以后在物理主机上 ifconfig
就能够看出和之前 FreeBSD Thin(薄) Jail / FreeBSD Linux Jail 的网络差异部分了:
ifconfig
输出lo0: flags=1008049<UP,LOOPBACK,RUNNING,MULTICAST,LOWER_UP> metric 0 mtu 16384
options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
inet 127.0.0.1 netmask 0xff000000
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
groups: lo
nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
wifibox0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
options=0
ether 58:9c:fc:10:60:55
inet 10.0.0.2 netmask 0xffffff00 broadcast 10.0.0.255
id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
member: epair10a flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
ifmaxaddr 0 port 5 priority 128 path cost 2000
member: tap0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
ifmaxaddr 0 port 3 priority 128 path cost 2000000
groups: bridge
nd6 options=9<PERFORMNUD,IFDISABLED>
tap0: flags=1008943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
options=80000<LINKSTATE>
ether 58:9c:fc:10:ff:b4
groups: tap
media: Ethernet 1000baseT <full-duplex>
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
Opened by PID 375
epair10a: flags=1008943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
description: jail:d2l
options=8<VLAN_MTU>
ether 02:39:45:0a:f6:0a
groups: epair
media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
请注意:
之前 FreeBSD Thin(薄) Jail / FreeBSD Linux Jail 是直接在
wifibox0
上绑定自己的IP地址的,也就是在inet 10.0.0.2
(第11行) 之后有inet 10.0.0.9
,但是现在这行inet 10.0.0.9
配置消失了新出现了一个
epair10a
设备,也就是 VNET Jaild2l.conf
配置中$epair
,此时在物理主机上看不到这个设备的IP地址
检查Jail
现在我们进入 d2l
Jail 检查: jexec d2l
在
d2l
Jail 中使用ifconfig
就可以看到$epair
的另外一头b
:
d2l
Jail 中使用 ifconfig
lo0: flags=1008049<UP,LOOPBACK,RUNNING,MULTICAST,LOWER_UP> metric 0 mtu 16384
options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
inet 127.0.0.1 netmask 0xff000000
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x7
groups: lo
nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
epair10b: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
options=8<VLAN_MTU>
ether 02:39:45:0a:f6:0b
inet 10.0.0.10 netmask 0xffffff00 broadcast 10.0.0.255
groups: epair
media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
此时
chroot
进入 Linux Jail 部分:
神奇的部分来了,此时在Linux环境执行 ifconfig
也能够看到完整的网卡:
d2l
chroot 的 Linux Jail 中使用 ifconfig
root@d2l:/ # chroot /compat/debian/ /bin/bash
root@d2l:/# uname -s -r -m
Linux 5.15.0 x86_64
root@d2l:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.10 netmask 255.255.255.0 broadcast 10.0.0.255
ether 02:39:45:0a:f6:0b (Ethernet)
RX packets 29 bytes 2540 (2.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 18 bytes 1379 (1.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=4169<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
inet 127.0.0.1 netmask 255.0.0.0
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 (UNSPEC)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
也就是说在 Linux Jail 中也能比较完整地使用网络堆栈了
现在验证 深度学习环境 ,终于能够正常运行 Jupyter - 数据科学开发平台 程序了(在 Linux Jail 中支持了socket)
备注
不过 VNET Linux 的网络依然不支持 UDP 协议,也不支持普通用户的ICMP
警告
我突然发现我可能搞错了,并不是Jail网络不支持UDP协议或者ICMP,有可能是Jail默认的安全限制。
在 man jail 8
中有众多的 allow.*
配置,其中就有限制 allow.raw_sockets
raw sockets 用于很多网络子系统配置和交互,会导致一些特殊问题。总之,太多配置选项需要挖掘。
参考
FreeBSD Jails And Networking 一篇分析FreeBSD Jail网络的好文,补充了Handbook