第21章 其他文件系统
附录 D. OpenPGP 密钥
15.6.使用 ezjail 管理 Jail

15.6.使用 ezjail 管理 Jail

创建和管理多个 jail 可能很快会变得繁琐且容易出错。Dirk Engling 的 ezjail 自动化并大大简化了许多 jail 任务。basejail 被创建为模板。其他 jail 使用 mount_nullfs(8) 来共享许多 basejail 目录,而无需使用额外的磁盘空间。在安装应用程序之前,每个额外的 jail 仅占用几兆字节的磁盘空间。升级 basejail 中用户空间的副本会自动升级所有其他 jail。
其他优点和功能在 ezjail 网站上详细描述,https://erdgeist.org/arts/software/ezjail/。

15.6.1. 安装 ezjail

安装 ezjail 包括添加一个环回接口以在 jail 中使用,安装 ports 或软件包以及启用服务。
  1. 1.
    为了保持 jail 环回流量离开主机的环回网络接口 lo0,通过向 /etc/rc.conf 添加一个条目来创建第二个环回接口:
1
cloned_interfaces="lo1"
Copied!
第二个环回接口将在 lo1 系统启动时创建。也可以手动创建它,而无需重新启动:
1
# service netif cloneup
2
Created clone interfaces: lo1.
Copied!
可以允许 jail 使用这个二级环回接口的别名而不干扰主机。
在 jail 内,对回环地址 127.0.0.1 的访问被重定向到分配给 jail 的第一个 IP 地址。为了使 jail 的环回地址与新的 lo1 接口相对应,在创建新 jail 时,必须首先在接口和 IP 地址列表中指定该接口。
127.0.0.0/8 网块中给每个 jail 一个唯一的环回地址。
  1. 1.
    安装 sysutils/ezjail
1
# cd /usr/ports/sysutils/ezjail
2
# make install clean
Copied!
  1. 1.
    通过将这行添加到 /etc/rc.conf 来启用 ezjail:
1
ezjail_enable="YES"
Copied!
  1. 1.
    该服务将在系统启动时自动启动。它可以立即为当前会话启动:
1
# service ezjail start
Copied!

15.6.2. 初始设置

安装 ezjail 后,可以创建和填充 basejail 目录结构。此步骤仅在 jail 主机上需要一次。
在这两个示例中。都会导致 ports 树使用 portsnap(8) 检索到 basejail。所有的 jail 都将共享这个 ports 目录的副本。为 jail 使用单独的 ports 目录副本可以将它们与主机隔离。ezjailFAQ 中有更详细的解释: http://erdgeist.org/arts/software/ezjail/#FAQ。
  1. 1.
    用 FreeBSD-RELEASE 来填充 jail
对于基于与主机相匹配的 FreeBSD RELEASE 的 basejail,使用 install。例如,在一台运行 FreeBSD 10-STABLE 的主机上,最新的 FreeBSD-10 RELEASE 版本将被安装在 jail 中。
1
# ezjail-admin install -p
Copied!
  1. 1.
    installworld 填充 jail
basejail 可以用 ezjail-admin updatebuildworld 在主机上创建的二进制文件安装。
在这个例子中,FreeBSD 10-STABLE 是从源代码构建的。jail 目录被创建。然后执行 installworld,将主机的 **/usr/obj** 安装到 basejail 中:
1
# ezjail-admin update -i -p
Copied!
默认情况下使用主机的 **/usr/src** 。可以用 -s 和路径指定主机上不同的源目录,或者用 **/usr/local/etc/ezjail.conf** 中的 ezjail_sourcetree 设置。
小技巧
basejail ports 树由其他 jail 共享。但是,下载的 distfile 存储在下载它们的 jail 中。默认情况下,这些文件存储在每个 jail 内的 /var/ports/distfile 中。在构建 ports 时,每个 jail 中的 /var/ports 也用作工作目录。
小技巧
默认情况下,FTP 协议用于下载用于安装 basejail 的软件包。防火墙或代理配置可以阻止或干扰 FTP 传输。HTTP 协议的工作方式不同,避免了这些问题。可以通过在 /usr/local/etc/ezjail.conf 中为特定下载镜像指定完整 URL 来选择它:
ezjail_ftphost=http://ftp.FreeBSD.org
有关站点列表,请参阅 镜像 部分。 |

