19.1 Jail 基础
19.1.1 FreeBSD Jail 概述
Jail 原意为“监狱、监禁”,在本书中指一种基于 chroot 改进的容器隔离技术。
Jail 技术于 1999 年提交到 FreeBSD 源代码树,随 2000 年 3 月发布的 FreeBSD 4.0 首次正式引入,首次实现了文件系统、进程空间和网络资源的三重隔离。
Jail 的发音为 [dʒeɪl](英/美),发音接近汉语“杰尔”;“炸儿”为非标准发音。
19.1.2 创建 Jail 目录
19.1.2.1 获取 FreeBSD 基本系统文件
19.1.2.1.1 编译基本系统(可选)
创建 Jail 根目录(不存在则递归创建):
# mkdir -p /usr/jail进入 FreeBSD 源代码目录:
# cd /usr/src编译整个用户空间(world):
# make buildworld将编译结果安装到 /usr/jail:
# make installworld DESTDIR=/usr/jail安装默认系统配置文件到 /usr/jail:
# make distribution DESTDIR=/usr/jail19.1.2.1.2 解压分发文件(可选)
可通过下载或从 ISO 镜像中提取 base.txz 分发文件,将其解压到 Jail 目录。
# tar -xJf base.txz -C /usr/jaildevfs 文件系统提供系统设备节点的访问接口,使 Jail 内的应用程序能够受控地访问底层硬件设备。推荐挂载 devfs 以便 Jail 访问必要的设备文件。
# mount -t devfs devfs /usr/jail/dev相关文件结构:
/
├── usr
│ ├── jail
│ │ └── dev # devfs 挂载点
│ └── src # FreeBSD 源代码路径
└── etc
├── rc.conf # 系统启动配置
├── jail.conf # Jail 配置文件
└── resolv.conf # DNS 配置19.1.2.2 在 /etc/rc.conf 文件中启用 Jail 服务
启用 Jail 服务开机自启动:
# sysrc jail_enable="YES"创建配置文件 /etc/jail.conf。也可写入 /etc/rc.conf 文件,但单独配置更便于管理,且服务配置和系统配置分离,便于独立维护和版本管理。
www { # Jail 名称为 www
host.hostname = www.example.org; # 主机名
ip4.addr = 192.168.0.10; # IP 地址
path = "/usr/jail"; # jail 路径
devfs_ruleset = 4; # devfs 规则集编号
mount.devfs; # 挂载 devfs 文件系统到 jail
exec.start = "/bin/sh /etc/rc"; # 启动命令
exec.stop = "/bin/sh /etc/rc.shutdown jail"; # 关闭命令
}19.1.3 Jail 实例状态管理
使用 jls 命令可查看当前运行中的 Jail 信息。默认输出包含四列:Jail 标识符(jid)、IP 地址(ip4.addr)、主机名(host.hostname)和根目录路径(path)。jls -N 可将第一列替换为 Jail 名称(若无名称则回退为数字 ID),jls -v 则提供每个 Jail 的多行详细摘要,额外显示名称、dying 状态、cpuset ID 及 IPv6 地址等。
以下为 jls 命令的示例输出:
JID IP Address Hostname Path
3 192.168.0.10 www /usr/jail/www字段说明(中英对照):
| 英语 | 中文 |
|---|---|
| JID | Jail ID |
| IP Address | IP 地址 |
| Hostname | 主机名 |
| Path | Jail 路径 |
19.1.4 Jail 服务的启动与停止
使用 service 命令管理 Jail 的启动与停止:
# service jail start www # 启动 Jail www
# service jail stop www # 停止 Jail www也可以使用 jail 命令直接操作。-r 会终止指定 Jail 内的所有进程及其子 Jail,-rc 将先移除再重新创建(即重启)。此外 jail -cm 在 Jail 不存在时创建、已存在时修改:
# jail -c www # 启动 Jail www
# jail -r www # 移除 Jail www(终止所有进程及子 Jail)19.1.5 进入 Jail
使用 jexec 命令可在指定 Jail 中执行命令,支持以 JID 或 Jail 名称定位目标 Jail。jexec -l 使用纯净环境运行命令(仅保留 HOME、SHELL、TERM 等基本变量,PATH 设为 /bin:/usr/bin)。以下示例在 Jail ID 为 3 的环境中启动 Shell:
# jexec 3 /bin/sh19.1.6 正常关闭 Jail
在 Jail 中执行关机脚本可实现正常关闭。以下示例在 Jail ID 为 3 的环境中执行 /etc/rc.shutdown:
# jexec 3 /etc/rc.shutdown19.1.7 更新 Jail 系统
使用 freebsd-update 可更新指定 Jail 的系统。需将 /usr/jail/www 替换为实际的 Jail 路径:
# freebsd-update -b /usr/jail/www fetch # 获取指定 Jail 的系统更新
# freebsd-update -b /usr/jail/www install # 安装指定 Jail 的系统更新19.1.8 启用 ping 支持
如需在 Jail 中使用 ping 等需要原始套接字的工具,可在 /etc/jail.conf 文件中添加以下配置:
allow.raw_sockets=1; # 允许 Jail 使用原始套接字
allow.sysvipc=1; # 允许 Jail 使用 System V IPC配置完成后请重启 Jail 以使配置生效。
示例:启动 Jail test,并加载其配置文件。
# jail -c test19.1.9 DNS 网络配置
/etc/resolv.conf 用于配置域名系统参数,包括默认搜索域和 DNS 服务器地址。在 Jail 内创建并编辑该文件以设置 DNS:
search lan # 指定默认搜索域为 lan
nameserver 223.5.5.5 # 指定 DNS 服务器
nameserver 223.6.6.6 # 指定备用 DNS 服务器配置完成后,可在 Jail 内使用 nslookup 或 ping 测试 DNS 解析是否正常。ping 需要启用原始套接字,如前文所述。
19.1.10 故障排除与未竟事宜
19.1.10.1 删除文件时提示没有权限
系统不可修改(schg)标志是 FreeBSD 文件系统的安全特性,设置后可防止文件遭到意外或恶意修改、重命名或删除。即使是超级用户也无法直接操作,需先递归取消该目录及其内容的标志:
# chflags -R noschg directory请将“directory”替换为需要操作的目录路径。
19.1.10.2 证书验证失败
该问题表现为证书验证错误,报错信息包含 STORE routines:ossl_store_get0_loader_int:unregistered。确认系统时间正常后,此问题通常与 FreeBSD 14.1-RELEASE 和 14.2-RELEASE 中的证书数据库索引有关。
解决方法:更新证书数据库的哈希索引。
# certctl rehash重新执行 pkg 命令。如问题仍存在,可清除 pkg 缓存:# pkg clean -a。
19.1.11 参考文献
- Rostislav M. Georgiev. The Story of Containers[EB/OL]. VMware. (2018-02-27)[2026-04-17]. https://blogs.vmware.com/opensource/2018/02/27/the-story-of-containers/. 虽然更早的 chroot(1979 年引入 UNIX V7)已提供了文件系统隔离,但并不涉及进程和网络的隔离。
- FreeBSD Project. Bug 280031 - Cannot install pkg due to 404 on pkg.freebsd.org[EB/OL]. [2026-03-25]. https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=280031. 该报告记录了 FreeBSD 14.x 证书验证问题及解决方案,为同类问题提供了重要参考。
- FreeBSD Forums. Cannot fetch (and install) pkg[EB/OL]. (2024-06-28)[2026-03-25]. https://forums.freebsd.org/threads/cannot-fetch-and-install-pkg.93976/. 社区讨论提供了问题复现与
certctl rehash命令的应用场景。 - FreeBSD Project. jail -- manage system jails[EB/OL]. [2026-04-14]. https://man.freebsd.org/cgi/man.cgi?query=jail&sektion=8. Jail 管理工具手册页,涵盖创建、修改与删除 Jail 的参数与操作。
- FreeBSD Project. jail.conf -- configuration file for jail(8)[EB/OL]. [2026-04-14]. https://man.freebsd.org/cgi/man.cgi?query=jail.conf&sektion=5. Jail 配置文件格式手册页,定义参数语法与伪参数。
- FreeBSD Project. jail_set -- create or manage jails[EB/OL]. [2026-04-14]. https://man.freebsd.org/cgi/man.cgi?query=jail_set&sektion=2. Jail 系统调用手册页,描述内核级 Jail 参数管理接口。
- FreeBSD Project. jls -- list jails[EB/OL]. [2026-04-14]. https://man.freebsd.org/cgi/man.cgi?query=jls&sektion=8. 列出运行中 Jail 的工具手册页。
- FreeBSD Project. jexec -- execute command inside an existing jail[EB/OL]. [2026-04-14]. https://man.freebsd.org/cgi/man.cgi?query=jexec&sektion=8. 在指定 Jail 中执行命令的工具手册页。
- Kamp P H, Watson R N M. Jails: Confining the Omnipotent Root[C]//Proceedings of the 3rd International SANE Conference. 2000. 原始 Jail 论文,系统阐述了文件系统、进程空间与网络资源三重隔离的设计目标与实现机制。
- FreeBSD Wiki. Jails[EB/OL]. [2026-04-16]. https://wiki.freebsd.org/Jails. 记载“Jails were introduced by Poul-Henning Kamp in March 2000 with FreeBSD 4.0-RELEASE”。