第一章:Jail主机

虚拟化是伟大的,但即使有嵌套的虚拟机层,最终你也会遇到安装在物理硬件上的操作系统。是的,现代系统的许多组件都运行自己的内部操作系统,但我们称之为BIOS、固件和UEFI,并拼命忽略它们。安装和配置您的主机,使其能够最容易地运行jail,这将为您节省大量以后的麻烦。

破解主机的入侵者可以控制该主机上运行的所有jail。从一开始就计划在主机上运行零个不必要的服务。如果不是绝对需要它来管理主机,那就把它关进jail。jail主机需要SSH和计时,所以在不暴露于互联网的网络接口上运行它们。Web、数据库和应用服务器?不可信的动物,他们很多。把他们都关进jail。拒绝潜在的入侵者,即使是破坏宿主的最小机会。 如果你想在jail中使用虚拟网络,我强烈建议使用FreeBSD 12或更高版本。你可以用FreeBSD的早期版本进行虚拟网络,但它相当可怕,要么需要编译一个自定义内核,要么需要将一堆虚拟接口粘在一起。这是可以做到的,但FreeBSD 12中的vnet极大地简化和稳定了虚拟网络。

我们将从存储开始,接着进行网络连接,然后查看主机服务和内核的详细配置。

第一章:Jail主机存储网络syslogdntpdsshd启用 JailsIocage Setup

存储

jail都是关于存储的。是的,他们需要流程管理和网络以及所有这些,但这些都可以重新配置,而无需剥离所有内容并重新开始。如果可能的话,将您的jail数据与主机数据分开。在具有多个硬盘的主机上,将几个硬盘专用于您的操作系统,其余的专用于jail。如果在小型操作系统安装中使用多个数TB的驱动器感觉浪费,请购买一块带有几个直接连接的高耐久性闪存驱动器的主板。无论哪种方式,都可以使用 geom_mirror(8) 或ZFS镜像操作系统驱动器。让你的jail存储也变成冗余的。

你的文件系统需要支持标准的Unix文件系统功能,如所有者和权限等。不要试图在FAT文件系统上构建jail,除非你想用新的有趣的失败场景来娱乐自己。使用UFS或ZFS。如果你的主机可以支持ZFS,我建议你选择它。Jails出现在UFS是FreeBSD中唯一严肃的文件系统选项的时候,但ZFS有额外的功能来放大和扩展Jails,比如完全将数据集委托给jail。

两个似乎是jail的明显选择的文件系统是nullfs和unionfs。我们将大量使用nullfs,但不止一位FreeBSD开发人员将unionfs描述为“一篮子恐慌(a basket of panic)”。手册页警告人们不要使用它。有些人无视这一警告并报告了出色的结果,而另一些人则遭受了无尽的痛苦。如果你使用unionfs并喜欢它,那对你来说是件好事——但这本书没有建议,我也不会推荐。

NFS或AFS等网络文件系统呢?任何网络文件系统都会带来挑战,从通常的性能问题到只影响您的精确配置的奇怪边缘情况,以及一个孤独的系统管理员的环境,他在1994年向Usenet发布了一份绝望的详细求助请求,但没有得到答复,也再也没有消息。如果你愿意在最不方便的时候处理这些问题,你可以让jail在网络文件系统上工作。NFSv4所需的nfsuserd(8) 守护进程与jail不能很好地互操作,因此您可能应该使用NFSv3或更早的版本。

记住,网络文件系统与网络磁盘不同。用于将磁盘连接到主机的机制无关紧要。光纤通道和iSCSI不是网络文件系统,而是网络磁盘。他们很好。没有人利用光纤通道越狱。

您将看到一些文档,声明您应该运行 lsvfs(1) 来查看内核支持的文件系统,并且只使用标记有jail标志的文件系统。这表示可以从jail内安全管理的文件系统,而不是主机可以用来为jail提供存储的文件系统。我们将在第8章讨论在jail内管理文件系统。