15.6.3. 创建和启动新 Jail

使用 ezjail-admin create 创建新的 jail。在这些示例中,环回接口lo1 按上述方式使用。
示例:创建和启动新 jail
  1. 1.
    创建 jail,指定名称、要使用的环回和网络接口及其 IP 地址。在此示例中,jail 被命名为 dnsjail
1
# ezjail-admin create dnsjail 'lo1|127.0.1.1,em0|192.168.1.50'
Copied!
小技巧
大多数网络服务在 jail 中运行,没有问题。一些网络服务,最明显的是 ping(8),使用 原始网络套接字。在 jail 中,出于安全考虑,默认情况下禁用原始网络套接字。需要它们的服务将不起作用。有时,jail 确实需要原始套接字。例如,网络监视应用程序经常使用 ping(8) 来检查其他计算机的可用性。当 jail 中实际需要原始网络套接字时,可以通过编辑各个 jail 的 ezjail 配置文件 /usr/local/etc/ezjail/jailname 来启用它们。修改 parameters 条目:
export jail_jailname_parameters="allow.raw_sockets=1"
不要启用原始网络套接字,除非 jail 中的服务确实需要它们。 |
  1. 1.
    启动 jail:
1
# ezjail-admin start dnsjail
Copied!
  1. 1.
    在 jail 中使用控制台:
1
# ezjail-admin console dnsjail
Copied!
jail 正在运行,可以完成其他配置。此时添加的典型设置包括:
  1. 1.
    设置 root 密码
连接到 jail 并设置 root 用户的密码:
1
# ezjail-admin console dnsjail
2
# passwd
3
Changing local password for root
4
New Password:
5
Retype New Password:
Copied!
  1. 1.
    时区配置
jail 的时区可以用 tzsetup(8) 来设置。为避免虚假的错误消息,可以注释或删除 /etc/crontab 中的 adjkerntz(8) 条目。此工作尝试使用时区更改来更新计算机的硬件时钟,但不允许 jail 访问该硬件。
  1. 1.
    域名服务器
/etc/resolv.conf 中输入域名服务器行,以便 DNS 在 jail 中工作。
  1. 1.
    编辑 /etc/hosts
更改地址并将 jail 名称添加到 /etc/hosts 中的 localhost 条目中。
  1. 1.
    配置 /etc/rc.conf
/etc/rc.conf 中输入配置设置。这很像配置一台完整的计算机。此处未设置主机名和 IP 地址。这些值已由 jail 配置提供。
配置 jail 后,可以安装为其创建 jail 的应用程序。
小技巧
某些 port 必须使用特殊选项构建才能在 jail 中使用。例如,网络监控插件包 net-mgmt/nagios-plugins ** 和 ** net-mgmt/monitoring 插件** 都有一个 JAIL 选项,必须启用该选项才能在 jail 中正常工作。**

15.6.4. 更新 Jail

15.6.4.1. 更新操作系统

