第五章:包和升级

空jail有用途,只是用途不多。你几乎肯定想在你的jail上安装FreeBSD软件包。同样,未打补丁的FreeBSD安装也有其用途,但这些用途都是针对入侵者的。您必须在jail上安装安全更新!FreeBSD的打包和升级工具支持jails,iocage对包有特定的支持。

第五章:包和升级pkg(8)Iocage 包修补 Jails使用 freebsd-update 进行修补使用Iocage进行备份和修补升级 Jails使用 freebsd-update 升级使用Iocage升级

你会看到有很多方法来管理jail里的包。选择一种方法并坚持下去。不要在iocage包和基于主机的 pkg(8) 和基于jail的 pkg 之间来回切换。包管理工具可能略有不同,特别是如果jail运行的FreeBSD版本比主机旧。

使用 pkg(8) 从主机管理jail包与运行 jexec -l jailname pkg 不同。前者使用主机的包管理工具,而后者运行jail的包管理工具。

jail所有者可能希望在jail内使用标准的 pkg(8) 工具安装自己的软件包。这是完全合理的——毕竟,监狱有一个完整的FreeBSD用户区。仔细考虑是否希望特定用户安装软件包。记住,如果用户搞砸了,你会接到用户的电话。如果用户没有对其软件包应用安全更新,并且入侵者闯入jail,您将接到执法部门的电话。对于那些甚至不应该有shell访问权限的用户,更不用说他们自己的jail了,我用一个shell脚本替换了jail的 /usr/sbin/pkg ,该脚本打印指令,要求帮助台安装所有软件包,然后通过电子邮件警告我,我的特别朋友正在干预他不理解的事情。不过,如果用户有一定的能力,让他们像其他FreeBSD安装一样使用 pkg(8) 管理自己的软件包。

pkg(8)

jail是 pkg(8) 生态系统的一级公民。主机的包工具可以按名称识别正在运行的jail,并管理其安装的包。我通常建议从主机那里管理jail内的包,而不是在jail里。虽然基于主机的包管理使用主机的打包工具,但它将jail的包数据库存储在jail中,并使用jail的 pkg.conf 、证书等。这使得jail可以使用不同的存储库。

使用主机的 pkg(8) 管理jail的包需要 -j 标志和jail名称。此标志位于 pkg 之后,而不是子命令之后。下面,我告诉pkg在jail logdb上运行,并安装sudo软件包:

第一次在主机上运行 pkg(8) 时,它会自动升级,安装存储库中可用的软件包数据库,并执行您要求的任何操作。在jail上运行主机的 pkg(8) 可以避免在jail中安装当前的pkg。pkg(8)程序将检测主机和jail之间的版本差异,并发出警告。您可以放心地忽略这些警告。

除了 -j 和jail名称之外,从主机管理jail的包与在任何其他主机上管理包完全一样。

Iocage 包

iocage将包管理集成到其命令行中。使用 iocage pkg 命令。给它指定jail的名称和要运行的 pkg(8) 命令。下面,我在监狱www1上安装了sudo:

iotage pkg 命令检查存储库的包数据库,如果需要,安装一个jail中的包数据库并安装sudo,就像我在主机上运行原始 pkg(8) 命令一样。只是语法略有不同。

为什么要使用 iocage pkg 而不是 pkg -j ?你的喜好。iocage的目标是成为一个完整的jail管理解决方案,并为iocage用户提供便利,仅此而已。

修补 Jails

FreeBSD的二进制升级工具 freebsd-update(8) 支持jail。毕竟,jail只是安装在特定目录下的FreeBSD安装。虽然您需要对标准jail使用 freebsd-update ,但iocage提供了一个更简单的前端,并利用了ZFS快照。

使用 freebsd-update 进行修补

你不能在jail里可靠地使用 freebsd-update(8) 。这里的关键词是可靠的。我已经逃脱了jail升级的惩罚,但它不受支持,如果你把它变成一种常规做法,它最终会把尖牙伸进你的手臂。在主机上执行所有jail升级。

要更新或升级jail,freebsd-update(8) 必须知道jail中运行的FreeBSD版本和jail的base目录。在升级之前,一定要备份你的jail。如果升级失败,备份tarball或ZFS快照将为您免去痛苦。

修补或升级jail的要求与主机不同。您的jail需要不同的更新配置。

打开文件并开始编辑。你需要一台服务器和该服务器的KeyPrint,所以别管它们了。从组件行开始。jail没有内核,所以不要尝试更新它。大多数(不是全部)jail不包含系统源代码。您必须始终更新的唯一组件是world:

如果你愿意,你可以在jail里使用主机的入侵检测功能。

有些命令永远不应该在我的jail里运行,比如 pkg(8)freebsd-update(8) 。我用shell脚本替换它们,提醒我不要使用它们。我也不关心 /etc/motd 等文件的更新。阻止freebsd-updateIgnorePaths 语句替换此类文件:

你需要在 /etc 中使用 MergeChanges ,但 /boot/device.hints 在jail中无关紧要。您可以修改 UpdateIfUnmodified 以适应您的配置。

freebsd-update(8) 命令检查内核,以确定它在哪个freebsd版本上运行,就像 uname -a 一样。jail在主机内核上运行,但jail的用户空间通常完全不同。在FreeBSD 13系统上运行的FreeBSD 12 jail将默认应用FreeBSD 13补丁。那太糟糕了。使用 freebsd-version(1) 来获取jail的当前补丁级别。

