For the complete documentation index, see llms.txt. This page is also available as Markdown.

17.14.更多 jail 选项

jail(8) 暴露的参数远比本章示例使用的要多。jail 是强大的隔离边界,但并非绝对的。每个 allow.* 放松都以能力换取隔离性,使 jail 的特权用户向宿主 root 的特权靠近一步。仅授予 jail 中工作负载真正需要的权限,其余保留在其更严格的默认值。完整列表见 jail(8)jail.conf(5);下面是管理员最常使用的参数。

17.14.1. allow.* 权限

allow.* 参数是布尔值,可向 jail 授予个别特权。根据 jail(8),“除了 allow.set_hostname 和 allow.reserved_ports 外,这些布尔参数默认关闭”,因此 jail 默认是锁定的,每项能力都必须显式授予。

参数
默认值
效果

allow.set_hostname

开启

jail 可更改自己的主机名。

allow.reserved_ports

开启

jail 中的 root 可绑定 1024 以下的保留端口。

allow.raw_sockets

关闭

启用原始套接字,使 ping(8)traceroute(8) 可在 jail 中工作。

allow.chflags

关闭

jail 中的 root 可像在宿主上一样操作系统文件标志。

allow.mount

关闭

jail 可挂载和卸载文件系统,配合 allow.mount.* 子参数。

allow.quotas

关闭

jail 可管理文件系统配额。

allow.read_msgbuf

关闭

jail 中的进程可通过 dmesg(8) 读取内核消息缓冲区。

allow.socket_af

关闭

允许 IPv4、IPv6、local 和 route 之外的套接字地址族。

allow.mlock

关闭

jail 中的进程可通过 mlock(2) 锁定物理内存。

allow.unprivileged_proc_debug

关闭

非特权用户可对自己的进程使用调试设施。

allow.vmm

关闭

jail 可使用 vmm(4) 管理程序运行 bhyve(8) 客户机。

allow.nfsd

关闭

jail 可运行 NFS 服务器。

权衡每项放松所暴露的内容:allow.raw_sockets 让 jail 中的进程可伪造数据包,allow.chflags 让 jail 中的 root 可清除宿主依赖的不可变和仅追加标志,而 allow.mount 开放了文件系统命名空间。

在 jail 内运行 NFS 服务器(FreeBSD 14.0 发行说明中提及)需要设置 allow.nfsd,需要一个根目录本身是文件系统挂载点的 VNET jail,且 enforce_statfs 不得设置为 0

17.14.2. System V IPC

依赖 System V 共享内存、信号量和消息队列的数据库及其他软件,可通过 sysvmsgsysvsemsysvshm 参数按模块控制。每个参数接受三个值之一:inherit 使宿主的所有 IPC 对象对 jail 可见,new 给 jail 自己私有的键命名空间,disable 使相关系统调用失败。

对于在 jail 中运行 PostgreSQL 的经典案例,new 是正确的选择,可为数据库提供自己的共享内存命名空间而不暴露宿主的:

较早的 allow.sysvipc 参数已被弃用。它等价于将三个模块参数都设置为 inherit,即将宿主范围的 IPC 命名空间与 jail 共享,因此推荐使用上面的按模块参数。

17.14.3. 挂载文件系统

allow.mount 让 jail 可挂载文件系统,一族子参数选择哪些类型:allow.mount.devfsallow.mount.fdescfsallow.mount.fusefsallow.mount.nullfsallow.mount.procfsallow.mount.linprocfsallow.mount.linsysfsallow.mount.tmpfsallow.mount.zfs。根据 jail(8),每个子参数“仅在配合 allow.mount 且 enforce_statfs 设置为低于 2 的值时才有效”。便利参数 mount.devfsmount.fdescfsmount.procfs 会为 jail 自动挂载这些文件系统,mount.fstab 指向包含额外挂载的 fstab 文件。

enforce_statfs 参数既控制 jail 能看到的挂载点,又通过上面的规则控制 allow.mount.* 权限是否生效。它接受三个值:

jail 可见的挂载点

0

宿主上的所有挂载点,无限制。

1

仅 jail 根目录之下的挂载点。

2(默认)

仅 jail 根目录所在的单一挂载点。

由于 allow.mount.* 权限要求值低于 2,因此必须挂载自己文件系统的 jail 通常配置为 enforce_statfs = 1

17.14.4. 按 jail 设置的 securelevel

securelevel 参数设置 jail 的 kern.securelevel,并在 jail 内部提高内核的不可变标志和设备保护。根据 jail(8),“jail 的 securelevel 不会低于其父系统,但通过设置此参数,可有更高的值”。因此,面向网络的 jail 可在加固的 securelevel = 3 下运行,而宿主保持默认值。

17.14.5. 分层 jail

jail 本身可创建子 jail,这是构建嵌套或分层 jail 层次结构的方式。children.max 参数设置一个 jail 可创建的子 jail 数量;默认为 0,表示不允许子 jail,只读的 children.cur 报告当前存在的数量。子 jail 永远不能超过其父 jail 的权限:根据 jail(8),“jail 中的进程不允许授予比自己拥有的更大的权限”。这使得在 jail 内运行 jail 管理器成为可能。

17.14.6. 空和持久 jail

默认情况下,jail 仅在有运行进程时存在;当其最后一个进程退出时,jail 消失。根据 jail(8) 的话,设置 persist 参数“允许 jail 在没有任何进程的情况下存在”。这正是使 jail 在创建为空后、填充内容之前保持活动的原因,也是锚定仅持有网络状态的 VNET jail 的依据。可创建一个空 jail 并保持其活动以便实验:

使用 nopersist 清除该标志,让 jail 在再次空闲时被移除。

17.14.7. 呈现不同的 OS 发行版本

jail 的用户空间可能比宿主内核旧,但其中的工具仍会通过 uname(1) 读取宿主的版本,除非另有指示。osrelease 参数设置 jail 的 kern.osreleaseuname -r 报告的字符串,osreldate 设置 kern.osreldateuname -K 报告的数字。将它们设置成让较旧的用户空间报告自己的发行版本,可使 uname(1)sysctl(8) 消费者和版本探测构建工具行为正确,包括在 jail 内运行的 freebsd-update(8)。软件包管理不受影响,因为 pkg(8) 从 jail 自己二进制文件的 ELF 注释派生其 ABI,而非从 uname(1)。这补充了 jail 用户空间不能比宿主内核更新的规则;参见 升级 jail

最后更新于