35.2 Debian Jail
本节基于 Debian 12 配置 Jail。
35.2.1 准备基本系统
以 Debian 12(bookworm)为例,构建 Ubuntu/Debian 基本系统。
安装用于构建 Debian/Ubuntu 基本系统的工具。
# pkg install debootstrap创建 Jail 路径:
# mkdir -p /usr/jails/debian通过中国科学技术大学开源镜像站自举 Debian 12 系统:
# debootstrap bookworm /usr/jails/debian https://mirrors.ustc.edu.cn/debian/示例输出如下:
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 文件。各文件系统作用如下:
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(默认,仅根目录所在挂载点可操作):
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 服务:
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 访问网络:
# pfctl -t jails -T add 192.168.5.135.2.5 启用实例
启动 Jail:
# jail -c debian停止 Jail:
# jail -r debian35.2.6 更新 Debian 系统
35.2.6.1 在 Jail 内部更新
执行以下命令进入 Jail 并更新系统:
# jexec debian /bin/bash # 此时位于 FreeBSD
Debian # apt remove rsyslog # 此时位于 Debian Jail
Debian # apt update # 此时位于 Debian Jail35.2.6.2 在 Jail 外部更新
# 在 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 服务:
# service jail enable默认情况下会启动 /etc/jail.conf 文件中配置的所有 Jail。
也可在 /etc/rc.conf 文件中用 jail_list 变量指定在开机时启动的 Jail 的名称,编辑 /etc/rc.conf 文件写入:
jail_list="debian"或执行:
# sysrc jail_list+=debian如果 jail_list 变量为空,则会启动所有在 /etc/jail.conf 文件中配置的 Jail。