这本书中手工制作的标准jail的例子都放在 /jail 文件系统中。理想情况下,这是一组与操作系统不同的物理介质。它可以使用UFS或ZFS。根据定义,在UFS上运行的任何示例都是标准jail,并出现在 /jail 中。

iocage仅适用于ZFS。我将我的池称为iocage专用池,挂载在 /iocage 。根据定义,/iocage 下的任何示例都使用iocage。

Python使用 fdescfs(5) 来提高性能。如果您正在使用iocage,请在主机上使用 /etc/fstab 条目启用fdescfs:

每个jail可以有几个挂载点。预计会有一大堆文件系统表文件,如 /etc/fstab

评论一切都很好。要么记录下来,要么后悔。

网络

TCP/IP的规则声明一次只能有一个进程监听IP地址和端口的组合。您可以将jail附加到主机上的任何IP地址和端口,但如果主机上的进程或另一个jail已经附加到该端口和地址,则jail将无法正常工作。最明显的例子是SSH服务器 sshd(8) 。SSH通常连接到主机上所有IP地址的端口22。如果您的主机垄断了所有jail地址上的端口22,则没有一个jail可以在端口22上使用SSH。它们必须使用不同的端口,这增加了复杂性。“主机使用端口22,而jail使用端口23”是那种让人们密谋报复系统管理员的说法。

当您第一次了解jail时,请使用具有单个网络接口但具有多个IP地址的简单主机。为主机专门分配一个IP。将主机的所有服务绑定到该IP。一旦你了解了jail的基本知识,你就可以在一个生产主机上开始,该主机具有连接到不同网络、VLAN和所有有趣的东西的多个接口,但要保持初始测试环境的简单。我们将在第9章讨论更复杂的网络设置。

如果你没有多个IP地址的奢侈,你必须跟踪哪些jail中的守护进程绑定到哪些IP地址和端口,可能是在加密签名的巨型电子表格的多个分布式副本上。这会告诉用户“将61000添加到所有端口号中,以找到jail 61的服务。是的,如61022、61443等。”

虽然jail通常依赖于主机的网络堆栈,但FreeBSD的 vnet(9) 虚拟网络堆栈允许您为每个jail分配一个虚拟网络堆栈和自己的路由表。每个jail都可以有一个完全不同的路由表。我们将在第9章讨论这个问题。

通过尽可能减少主机的网络配置文件来保护您的主机。使用 sockstat(1)netstat(1) 标识开放端口。记住,您在主机上运行的任何服务也是入侵者的潜在攻击向量。新的FreeBSD安装默认有三个守护进程监听网络:syslogd(8)ntpd(8)sshd(8)

syslogd

FreeBSD的日志记录器 syslogd(8) 主动绑定到每个可用IP上的UDP端口514,以便它可以向其他主机发送日志消息。如果您不需要远程日志记录,或者您的远程日志记录解决方案不使用syslogd(8),请使用-ss禁用syslogd的网络访问:(这可能是FreeBSD 13的默认设置。)

安全敏感组织几乎肯定需要远程日志记录。使用-b标志将syslogd锁定到主机的管理IP:

这释放了jail其他地址上的syslogd端口。

ntpd

所有的jaio都占用了host的时间。FreeBSD的计时器守护进程 ntpd(8) 监听所有可用的IP地址。使用stock ntpd无法限制这一点——您可以将ntpd绑定到单个接口,但不能绑定到单个地址。在这种情况下,我会告诉你不要担心,运行ntpd。

Jails不能改变内核的时间。即使你在jail里运行ntpd,它实际上也无法改变主机时间。任何在jail中运行的程序,只要连接到UDP端口123或从UDP端口123连接,就像ntpd一样,几乎肯定会试图偷偷通过数据包过滤器。没有理由让这个小把戏变得更容易。让主机独占UDP端口123。