由于 basejail 的用户空间副本由其他 jail 共享,因此更新 basejail 会自动更新所有其他 jail。可以使用源更新或二进制更新。
要从主机上的源代码构建世界,然后将其安装在 basejail 中,请使用:
1
# ezjail-admin update -b
Copied!
如果世界已经在主机上编译,请使用以下命令将其安装在 basejail 中:
1
# ezjail-admin update -i
Copied!
二进制更新使用 freebsd-update(8)。这些更新与直接运行 freebsd-update(8) 具有相同的限制。最重要的一点是,只有 -RELEASE 版本的 FreeBSD 可以使用此方法。
将 basejail 更新到主机上 FreeBSD 版本的最新补丁版本。例如,从 RELEASE-p1 更新到 RELEASE-p2。
1
# ezjail-admin update -u
Copied!
要将 basejail 升级到新版本,请首先按照 “执行主要和次要版本升级” 中所述升级主机系统。升级并重新引导主机后,即可升级 basejail。freebsd-update(8) 无法确定 basejail 中当前安装了哪个版本。因此必须指定原始版本。使用 file(1) 确定 basejail 中的原始版本:
1
# file /usr/jail/basejail/bin/sh
2
/usr/jail/basejail/bin/sh: ELF 64-bit LSB executable, x86-64, version 1 (FreeBSD), dynamically linked (uses shared libs), for FreeBSD 9.3, stripped
Copied!
现在,使用此信息执行从 9.3-RELEASE 主机系统的当前版本的升级:
1
# ezjail-admin update -U -s 9.3-RELEASE
Copied!
更新 basejail 后。必须运行 mergemaster(8) 来更新每个 jail 的配置文件。
如何使用 mergemaster(8) 取决于 jail 的目的和可信度。如果 jail 的服务或用户不受信任,则 mergemaster(8) 只能从该 jail 内运行:
示例 1.mergemaster(8) 不信任的 Jail
删除从 jail 的 /usr/src 到 basejail 的链接,并在 jail 中创建一个新的 /usr/src 作为挂载点。将主机的 /usr/src 只读挂载到 jail 的新 /usr/src 挂载点上:
1
# rm /usr/jail/jailname/usr/src
2
# mkdir /usr/jail/jailname/usr/src
3
# mount -t nullfs -o ro /usr/src /usr/jail/jailname/usr/src
Copied!
在 jail 中获取控制台:
1
# ezjail-admin console jailname
Copied!
在 jail 里运行 mergemaster。然后退出 jail 控制台:
1
# cd /usr/src
2
# mergemaster -U
3
# exit
Copied!
最后,卸载 jail 的 /usr/src
1
# umount /usr/jail/jailname/usr/src
Copied!
示例 2.mergemaster(8) 信任的 Jail
如果 jail 中的用户和服务是受信任的。mergemaster(8) 可以从主机运行:
1
# mergemaster -U -D /usr/jail/jailname
Copied!
小技巧
**在主要版本更新后,建议使用 sysutils/ezjail,以确保你的版本正确。因此,请输入:
pkg # pkg-static upgrade -f pkg
以升级或降级到相应的版本。** |

15.6.4.2. 更新 ports

基本系统 Jail 中的 port 树由其他 Jail 共享。更新 port 树的该副本也会为其他 jail 提供更新的版本。
basejail ports 树已使用 portsnap(8) 更新:
1
# ezjail-admin update -P
Copied!

15.6.5. 控制 Jail

15.6.5.1. 停止和启动 Jail

ezjail 在计算机启动时会自动启动 jail。可以使用 stopstart 手动停止和重新启动 Jail:
1
# ezjail-admin stop sambajail
2
Stopping jail: sambajail.
Copied!
默认情况下,jail 在主机启动时自动启动。自动启动可以通过 config 禁用:
1
# ezjail-admin config -r norun seldomjail
Copied!
这将在下次启动主机时生效。已经运行的jail不会停止。
启用自动启动非常相似:
1
# ezjail-admin config -r run oftenjail
Copied!

15.6.5.2. 归档和恢复 Jail

使用归档来创建一个 .tar.gz 的 jail 归档。文件名是由jail的名称和当前日期组成。归档文件被写入归档目录,/usr/jail/ezjail_archives。可以通过在配置文件中设置 ezjail_archivedir 来选择一个不同的归档目录。
可以将存档文件作为备份复制到其他位置,也可以使用 restore 从中恢复现有 jail。可以从存档中创建新的 jail,从而为克隆现有 jail 提供便捷的方法。
停止 jail 并存档一个名为 wwwserver
1
# ezjail-admin stop wwwserver
2
Stopping jail: wwwserver.
3
# ezjail-admin archive wwwserver
4
# ls /usr/jail/ezjail-archives/
5
wwwserver-201407271153.13.tar.gz
Copied!
根据在上一步中创建的存档创建一个名为 wwwserver-clone 的新 jail。使用 em1 接口并分配新的 IP 地址以避免与原始 IP 地址冲突:
1
# ezjail-admin create -a /usr/jail/ezjail_archives/wwwserver-201407271153.13.tar.gz wwwserver-clone 'lo1|127.0.3.1,em1|192.168.1.51'
Copied!

