Skip to content

35.2 Debian Jail

本节基于 Debian 12 配置 Jail。

35.2.1 准备基本系统

以 Debian 12(bookworm)为例,构建 Ubuntu/Debian 基本系统。

安装用于构建 Debian/Ubuntu 基本系统的工具。

sh
# pkg install debootstrap

创建 Jail 路径:

sh
# mkdir -p /usr/jails/debian

通过中国科学技术大学开源镜像站自举 Debian 12 系统:

sh
# debootstrap bookworm /usr/jails/debian https://mirrors.ustc.edu.cn/debian/

示例输出如下:

sh
I: Retrieving InRelease
I: Retrieving Packages
I: Validating Packages
I: Resolving dependencies of required packages...
I: Resolving dependencies of base packages...
I: Checking component main on https://mirrors.ustc.edu.cn/debian...
I: Retrieving adduser 3.130
I: Validating adduser 3.130
...
I: Extracting usr-is-merged...
I: Extracting util-linux-extra...
I: Extracting zlib1g...

输出末尾可能出现与配置相关的提示信息,这是 debootstrap 在 chroot 环境中运行服务配置脚本时的正常现象,不影响基本系统的使用。

使用 Debian 12 基本系统创建 Jail 实例,命名为 debian。

35.2.2 配置挂载文件

创建 /etc/fstab.debian 文件。各文件系统作用如下:

ini
devfs      /usr/jails/debian/dev      devfs       rw                      0  0
tmpfs      /usr/jails/debian/dev/shm  tmpfs       rw,size=1g,mode=1777    0  0
fdescfs    /usr/jails/debian/dev/fd   fdescfs     rw,linrdlnk             0  0
linprocfs  /usr/jails/debian/proc     linprocfs   rw                      0  0
linsysfs   /usr/jails/debian/sys      linsysfs    rw                      0  0
/tmp       /usr/jails/debian/tmp      nullfs      rw                      0  0

各文件系统作用如下:

文件系统作用
devfs提供设备节点访问
tmpfs为共享内存提供临时文件系统
fdescfs提供文件描述符访问
linprocfs为 Linux 应用提供兼容的 proc 文件系统
linsysfs为 Linux 应用提供兼容的 sys 文件系统
nullfs挂载宿主机的 tmp 目录

35.2.3 管理 Jail 配置文件

/etc/jail.conf 文件中,加入以下内容(如果没有则新建)。关键配置项包括:devfs_ruleset 定义 devfs 的规则集;enforce_statfs 控制 Jail 中挂载点的可见性,取值为 0(无限制)、1(仅根目录下可见)或 2(默认,仅根目录所在挂载点可操作):

ini
debian {                               # Jail 名称
  host.hostname = "debian";             # 设置 Jail 的主机名
  mount.fstab = "/etc/fstab.debian";    # Jail 使用的 fstab 文件:启动或关闭 Jail 时,挂载或卸载对应的文件系统
  path = "/usr/jails/debian";           # Jail 的根目录路径
  devfs_ruleset = 4;                     # Jail 挂载 devfs 的规则集,0 表示无规则集,Jail 会继承上级规则集;
                                        # 仅在启用 allow.mount 和 allow.mount.devfs 且 enforce_statfs 小于 2 时可挂载 devfs
  enforce_statfs = 1;                    # 设置为 0:所有挂载点可用,无限制
                                        # 设置为 1:仅 Jail 根目录下的挂载点可见,且路径前缀中的 Jail 根目录部分会被剥离(例如 /usr/jails/debian/mnt 在 Jail 内显示为 /mnt)
                                        # 设置为 2(默认):只能在 Jail 根目录所在挂载点操作,无法挂载 devfs、tmpfs 等
  allow.mount;                          # 允许挂载文件系统
  allow.mount.devfs;                     # 允许挂载 devfs
  exec.start = "/bin/true";              # Jail 启动时执行的命令
  exec.stop = "/bin/true";               # Jail 停止时执行的命令
  persist;                               # 允许 Jail 在无任何进程情况下仍然存在
  allow.raw_sockets;                      # 允许使用 raw Socket,例如 ping
  interface = "lo1";                      # 使用 lo1 作为网络接口
  ip4.addr = 192.168.5.1;                 # 指定 IPv4 地址
  ip6 = "disable";                        # 禁用 IPv6
}

exec.start 指定启动 Jail 时运行的命令。在 FreeBSD 中创建 Jail 时,一般使用 exec.start = 'sh /etc/rc' 来调用 rc 系统启动服务。

Debian 使用 systemd 作为初始化系统,而 Jail 缺少必要的 cgroup 挂载和系统权限,无法使用 systemd,因此无法直接运行相应命令(但 service 命令仍可使用)。此处使用 /bin/true 安全返回 true(成功状态),不执行任何操作。

例如,在 debian Jail 中启用 sshd 服务后(执行 service ssh start),重启 Jail 时 sshd 服务不会随 Jail 自动启动。此时可设置 exec.start = 'service ssh start',以确保启动 Jail 时自动启动 sshd 服务。

要启用更多服务,可按如下方式编写:

在 Jail 启动时按顺序启动 SSH 和 D-Bus 服务:

ini
exec.start += 'service ssh start'
exec.start += 'service dbus start'

exec.stop 指定停止 Jail 时运行的命令。FreeBSD Jail 通常使用 sh /etc/rc.shutdown

同样由于 systemd 的限制,此处使用 /bin/true 安全返回 true

35.2.4 管理防火墙放行网络

在 pf 防火墙中的 jails 表中加入 Jail 的地址,以允许 Jail 访问网络:

sh
# pfctl -t jails -T add 192.168.5.1

35.2.5 启用实例

启动 Jail:

sh
# jail -c debian

停止 Jail:

sh
# jail -r debian

35.2.6 更新 Debian 系统

35.2.6.1 在 Jail 内部更新

执行以下命令进入 Jail 并更新系统:

sh
# jexec debian /bin/bash # 此时位于 FreeBSD
Debian # apt remove rsyslog  # 此时位于 Debian Jail
Debian # apt update # 此时位于 Debian Jail

35.2.6.2 在 Jail 外部更新

sh
# 在 debian Jail 内执行命令,卸载 rsyslog
# jexec -l debian /bin/bash -c "apt remove rsyslog"

# 在 debian Jail 内执行命令,更新软件包索引
# jexec -l debian /bin/bash -c "apt update"

采用相同方法可创建基于不同版本的 Debian 或 Ubuntu 的多个 Jail。

35.2.7 Jail 服务管理

开机时启动 jail 服务:

sh
# service jail enable

默认情况下会启动 /etc/jail.conf 文件中配置的所有 Jail。

也可在 /etc/rc.conf 文件中用 jail_list 变量指定在开机时启动的 Jail 的名称,编辑 /etc/rc.conf 文件写入:

ini
jail_list="debian"

或执行:

sh
# sysrc jail_list+=debian

如果 jail_list 变量为空,则会启动所有在 /etc/jail.conf 文件中配置的 Jail。