Skip to content

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 根目录(不存在则递归创建):

sh
# mkdir -p /usr/jail

进入 FreeBSD 源代码目录:

sh
# cd /usr/src

编译整个用户空间(world):

sh
# make buildworld

将编译结果安装到 /usr/jail

sh
# make installworld DESTDIR=/usr/jail

安装默认系统配置文件到 /usr/jail

sh
# make distribution DESTDIR=/usr/jail

19.1.2.1.2 解压分发文件(可选)

可通过下载或从 ISO 镜像中提取 base.txz 分发文件,将其解压到 Jail 目录。

sh
# tar -xJf base.txz -C /usr/jail

devfs 文件系统提供系统设备节点的访问接口,使 Jail 内的应用程序能够受控地访问底层硬件设备。推荐挂载 devfs 以便 Jail 访问必要的设备文件。

sh
# mount -t devfs devfs /usr/jail/dev

相关文件结构:

sh
/
├── usr
   ├── jail
   └── dev        # devfs 挂载点
   └── src            # FreeBSD 源代码路径
└── etc
    ├── rc.conf        # 系统启动配置
    ├── jail.conf      # Jail 配置文件
    └── resolv.conf    # DNS 配置

19.1.2.2 在 /etc/rc.conf 文件中启用 Jail 服务

启用 Jail 服务开机自启动:

sh
# sysrc jail_enable="YES"

创建配置文件 /etc/jail.conf。也可写入 /etc/rc.conf 文件,但单独配置更便于管理,且服务配置和系统配置分离,便于独立维护和版本管理。

ini
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 命令的示例输出:

sh
JID IP Address    Hostname   Path
3   192.168.0.10  www       /usr/jail/www

字段说明(中英对照):

英语中文
JIDJail ID
IP AddressIP 地址
Hostname主机名
PathJail 路径

19.1.4 Jail 服务的启动与停止

使用 service 命令管理 Jail 的启动与停止:

sh
# service jail start www   # 启动 Jail www
# service jail stop www    # 停止 Jail www

也可以使用 jail 命令直接操作。-r 会终止指定 Jail 内的所有进程及其子 Jail,-rc 将先移除再重新创建(即重启)。此外 jail -cm 在 Jail 不存在时创建、已存在时修改:

sh
# 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:

sh
# jexec 3 /bin/sh

19.1.6 正常关闭 Jail

在 Jail 中执行关机脚本可实现正常关闭。以下示例在 Jail ID 为 3 的环境中执行 /etc/rc.shutdown

sh
# jexec 3 /etc/rc.shutdown

19.1.7 更新 Jail 系统

使用 freebsd-update 可更新指定 Jail 的系统。需将 /usr/jail/www 替换为实际的 Jail 路径:

sh
# 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 文件中添加以下配置:

ini
allow.raw_sockets=1;   # 允许 Jail 使用原始套接字
allow.sysvipc=1;       # 允许 Jail 使用 System V IPC

配置完成后请重启 Jail 以使配置生效。

示例:启动 Jail test,并加载其配置文件。

sh
# jail -c test

19.1.9 DNS 网络配置

/etc/resolv.conf 用于配置域名系统参数,包括默认搜索域和 DNS 服务器地址。在 Jail 内创建并编辑该文件以设置 DNS:

ini
search lan # 指定默认搜索域为 lan
nameserver 223.5.5.5 # 指定 DNS 服务器
nameserver 223.6.6.6 # 指定备用 DNS 服务器

配置完成后,可在 Jail 内使用 nslookupping 测试 DNS 解析是否正常。ping 需要启用原始套接字,如前文所述。

19.1.10 故障排除与未竟事宜

19.1.10.1 删除文件时提示没有权限

系统不可修改(schg)标志是 FreeBSD 文件系统的安全特性,设置后可防止文件遭到意外或恶意修改、重命名或删除。即使是超级用户也无法直接操作,需先递归取消该目录及其内容的标志:

sh
# chflags -R noschg directory

请将“directory”替换为需要操作的目录路径。

19.1.10.2 证书验证失败

该问题表现为证书验证错误,报错信息包含 STORE routines:ossl_store_get0_loader_int:unregistered。确认系统时间正常后,此问题通常与 FreeBSD 14.1-RELEASE 和 14.2-RELEASE 中的证书数据库索引有关。

解决方法:更新证书数据库的哈希索引。

sh
# certctl rehash

重新执行 pkg 命令。如问题仍存在,可清除 pkg 缓存:# pkg clean -a

19.1.11 参考文献