Creating a Linux Jail 手册:
https://docs.freebsd.org/en/books/handbook/jails/#thin-jail
FreeBSD系统里创建Linux的jail的思路是:
跟主系统启动Linux兼容层协议一样。主系统启动Linux是使用FreeBSD内核,然后使用Linux兼容层来实现Linux软件的运行(具体是Linux ABI 实现Linux的调用)。所以创建Linux jail,思路就是先创建一个FreeBSD的jail,然后里面使用debootstrap安装Ubuntu兼容系统。
先启动FreeBSD主系统linux兼容协议
配置linux兼容
sysrc linux_enable="YES"
启动linux兼容协议
service linux start
这样启动后,linux兼容要多大约内存耗费增加300k
使用OpenZFS创建一个轻量级jail的快照 a Thin Jail Using OpenZFS Snapshots
这部跟创建轻量级FreeBSD jail的方法一模一样,完全可以参考官网a Thin Jail Using OpenZFS Snapshots这部分,除了设置的名字不一样(名字也可以跟官方一样用ubuntu,但是我还是喜欢用ubjail1这个名字),其它都可以跟官方一样。
参考这里:https://skywalk.blog.csdn.net/article/details/154576901
先创建目录
zfs create -o mountpoint=/usr/local/jails zroot/jails
zfs create zroot/jails/media
zfs create zroot/jails/templates
zfs create zroot/jails/containers
创建一个模版
zfs create -p zroot/jails/templates/14.3-RELEASE
下载linux的base.txz
可以使用阿里镜像,非常快!
fetch https://download.freebsd.org/ftp/releases/amd64/amd64/14.3-RELEASE/base.txz -o /usr/local/jails/media/14.3-RELEASE-base.txz
# 阿里镜像 非阿里云也可以用
fetch https://mirrors.aliyun.com/freebsd/releases/amd64/14.3-RELEASE/base.txz -o /usr/local/jails/media/14.3-RELEASE-base.txz
下载完成解压
tar -xf /usr/local/jails/media/14.3-RELEASE-base.txz -C /usr/local/jails/templates/14.3-RELEASE --unlink
设定jail虚拟机相关
待用户空间提取到模板目录中,就需要通过以下命令将时区和 DNS 服务器文件复制到模板目录中:
cp /etc/resolv.conf /usr/local/jails/templates/14.3-RELEASE/etc/resolv.conf
cp /etc/localtime /usr/local/jails/templates/14.3-RELEASE/etc/localtime
升级补丁
将文件移动到模板中后,接下来的步骤是通过以下命令更新到最新的补丁级别:
freebsd-update -b /usr/local/jails/templates/14.3-RELEASE/ fetch install
生成快照
zfs snapshot zroot/jails/templates/14.3-RELEASE@base
创建Linux jail
创建一个普通的FreeBSD轻量级jail ,名字叫ubjail1,所以目录放在了zroot/jails/containers/ubjail1
zfs clone zroot/jails/templates/14.3-RELEASE@base zroot/jails/containers/ubjail1
一直到这一步,创建Linux jail的过程跟创建FreeBSD jail的步骤一模一样,就是创建了一个FreeBSD jail的快照。
启动和配置jail
跟普通的FreeBSD轻量级jail不一样,这里没有jail的配置文件(不先配置,先启动,最后还是要写一个配置文件),而是在启动jail的时候这样写命令配置并启动jail:
jail -cm \
name=ubjail1 \
host.hostname="ubjail1.example.com" \
path="/usr/local/jails/containers/ubjail1" \
interface="igb0" \
ip4.addr="192.168.1.12" \
exec.start="/bin/sh /etc/rc" \
exec.stop="/bin/sh /etc/rc.shutdown" \
mount.devfs \
devfs_ruleset=4 \
allow.mount \
allow.mount.devfs \
allow.mount.fdescfs \
allow.mount.procfs \
allow.mount.linprocfs \
allow.mount.linsysfs \
allow.mount.tmpfs \
allow.raw_sockets \
allow.socket_af \
allow.sysvipc \
enforce_statfs=1
注意,这里加上了4句官方手册里没有句子,否则网络不会通:
allow.mount.tmpfs \
allow.raw_sockets \
allow.socket_af \
allow.sysvipc \
启动成功:
ELF ldconfig path: /lib /usr/lib /usr/lib/compat
32-bit compatibility ldconfig path: /usr/lib32
Updating motd:.
Creating and/or trimming log files.
Clearing /tmp (X related).
Updating /var/run/os-release done.
Starting syslogd.
Starting cron.
Sat Nov 15 11:56:01 CST 2025
这时候jls看看,可以看到确实启动成功了
jls
JID IP Address Hostname Path
8 wwwjail /usr/local/jails/containers/wwwjail
9 datajail /usr/local/jails/containers/datajail
14 192.168.1.12 ubjail1.example.com /usr/local/jails/containers/ubjail1
配置jail的Linux部分
登录jail
jexec -u root ubjail1
可以看到当前还是FreeBSD的jail
jexec -u root ubjail1
root@ubjail1:/ # uname -a
FreeBSD ubjail1.example.com 14.3-RELEASE FreeBSD 14.3-RELEASE releng/14.3-n271432-8c9ce319fef7 GENERIC amd64
安装jammy
在jail里安装debootstrap,然后再安装Ubuntu的jammy版本:
pkg install debootstrap
debootstrap jammy /compat/ubuntu
如果pkg速度慢,就设置镜像
创建路径及文件 /usr/local/etc/pkg/repos/USTC.conf 来覆盖配置,文件内容如下:
ustc: {
url: "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/quarterly"
}
FreeBSD: { enabled: no }
debootstrap jammy /compat/ubuntu 的速度非常慢,不知道该怎么解决。
找到解决方法了:
在运行 debootstrap 命令时,可以通过 --mirror 参数指定国内的镜像源地址。以下是一些稳定且速度较快的国内镜像源:
清华大学镜像源:https://mirrors.tuna.tsinghua.edu.cn/ubuntu/
中国科学技术大学镜像源 (USTC):https://mirrors.ustc.edu.cn/ubuntu/
华为云镜像源:https://mirrors.huaweicloud.com/ubuntu/
阿里云镜像源:https://mirrors.aliyun.com/ubuntu/
网易镜像源:http://mirrors.163.com/ubuntu/
比如可以这样写:
debootstrap jammy /compat/jammy https://mirrors.aliyun.com/ubuntu/
然后写一个配置文件
写到/etc/jail.conf文件中:
ubjail1 {
# STARTUP/LOGGING
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";
exec.consolelog = "/var/log/jail_console_${name}.log";
# PERMISSIONS
allow.raw_sockets;
exec.clean;
mount.devfs;
devfs_ruleset = 4;
# HOSTNAME/PATH
host.hostname = "${name}";
path = "/usr/local/jails/containers/${name}";
# NETWORK
ip4.addr = 192.168.1.12;
interface = igb0;
# MOUNT
mount += "devfs $path/compat/ubuntu/dev devfs rw 0 0";
mount += "tmpfs $path/compat/ubuntu/dev/shm tmpfs rw,size=1g,mode=1777 0 0";
mount += "fdescfs $path/compat/ubuntu/dev/fd fdescfs rw,linrdlnk 0 0";
mount += "linprocfs $path/compat/ubuntu/proc linprocfs rw 0 0";
mount += "linsysfs $path/compat/ubuntu/sys linsysfs rw 0 0";
mount += "/tmp $path/compat/ubuntu/tmp nullfs rw 0 0";
mount += "/home $path/compat/ubuntu/home nullfs rw 0 0";
}
停机
service jail onestop ubjail1
重新启动
按照常规jail的方法启动
service jail start ubjail1
进入jail
注意进入方式跟普通FreeBSD jail不同,因为如果用同样的命令,进入的就是FreeBSD,只有靠chroot,可以进入Linux兼容环境
jexec ubjail1 chroot /compat/ubuntu /bin/bash
看看当前系统
jexec ubjail1 chroot /compat/ubuntu /bin/bash
root@ubjail1:/# uname -a
Linux ubjail1 5.15.0 FreeBSD 14.3-RELEASE releng/14.3-n271432-8c9ce319fef7 GENERIC x86_64 x86_64 x86_64 GNU/Linux
果然是linux了 。
后续工作
设置Ubuntu jammy加速
修改/etc/apt/sources.list文件,
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
# 以下安全更新软件源包含了官方源与镜像站配置,如有需要可自行修改注释切换
deb http://security.ubuntu.com/ubuntu/ jammy-security main restricted universe multiverse
# deb-src http://security.ubuntu.com/ubuntu/ jammy-security main restricted universe multiverse
# 预发布软件源,不建议启用
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse
# # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse
查看当前内存占用
Mem: 21M Active
linux内核起来还是有点占内存的,一个Linux jail几乎比主机+两个FreeBSD jail占用的都多。
但是也总共只占用了21M,还是相当可以的。全部内存信息:Mem: 20M Active, 259M Inact, 2451M Wired, 5068M Free