如果您仍然担心,请禁用基本系统的 ntpd(8) 并安装OpenNTPd。OpenNTPd有特权分离作为奖励。

sshd

每个人都使用 sshd(8) 管理Unix主机。你的用户会想通过SSH进入他们的jail,强迫他们使用备用端口会惹恼他们。如果您的所有jail都使用相同的IP,这将无济于事,但在我们的理想情况下,每个jail都有自己的IP世界,您将把主机的SSH守护进程限制为单个IP。使用 /etc/ssh/sshd_config 中的 ListenAddress 关键字来限制OpenSSH的 sshd(8) 使用哪个地址。

理想情况下,此地址只能从您的管理网络访问。

第9章将带你深入jail网络,但这应该让你开始。

启用 Jails

FreeBSD内置了启动和停止jail的脚本。脚本读取配置文件 /etc/jail.conf 并将结果馈送到 jail(8) 。虽然可以使用 jail 命令在命令行上完全配置、启动和停止jail,正如我们将在第3章中看到的那样,但随着jail数量的增加,这些命令变得乏味。您最好使用配置文件并通过 service(8) 启用jail管理。

iocage使用存储在每个单独jail中的配置文件。当iocage启动时,它会读取自己的配置文件,并启动 jail(8) 来创建和启动您标记为自动启动的所有jail。告诉FreeBSD在启动时启动iocage,并启用服务iocage。

您可以同时使用这两个jail管理系统。jail.conf 中配置的jail与iocage管理的jail本身并不冲突。毕竟,这两个系统都只是jail的前端。它们可能存在管理冲突,例如两者都试图绑定到相同的IP地址和端口,但这两个系统是独立工作的。iocage可以管理数百种最常见的jail类型,让你可以痛苦地维护几座溃烂的手工制作的工匠(artisan) jail,这些jail需要自己的异国情调(exotic weirdness)。

Iocage Setup

首先,iocage需要ZFS。如果你没有ZFS,不要尝试使用iocage。使用 pkg search iocage 查找当前的iocage包,或从github获取最新版本。不过,一旦你做到了这一点,iocage就需要特定的区域设置。将以下内容添加到 $HOME/.login.conf 中:

注销并重新登录以激活这些区域设置。

第一次运行任何iocage命令时,它会自动在根池上创建iocage数据集。如果你有一个单独的iocage jail池,在iocage spams你的根池之前告诉它。使用 iocage activate 命令将iocage指向您的池。在这里,我将 iocage 池奉献给iocage jails:

ZFS池 iocage 成功激活。

iocage文件被挂载到 /poolname/iocage 。如果你使用默认安装和默认根池,就像没有人做的那样,所有iocage文件都会出现在 /zroot/iocage 下。使用名为iocage的池,iocage文件将放在 /iocage/iocage 下。为了简洁起见,并避免在本书中散布像 $POOL/iocage 这样的可怕文件名,所有示例都使用 /iocage

如果你错误地告诉iocage将自己设置在错误的池上,请使用 iocage clean -a 销毁所有这些数据集。对于旧版本的iocage,您必须使用 zfs destroy -r 命令来销毁包含iocage文件的任何数据集。

第一次运行iocage时,它会为downloads、jails、templates和所有其他iocage函数创建数据集。如果你提前创建了你的第一个jail,iocage会自动提示你选择一个版本,下载它,并为你设置jail。或者,您可以运行 iocage list 来显示您所有的iocage jail,而您还没有。我们将在本书中解释所有这些数据集。

iocage具有实验性的颜色输出。我在这里不使用颜色,因为这本书将以黑白打印,但如果你想在终端中使用颜色,请将环境变量 IOCAGE_COLOR 设置为 TRUE

重新启动主机,以验证所有内容是否如您所想的那样安全,以及主机是否按预期重新启动。一旦你确认了一切,你就可以开始添加jail了。