15.6.6. 完整示例:在 Jail 中绑定

将 BINDDNS 服务器放入 jail 中可以通过隔离它来提高安全性。此示例创建一个简单的仅缓存域名服务器。
  • jail 将被称为 dns1
  • jail 将使用主机接口 re0 上的 IP 地址 192.168.1.240
  • 上游 ISP 的 DNS 服务器位于 10.0.0.6210.0.0.61
  • basejail 已经创建,并且安装了 ports 树,如 初始设置 中所示。
示例 3.在 jail 里运行
通过向 /etc/rc.conf 添加一行来创建克隆的环回接口:
1
cloned_interfaces="lo1"
Copied!
立即创建新的环回接口:
1
# service netif cloneup
2
Created clone interfaces: lo1.
Copied!
创建 jail:
1
# ezjail-admin create dns1 'lo1|127.0.2.1,re0|192.168.1.240'
Copied!
启动 jail,连接到在其上运行的控制台,然后执行一些基本配置:
1
# ezjail-admin start dns1
2
# ezjail-admin console dns1
3
# passwd
4
Changing local password for root
5
New Password:
6
Retype New Password:
7
# tzsetup
8
# sed -i .bak -e '/adjkerntz/ s/^/#/' /etc/crontab
9
# sed -i .bak -e 's/127.0.0.1/127.0.2.1/g; s/localhost.my.domain/dns1.my.domain dns1/' /etc/hosts
Copied!
/etc/resolv.conf 中临时设置上游 DNS 服务器,以便可以下载 ports:
1
nameserver 10.0.0.62
2
nameserver 10.0.0.61
Copied!
仍在使用 jail 控制台,安装 dns/bind99
1
# make -C /usr/ports/dns/bind99 install clean
Copied!
通过编辑 /usr/local/etc/namedb/named.conf 来配置域名服务器。
创建允许向此域名服务器发送 DNS 查询的地址和网络的访问控制列表 (ACL)。此部分将添加到文件中已有的 options 部分之前:
1
...
2
// or cause huge amounts of useless Internet traffic.
3
4
acl "trusted" {
5
192.168.1.0/24;
6
localhost;
7
localnets;
8
};
9
10
options {
11
...
Copied!
listen-on 设置中使用 jail IP 地址来接受来自网络上其他计算机的 DNS 查询:
1
listen-on { 192.168.1.240; };
Copied!
通过更改 forwarders 该部分来创建一个简单的仅缓存 DNS 域名服务器。原始文件包含:
1
/*
2
forwarders {
3
127.0.0.1;
4
};
5
*/
Copied!
通过删除 /**/ 行来取消注释该部分。输入上游 DNS 服务器的 IP 地址。紧跟在 forwarders 部分之后,添加对前面定义的 trusted ACL 的引用:
1
forwarders {
2
10.0.0.62;
3
10.0.0.61;
4
};
5
6
allow-query { any; };
7
allow-recursion{ trusted; };
8
allow-query-cache { trusted; };
Copied!
/etc/rc.conf 中启用该服务:
1
named_enable="YES"
Copied!
启动并测试域名服务器:
1
# service named start
2
wrote key file "/usr/local/etc/namedb/rndc.key"
3
Starting named.
4
# /usr/local/bin/dig @192.168.1.240 freebsd.org
Copied!
响应包括
1
;; Got answer;
Copied!
显示新的 DNS 服务器正在工作。长时间延迟后出现响应,包括
1
;; connection timed out; no servers could be reached
Copied!
显示一个问题。检查配置设置,并确保任何本地防火墙允许对上游 DNS 服务器进行新的 DNS 访问。
新的 DNS 服务器可以像其他本地计算机一样,将自身用于本地名称解析。在客户端计算机的 /etc/resolv.conf 中设置 DNS 服务器的地址:
1
nameserver 192.168.1.240
Copied!
可以将本地 DHCP 服务器配置为为本地 DNS 服务器提供此地址,从而在 DHCP 客户端上提供自动配置。