总结
这大约是第一次整明白FreeBSD轻量级Linux jail ,以前大部分时候都是用easyjail或者cbsd自动生成的。而且cbsd自动生成的Linux jail,有时候启动进去还是FreeBSD,这里也弄明白了,因为如果是用的Linux兼容技术,那么就不能直接用/bin/bash ,那个是FreeBSD,而是应该用chroot /compat/linux/ /bin/bash 进入的才是Linux jail !
看着步骤还是非常繁琐,直接用cbsd来安装要方便很多,可以参考这篇文档:https://skywalk.blog.csdn.net/article/details/139719880
调试
jail -cm启动的时候报错
jail: mount.devfs: /usr/local/jails/ubjail1/dev: No such file or directory
ifconfig: ioctl (SIOCDIFADDR): Can't assign requested address
jail: /sbin/ifconfig igb0 inet 192.168.1.22/24 -alias: failed
原来的命令:
jail -cm \
name=ubjail1 \
host.hostname="ubjail1.example.com" \
path="/usr/local/jails/ubjail1" \
interface="igb0" \
ip4.addr="192.168.1.22" \
exec.start="/bin/sh /etc/rc" \
exec.stop="/bin/sh /etc/rc.shutdown" \
mount.devfs \
devfs_ruleset=4 \
allow.mount \
allow.mount.devfs \
allow.mount.fdescfs \
allow.mount.procfs \
allow.mount.linprocfs \
allow.mount.linsysfs \
allow.mount.tmpfs \
enforce_statfs=1
手工创建这个目录试试:
sudo mount -t devfs devfs /usr/local/jails/ubjail1/dev
哦了,没有dev的报错了。后来弄明白了,不是这个问题,是目录写错了,应该是/usr/local/jails/containers/ubjail1 配置文件应该是:
jail -cm \
name=ubjail1 \
host.hostname="ubjail1.example.com" \
path="/usr/local/jails/containers/ubjail1" \
interface="igb0" \
ip4.addr="192.168.1.12" \
exec.start="/bin/sh /etc/rc" \
exec.stop="/bin/sh /etc/rc.shutdown" \
mount.devfs \
devfs_ruleset=4 \
allow.mount \
allow.mount.devfs \
allow.mount.fdescfs \
allow.mount.procfs \
allow.mount.linprocfs \
allow.mount.linsysfs \
allow.mount.tmpfs \
enforce_statfs=1
修改启动文件参数后,配置和启动完成:
ELF ldconfig path: /lib /usr/lib /usr/lib/compat
32-bit compatibility ldconfig path: /usr/lib32
Updating motd:.
Creating and/or trimming log files.
Clearing /tmp (X related).
Updating /var/run/os-release done.
Starting syslogd.
Starting cron.
Sat Nov 15 11:56:01 CST 2025
启动后无法连外网
发现没有ip
igb0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
options=4e527bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,WOL_MAGIC,VLAN_HWFILTER,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6,HWSTATS,MEXTPG>
ether 00:e2:69:13:67:f6
media: Ethernet autoselect (1000baseT <full-duplex>)
status: active
jail -cm \
name=ubjail1 \
host.hostname="ubjail1.example.com" \
path="/usr/local/jails/containers/ubjail1" \
interface="igb0" \
ip4.addr="10.168.1.12" \
exec.start="/bin/sh /etc/rc" \
exec.stop="/bin/sh /etc/rc.shutdown" \
mount.devfs \
devfs_ruleset=4 \
allow.mount \
allow.mount.devfs \
allow.mount.fdescfs \
allow.mount.procfs \
allow.mount.linprocfs \
allow.mount.linsysfs \
allow.mount.tmpfs \
enforce_statfs=1
在jail内部修改ip试试
echo 'ifconfig_igb0="inet 192.168.1.12 netmask 255.255.255.0"'
不行,用命令试试
ifconfig_igb0="inet 192.168.1.12 netmask 255.255.255.0"
defaultrouter="192.168.1.1"
不行,jail内部会报错:
/etc/netstart
Starting devd.
devd: Can't open devctl device /dev/devctl: No such file or directory
/etc/rc.d/devd: WARNING: failed to start devd
/etc/rc.d/hostid: WARNING: hostid: unable to figure out a UUID from DMI data, generating a new one
Setting hostuuid: 0f360e44-9944-41e5-b2ca-fdb949f43733.
Setting hostid: 0xbc850509.
ifconfig: up: permission denied
ifconfig: ioctl (SIOCAIFADDR): Operation not permitted
ifconfig: ioctl (SIOCAIFADDR): Operation not permitted
ifconfig: up: permission denied
Starting Network: lo0 igb0 cbsdbr0.
lo0: flags=1008049<UP,LOOPBACK,RUNNING,MULTICAST,LOWER_UP> metric 0 mtu 16384
options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
groups: lo
igb0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
options=4e527bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,WOL_MAGIC,VLAN_HWFILTER,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6,HWSTATS,MEXTPG>
ether 00:e2:69:13:67:f6
media: Ethernet autoselect (1000baseT <full-duplex>)
status: active
cbsdbr0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
options=0
ether 58:9c:fc:10:ff:83
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
groups: bridge
add host 127.0.0.1: gateway lo0 fib 0: Operation not permitted
add net default: gateway 192.168.1.1 fib 0: Operation not permitted
sysctl: net.inet.icmp.bmcastecho=0: Operation not permitted
sysctl: net.inet.icmp.drop_redirect=0: Operation not permitted
sysctl: net.inet.icmp.log_redirect=0: Operation not permitted
sysctl: net.inet.ip.forwarding=0: Operation not permitted
sysctl: net.inet.ip.sourceroute=0: Operation not permitted
sysctl: net.inet.ip.accept_sourceroute=0: Operation not permitted
sysctl: net.link.ether.inet.proxyall=0: Operation not permitted
add host ::1: gateway lo0 fib 0: Operation not permitted
add net fe80::: gateway ::1 fib 0: Operation not permitted
add net ff02::: gateway ::1 fib 0: Operation not permitted
add net ::ffff:0.0.0.0: gateway ::1 fib 0: Operation not permitted
add net ::0.0.0.0: gateway ::1 fib 0: Operation not permitted
sysctl: net.inet6.ip6.forwarding=0: Operation not permitted
尝试加入这几句
allow.raw_sockets \
allow.socket_af \
allow.sysvipc \
jail -cm \
name=ubjail1 \
host.hostname="ubjail1.example.com" \
path="/usr/local/jails/containers/ubjail1" \
interface="igb0" \
ip4.addr="192.168.1.12" \
exec.start="/bin/sh /etc/rc" \
exec.stop="/bin/sh /etc/rc.shutdown" \
mount.devfs \
devfs_ruleset=4 \
allow.mount \
allow.mount.devfs \
allow.mount.fdescfs \
allow.mount.procfs \
allow.mount.linprocfs \
allow.mount.linsysfs \
allow.mount.tmpfs \
allow.raw_sockets \
allow.socket_af \
allow.sysvipc \
enforce_statfs=1
网络终于通了,问题解决
apt update的时候报错 Updates for this repository will not be applied.
apt update
Get:1 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy InRelease [270 kB]
Get:2 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy-updates InRelease [128 kB]
Get:3 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy-backports InRelease [127 kB]
Get:4 http://security.ubuntu.com/ubuntu jammy-security InRelease [129 kB]
Get:5 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy/main amd64 Packages [1395 kB]
Get:6 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy/main Translation-en [510 kB]
Get:7 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy/restricted amd64 Packages [129 kB]
Get:8 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy/restricted Translation-en [18.6 kB]
Get:9 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy/universe amd64 Packages [14.1 MB]
Get:10 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy/universe Translation-en [5652 kB]
Get:11 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy/multiverse amd64 Packages [217 kB]
Get:12 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy/multiverse Translation-en [112 kB]
Reading package lists... Done
E: Release file for https://mirrors.tuna.tsinghua.edu.cn/ubuntu/dists/jammy-updates/InRelease is not valid yet (invalid for another 6h 36min 10s). Updates for this repository will not be applied.
E: Release file for https://mirrors.tuna.tsinghua.edu.cn/ubuntu/dists/jammy-backports/InRelease is not valid yet (invalid for another 4h 37min 57s). Updates for this repository will not be applied.
E: Release file for http://security.ubuntu.com/ubuntu/dists/jammy-security/InRelease is not valid yet (invalid for another 6h 33min 25s). Updates for this repository will not be applied.
我的理解是要等6个小时之后才可以update ?