# 19.1 Jail 基础

## FreeBSD Jail 概述

Jail 原意为“监狱、监禁”，在本书中指一种基于 chroot 改进的容器隔离技术。

Jail 技术于 1999 年提交到 FreeBSD 源代码树，随 2000 年 3 月发布的 FreeBSD 4.0 首次正式引入，首次实现了文件系统、进程空间和网络资源的三重隔离。

Jail 的发音为 \[dʒeɪl]（英/美），发音接近汉语“杰尔”；“炸儿”为非标准发音。

## 创建 Jail 目录

### 获取 FreeBSD 基本系统文件

#### 编译基本系统（可选）

创建 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
```

#### 解压分发文件（可选）

可通过下载或从 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 配置
```

### 在 **/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"; # 关闭命令
}
```

## 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
```

字段说明（中英对照）：

| 英语         | 中文      |
| ---------- | ------- |
| JID        | Jail ID |
| IP Address | IP 地址   |
| Hostname   | 主机名     |
| Path       | Jail 路径 |

## 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）
```

## 进入 Jail

使用 `jexec` 命令可在指定 Jail 中执行命令，支持以 JID 或 Jail 名称定位目标 Jail。`jexec -l` 使用纯净环境运行命令（仅保留 HOME、SHELL、TERM 等基本变量，PATH 设为 `/bin:/usr/bin`）。以下示例在 Jail ID 为 3 的环境中启动 Shell：

```sh
# jexec 3 /bin/sh
```

## 正常关闭 Jail

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

```sh
# jexec 3 /etc/rc.shutdown
```

## 更新 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 的系统更新
```

## 启用 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
```

## DNS 网络配置

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

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

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

## 故障排除与未竟事宜

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

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

```sh
# chflags -R noschg directory
```

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

### 证书验证失败

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

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

```sh
# certctl rehash
```

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

## 参考文献

* 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”。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.bsdcn.org/di-19-zhang-jail-rong-qi-guan-li/di-19.1-jie-jail-ji-chu-pei-zhi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
