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.chflags
关闭
jail 中的 root 可像在宿主上一样操作系统文件标志。
allow.mount
关闭
jail 可挂载和卸载文件系统,配合 allow.mount.* 子参数。
allow.quotas
关闭
jail 可管理文件系统配额。
allow.socket_af
关闭
允许 IPv4、IPv6、local 和 route 之外的套接字地址族。
allow.unprivileged_proc_debug
关闭
非特权用户可对自己的进程使用调试设施。
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 共享内存、信号量和消息队列的数据库及其他软件,可通过 sysvmsg、sysvsem 和 sysvshm 参数按模块控制。每个参数接受三个值之一:inherit 使宿主的所有 IPC 对象对 jail 可见,new 给 jail 自己私有的键命名空间,disable 使相关系统调用失败。
对于在 jail 中运行 PostgreSQL 的经典案例,new 是正确的选择,可为数据库提供自己的共享内存命名空间而不暴露宿主的:
较早的 allow.sysvipc 参数已被弃用。它等价于将三个模块参数都设置为 inherit,即将宿主范围的 IPC 命名空间与 jail 共享,因此推荐使用上面的按模块参数。
17.14.3. 挂载文件系统
allow.mount 让 jail 可挂载文件系统,一族子参数选择哪些类型:allow.mount.devfs、allow.mount.fdescfs、allow.mount.fusefs、allow.mount.nullfs、allow.mount.procfs、allow.mount.linprocfs、allow.mount.linsysfs、allow.mount.tmpfs 和 allow.mount.zfs。根据 jail(8),每个子参数“仅在配合 allow.mount 且 enforce_statfs 设置为低于 2 的值时才有效”。便利参数 mount.devfs、mount.fdescfs 和 mount.procfs 会为 jail 自动挂载这些文件系统,mount.fstab 指向包含额外挂载的 fstab 文件。
enforce_statfs 参数既控制 jail 能看到的挂载点,又通过上面的规则控制 allow.mount.* 权限是否生效。它接受三个值:
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.osrelease 和 uname -r 报告的字符串,osreldate 设置 kern.osreldate 和 uname -K 报告的数字。将它们设置成让较旧的用户空间报告自己的发行版本,可使 uname(1)、sysctl(8) 消费者和版本探测构建工具行为正确,包括在 jail 内运行的 freebsd-update(8)。软件包管理不受影响,因为 pkg(8) 从 jail 自己二进制文件的 ELF 注释派生其 ABI,而非从 uname(1)。这补充了 jail 用户空间不能比宿主内核更新的规则;参见 升级 jail。
最后更新于