> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/handbook/di-17-zhang-jail-yu-rong-qi/17.7.-linux-jail.md).

# 17.7.Linux jail

FreeBSD 可在 jail 内运行 Linux，利用 [Linux 二进制兼容性](/handbook/di-12-zhang-linux-er-jin-zhi-jian-rong-ceng/12.1.-gai-shu.md) 和 [sysutils/debootstrap](https://cgit.freebsd.org/ports/tree/sysutils/debootstrap/)。jail 没有内核，它们运行在宿主机的内核上。因此，需要在宿主系统中启用 Linux 二进制兼容性。

要在启动时启用 Linux ABI，执行以下命令：

```sh
# sysrc linux_enable="YES"
```

启用后，可执行以下命令在不重启的情况下启动它：

```sh
# service linux start
```

接下来，按照上述方法创建 jail，例如在 [使用 OpenZFS 快照创建瘦 jail](/handbook/di-17-zhang-jail-yu-rong-qi/17.5.-shou-jail.md) 中所示，但 **不做** 配置。FreeBSD Linux jails 需要特定的配置，接下来将详细说明。

如果宿主上尚不存在 **/etc/jail.conf**——例如在一个此前仅从命令行创建 jail 的系统上——创建一个空文件，以便 [service(8)](https://man.freebsd.org/cgi/man.cgi?query=service\&sektion=8\&format=html) 稍后可以停止该 jail：

```sh
# touch /etc/jail.conf
```

[service(8)](https://man.freebsd.org/cgi/man.cgi?query=service\&sektion=8\&format=html) jail 脚本在停止 jail 时会读取 **/etc/jail.conf**，因此如果该文件不存在，stop 命令会失败。如果前面章节中已经存在 **/etc/jail.conf**，则不需要此步骤。

以下 [jail(8)](https://man.freebsd.org/cgi/man.cgi?query=jail\&sektion=8\&format=html) 命令为 jail 执行所需配置并直接启动它，无需 **/etc/jail.conf** 条目。`-c` 标志创建新 jail，`-m` 修改已存在的 jail；合并为 `-cm` 时，[jail(8)](https://man.freebsd.org/cgi/man.cgi?query=jail\&sektion=8\&format=html) 在 jail 不存在时创建它，在存在时更新它：

```sh
# jail -cm \
    name=ubuntu \
    host.hostname="ubuntu.example.com" \
    path="/usr/local/jails/containers/ubuntu" \
    interface="em0" \
    ip4.addr="192.168.1.155" \
    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
```

以 `root` 身份使用 [jexec(8)](https://man.freebsd.org/cgi/man.cgi?query=jexec\&sektion=8\&format=html) 访问新创建的 jail：

```sh
# jexec -u root ubuntu sh
```

在 jail 内，安装 [sysutils/debootstrap](https://cgit.freebsd.org/ports/tree/sysutils/debootstrap/) 并使用它在 **/compat/ubuntu** 下构建 Ubuntu 用户空间。[sysutils/debootstrap](https://cgit.freebsd.org/ports/tree/sysutils/debootstrap/) 是构建 Linux 用户空间的工具；之后进入 jail 并不需要它。首次运行 [pkg(7)](https://man.freebsd.org/cgi/man.cgi?query=pkg\&sektion=7\&format=html) 会自动引导其安装：

```sh
# pkg install debootstrap
# debootstrap jammy /compat/ubuntu
```

`jammy` 选择 Ubuntu 22.04 LTS。也可选择更新的 LTS，例如 `noble`（Ubuntu 24.04），前提是它能在 linuxulator 下运行。

当进程完成并在控制台上显示 `Base system installed successfully` 信息时，从宿主系统停止 jail。由于此 jail 未在 **/etc/rc.conf** 中启用，也未在 **/etc/jail.conf** 中列出，因此使用带 `one` 前缀的 [service(8)](https://man.freebsd.org/cgi/man.cgi?query=service\&sektion=8\&format=html) 操作，该操作即使对未通过 `jail_enable` 启用或未在 `jail_list` 中列出的 jail 也会运行：

```sh
# service jail onestop ubuntu
```

`onestart` 和 `onestop` 操作是 `start` 和 `stop` 对于未通过 `jail_enable` 启用或未在 `jail_list` 中列出的 jail 的对应操作。

然后，在 **/etc/jail.conf** 中为 Linux jail 添加条目：

```sh
ubuntu {
  # 启动/日志记录
  exec.start = "/bin/sh /etc/rc";
  exec.stop = "/bin/sh /etc/rc.shutdown";
  exec.consolelog = "/var/log/jail_console_${name}.log";

  # 权限
  allow.raw_sockets;
  exec.clean;
  mount.devfs;
  devfs_ruleset = 4;

  # 主机名/路径
  host.hostname = "${name}";
  path = "/usr/local/jails/containers/${name}";

  # 网络
  ip4.addr = 192.168.1.155;
  interface = em0;

  # 挂载
  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";
}
```

> **技巧**
>
> jail 还可向其中运行的程序呈现特定的 Linux 内核标识。`linux` 参数选择 jail 是继承宿主的 Linux 模拟环境（`inherit`）还是获得自己的环境（`new`），`linux.osname`、`linux.osrelease` 和 `linux.oss_version` 分别设置 Linux 二进制文件看到的 OS 名称、发行版本和 OSS 版本。例如，设置 `linux.osrelease=6.1.0` 会使 jail 内的 [uname(1)](https://man.freebsd.org/cgi/man.cgi?query=uname\&sektion=1\&format=html) 和版本检查 Linux 程序报告该内核发行版本，而非宿主全局的 `compat.linux.osrelease` 值。

然后，使用以下命令像往常一样启动 jail：

```sh
# service jail start ubuntu
```

可使用以下命令访问 Ubuntu 环境：

```sh
# jexec ubuntu chroot /compat/ubuntu /bin/bash
```

更多信息，请参阅 [Linux 二进制兼容性](/handbook/di-12-zhang-linux-er-jin-zhi-jian-rong-ceng/12.1.-gai-shu.md)一章。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/handbook/di-17-zhang-jail-yu-rong-qi/17.7.-linux-jail.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