在这里,我的标准jail ldap1目前运行FreeBSD 11.1-RELEASE。我需要在其上安装当前的安全补丁。我正在主机上运行此补丁:

jail现在已经更新了二进制文件,正如 freebsd-version(1) 所证实的那样。

不过,当前运行的任何程序仍然是旧版本。最好重新启动整个jail。

你的jail现在升级了。

这是一个令人恼火的长命令行,但如果你的jail在一个以jail命名的目录中,那么它很容易编写脚本。这是我的脚本 jailpatch.sh 。它只需要一个参数,即要修补的jail的名称。

运行此循环以修补并重新启动所有jail。

勇敢的人可以在脚本中间添加一个 pkg -j $1 upgrade -y

使用Iocage进行备份和修补

iocage的快照功能简化了升级前的备份。iocage snapshot 命令用于拍摄快照。为其指定jail名称,然后使用 -n 提供快照名称。在这里,我拍摄了jail www1的快照,并将其命名为“install”。如果你没有提供快照名称,iocage会根据当前日期和时间创建一个快照。

使用iocage快照列表查看所有快照。添加jail名称。与大多数 iocage 命令一样,您可以使用 -h 选项来摆脱表格式和/或使用 -s 对列进行排序:

在更新jail之前,一定要拍一张快照。

iocage使用 iocage update 命令简化了jail补丁。给一个参数,要修补的jail的名字:

您将看到常见的freebsd-update消息。

如果升级出现严重错误,您可以使用 iocage rollback 命令还原升级。使用 -n 指定快照名称,然后指定jail名称:

现在,当你的疼痛耐受性更高时,你可以再次尝试patch。

使用 iocage snapremove 删除快照。使用 -n 指定快照名称,然后指定jail名称。在几次成功升级后,安装时快照将永远不会被使用,因此您可以将其丢弃。

这个特殊的jail运行FreeBSD 9.3。我真的不想修补它。我想将它升级到FreeBSD的支持版本。让我们讨论一下升级。

升级 Jails

得益于 freebsd-update(8) ,在FreeBSD的主要(12.0到13.0)或次要(12.0至12.1)版本之间升级主机比以前容易得多。即便如此,如果你有一个自动化系统,比如Ansible或Puppet,使部署变得简单,我建议在新的FreeBSD版本上安装新的jail,而不是升级。自动化使服务器安装比升级更快、更安全。对于iocage来说尤其如此,因为默认的iocage jail是ZFS克隆,从12.2升级到13.0会大大增加磁盘空间的使用。

无论你如何升级你的jail,在开始之前一定要做好备份。

使用 freebsd-update 升级

修补jail的一切都适用于升级jail。您需要相同的jail特定 freebsd-update.conf 来升级jail。您必须向freebsd-update提供 jail的当前的FreeBSD版本和根目录。不过,一旦你设置好更新jail,升级也没什么不同。

jail ldap1运行FreeBSD 11.1补丁级别的东西。我想将其升级到完全修补的11.2。使用 -r 指定目标版本,并给出 upgrade 子命令:

系统会要求您确认哪些组件已安装,哪些未安装。检查系统并下载补丁后,您将看到要更新、添加和删除的文件列表。所有这些完成后,您需要将更新作为第二个命令安装:

freebsd-update 修补了jail内核文件的副本,这很好,但这无关紧要。jail主机总是运行与任何jail相同或更新的FreeBSD。点击向上箭头重复该命令并安装新的用户区。

这是FreeBSD的新版本,所以你真的应该重新安装所有的软件包。使用 -f 标志强制重新安装,即使软件似乎没有更改:

现在重启jail:

与修补程序一样,这些升级非常适合脚本编写。此脚本接受一个参数,即要升级的jail,并将其升级到FreeBSD 11.2。当我升级一堆jail时,我会编辑脚本以更改版本号。你可以将FreeBSD版本作为脚本的参数,但这意味着命令行更长,我不会介意的。

如果您要跨主要版本进行升级,系统还会提示您合并 /etc/

使用Iocage升级

您可以将 freebsd-update(8) 与 iocage jails一起使用,但iocage在 iocage upgrade 命令中吸收了大量命令行。将jail的名称作为一个参数,并使用 -r 指定所需的升级目标。我的jail www1运行的是FreeBSD 9.3,我想将其升级到最新的FreeBSD 10:

您将看到熟悉的“检查系统”和“准备下载文件”消息。这个特殊的升级需要35266个补丁和50864个文件,所以现在是检查Mastodon提要的好时机。

一旦所有这些完成,你就可以将 /etc 更改合并到你的jail中。iocage会自动更新您未更改的所有文件。iocage会自动处理完成升级所需的freebsd-update的重复运行。

跨主要版本升级iocage jail是不明智的。除非另有说明,否则iocage会将jail创建为ZFS克隆。ZFS克隆仅使用的磁盘空间量等于从中克隆的快照与磁盘上的当前文件之间的差异。即使是小版本的升级也会占用半GB的磁盘,而大版本的修订会占用完整FreeBSD安装的空间。

将这个jail从9.3升级到10.4使用了额外的680 MB磁盘空间。这不是一个杀手,但与完整的10.4安装相比,它肯定不会节省空间。

幸运的是,您可以在升级过程中以节省磁盘的方式配置jail。我们将在下一章中看到其中的一些。