14.6. 使用 ezjail 管理 Jail

Originally contributed by Warren Block.

创建和管理多个 Jail 可能很快就会变得繁琐和容易出错。Dirk Engling的ezjail简化了 Jail 管理。创建basejail模板。其他 Jail 使用 mount_nullfs(8)共享 basejail 目录,不使用额外的磁盘空间。在安装应用程序之前,每个 jail 只占用几兆字节的磁盘空间。升级 basejail 中的用户态的副本,会自动升级所有 Jail。

关于 ezjail 的更多信息可以在ezjail 的网站https://erdgeist.org/arts/software/ezjail/ 上找到。

14.6.1. 安装ezjail

安装ezjail时将添加一个回环接口,在 jail 中使用,安装端口或软件包以及启用服务。

  1. 为了将 jail 回环流量从主机的环回网络接口lo0上保留下来,通过向/etc/rc.conf添加条目来创建第二个回回接口:

    cloned_interfaces="lo1"

    系统启动时将创建第二个回环接口 lo1。您也可以手动创建,无需重启:

    # service netif cloneup
    Created clone interfaces: lo1.

    可以允许 Jail 使用此辅助回环接口的别名,不会干扰主机。

    在 jail 内,访问环回地址127.0.0.1时将重定向到分配给该 jail 的第一个 IP 地址。为了让 jail loopback 与 新的接口 lo1对应,该接口必须在接口列表的首位并在 jail 创建时就指定 IP 地址。

    127.0.0.0/8网络块为每个 jail 配置不同的回环地址。

  2. 安装sysutils/ezjail

    # cd /usr/ports/sysutils/ezjail
    # make install clean
  3. 将这行添加到/etc/rc.conf,启用ezjail

    ezjail_enable="YES"
  4. ezjail 将在系统启动时启动。现在使用此命令启动 ezjail:

    # service ezjail start

14.6.2. 初始设定

安装了ezjail后,可以创建并填充basejail目录结构。这一步只需要在 jail 主机上执行一次即可。

在这两个例子中, -p 会导致将 portsnap(8) 检索到 basejail 中的 port 树。这个单独的 ports 目录副本将被所有的 jail 共享。为 jails 使用单独的 ports 目录副本, 可以将它们与主机隔离开来。ezjail FAQ 中有更详细的说明:http://erdgeist.org/arts/software/ezjail/#FAQ

    • 在 jail 中使用 FreeBSD-RELEASE

      对于基于 FreeBSD RELEASE 版本的 basejail, 请使用 install。例如, 在运行 FreeBSD 10-STABLE 的主机上, 将会在 jail中安装最新的 FreeBSD -10 的 RELEASE 版本:

      # ezjail-admin install -p
    • 使用 installworld 填充 jail

      basejail可以通过buildworld在主机上用ezjail-admin update创建的二进制文件来安装。

      在此示例中,已从源码编译好了 FreeBSD 10-STABLE。jail 目录也创建好了。然后执行 installworld,将主机的/usr/obj安装到 basejail。

      # ezjail-admin update -i -p

      主机的/usr/src是默认使用的。在主机上可以用-s和路径指定不同的源目录,或者在/usr/local/etc/ezjail.conf中用ezjail_sourcetree设置。

提示:

basejail 的 port 树是由其他jail共享的。但是,下载的 distfiles 会被存储在下载这些文件的 jail 中。默认情况下,这些文件存储在每个 jail 中的 /var/ports/distfiles 中。jail 内的 /var/ports 也是 port 的工作目录。

提示:

FTP协议默认用于下载安装basejail的软件包。防火墙或代理配置可以阻止或干扰 FTP传输。HTTP协议的工作方式不同,可以避免这些问题。它可以通过在/usr/local/etc/ezjail.conf中指定一个完整的URL来选择:

ezjail_ftphost=http://ftp.FreeBSD.org

查看第 A.2 节 “FTP 站点”获取完整站点列表。

14.6.3. 建立并启动新的Jail

ezjail-admin create创建新的 jails。在这些例子中,如上所述,使用了lo1环回接口。

过程 14.1. 创建并启用新的 Jail
  1. 创建 jail,指定一个名称和要使用的环回和网络接口,以及它们的IP地址。在这个例子中,jail 被命名为dnsjail

    # ezjail-admin create dnsjail 'lo1|127.0.1.1,em0|192.168.1.50'

    提示:

    大多数网络服务可以在 jail 中运行,没有任何问题。少数网络服务,例如 ping(8),使用的是raw网络套接字。在 jail 中,为了安全起见,默认情况下禁用原始网络套接字。需要它们的服务将无法工作。

    偶尔,jail 真正需要的是原始套接字(socket)。例如,网络监控应用程序经常使用ping(8)来检查其他计算机的可用性。当 jail 中实际需要原始网络套接字时,可以通过编辑 jail 的ezjail配置文件,/usr/local/etc/ezjail/jailname来启用。修改parameters条目:

    export jail_jailname_parameters="allow.raw_sockets=1"

    不要启用原始网络套接字,除非 jail 中的服务真的需要它。

  2. 启动 jial:

    # ezjail-admin start dnsjail
  3. 打开 dnsjail jail 的控制台:

    # ezjail-admin console dnsjail

Jail 开始运行,可以完成额外的配置。这时添加的典型设置包括:

  1. 设置root 密码

    连接到 jail 并设置 root 密码:

    # ezjail-admin console dnsjail
    # passwd
    Changing local password for root
    New Password:
    Retype New Password:
  2. 设置时区

    可以用tzsetup(8)来设置 jail 的时区。为了避免虚假错误信息,可以注释或删除/etc/crontab中的adjkerntz(8)条目。这个工作试图用时区变化来更新计算机的硬件时钟,但监听器不允许访问该硬件。

  3. DNS 服务器

    /etc/resolv.conf写入域名服务器地址,这样jail中就能正常使用DNS

  4. 编辑 /etc/hosts

    修改地址并添加 jail 名字到/etc/hostslocalhost条目中。

  5. 配置 /etc/rc.conf

    /etc/rc.conf中输入配置信息。这和配置一台完整的计算机很像。这里不设置主机名和 IP地址。这些值已经由 jail 配置提供了。

配置好 jail 后,可以在该 jail 中安装应用程序。

提示:

有些 port 必须通过特殊选项来构建,才能在 jail 中使用。例如,网络监控插件包 net-mgmt/nagios-pluginsnet-mgmt/monitoring-plugins都有JAIL选项,必须启用该选项才能在 jail 中正常工作。

14.6.4. 更新Jail

14.6.4.1. 更新操作系统

因为basejail的用户的副本是由其他 jail 共享的,所以更新basejail会自动更新所有其他 jail。可以使用源码或二进制文件更新。

在宿主机上从源码编译FreeBSD基础系统,并将其装入basejail中:

# ezjail-admin update -b

如果已经在主机上编译好 world,使用以下命令将其安装到 basejail 中:

# ezjail-admin update -i

使用freebsd-update(8)进行二进制更新。这些更新与直接运行freebsd-update(8)的限制是一样的。注意,只有 FreeBSD-RELEASE 才能这种方法。

使用主机中的 FreeBSD 补丁更新 basejail,例如从 RELEASE-p1 更新到 RELEASE-p2。

# ezjail-admin update -u

要将 basejail 升级到新版本,首先要按照第 23.2.3 节 “执行主要及次要版号升级”中的描述升级主机系统。一旦主机升级并重新启动后,就可以升级basejail。freebsd-update(8)无法确定当前 basejail 中安装的是哪个版本,所以必须指定原始版本。使用 file(1)来确定 basejail 中的原始版本:

# file /usr/jails/basejail/bin/sh
/usr/jails/basejail/bin/sh: ELF 64-bit LSB executable, x86-64, version 1 (FreeBSD), dynamically linked (uses shared libs), for FreeBSD 9.3, stripped

现在使用此信息将主机从 9.3-RELEASE 升级到 current 版本:

# ezjail-admin update -U -s 9.3-RELEASE

更新 basejail 后,需执行 mergemaster(8) 来更新 jail 配置文件。

如何使用mergemaster(8)取决于 jail 的目的和可信度。如果 jail 的服务或用户不受信任,则mergemaster(8)应仅从该 jail 内运行:

例 14.1. 在不信任的Jail做mergemaster(8)

将 jail 中的 /usr/src 删除,并中创建一个新的/usr/src作为挂载点。将主机的/usr/src只读挂载在 jail 的新/usr/src挂载点上:

# rm /usr/jails/jailname/usr/src
# mkdir /usr/jails/jailname/usr/src
# mount -t nullfs -o ro /usr/src /usr/jails/jailname/usr/src

打开 jail 的控制台:

# ezjail-admin console jailname

在 jail 中执行 mergemaster。然后退出 jail 控制台:

# cd /usr/src
# mergemaster -U
# exit

最后,卸载 jail 中的 /usr/src

# umount /usr/jails/jailname/usr/src

例 14.2. 在信任的Jail做mergemaster(8)

如果 jail 中的用户和服务都是可信的,mergemaster(8) 可以从主机中运行:

# mergemaster -U -D /usr/jails/jailname

提示:

sysutils/ezjail 升级到合适版本后后还需将 pkg 升级到正确版本,输入:

# pkg-static upgrade -f pkg

升级到或降级到适当的版本。

14.6.4.2. 更新Port

basejail 中的 port 和其他 jail 共享。更新该 port 树时也会更新其他 jail 的 port。

使用portsnap(8)更新 basejail ports 树:

# ezjail-admin update -P

14.6.5. 控制Jail

14.6.5.1. 停止与启动Jail

当计算机启动时,ezjail会自动启动 jail。可以使用stopstart手动停止和重启 jail:

# ezjail-admin stop sambajail
Stopping jails: sambajail.

默认情况下,当主机启动时,将自动启动 jail。可以通过config禁止自动启动 jail :

# ezjail-admin config -r norun seldomjail

这将在下次启动主机时生效。已运行的 jail 不会停止。

开启自动启动:

# ezjail-admin config -r run oftenjail

14.6.5.2. 封存与还原Jail

使用archive创建一个 jail 的.tar.gz存档。文件名由 jail 的名称和当前日期组成。归档文件被写入归档目录,/usr/jails/ezjail_archives。可以通过在配置文件中设置 ezjail_archivedir来选择不同的归档目录。

可以将存档文件复制到其他地方作为备份,或者用restore还原现有的 jail。可以从存档中创建一个新的 jail,为克隆现有的 jail 提供了一种方便的方法。

关闭和保存名为wwwserver的 jail:

# ezjail-admin stop wwwserver
Stopping jails: wwwserver.
# ezjail-admin archive wwwserver
# ls /usr/jails/ezjail-archives/
wwwserver-201407271153.13.tar.gz

从上一步创建的存档中创建一个新的 jail,命名为wwwserver-clone。使用em1接口,并分配一个新的IP地址,避免与原地址冲突:

# ezjail-admin create -a /usr/jails/ezjail_archives/wwwserver-201407271153.13.tar.gz wwwserver-clone 'lo1|127.0.3.1,em1|192.168.1.51'

14.6.6. 完整示例:在Jail中安装BIND

BIND DNS服务器放在 jail 中,提高安全性。这个例子创建了一个简单的仅有缓存的名称服务器。

  • 这个 jail 名字是dns1

  • jail 将在主机的 re0 接口上使用 192.168.1.240 IP 地址。

  • ISP提供的 DNS 地址是10.0.0.6210.0.0.61

  • 已经创建了 basejail,并安装了一个 port 树,如第 14.6.2 节 “初始设定”中所示。

例 14.3. 在Jail中执行BIND

将以下行添加到 /etc/rc.conf 创建克隆的环回接口:

cloned_interfaces="lo1"

创建新的回环接口:

# service netif cloneup
Created clone interfaces: lo1.

创建 Jail:

# ezjail-admin create dns1 'lo1|127.0.2.1,re0|192.168.1.240'

启动 jail 并连接到它的控制台,进行基础配置:

# ezjail-admin start dns1
# ezjail-admin console dns1
# passwd
Changing local password for root
New Password:
Retype New Password:
# tzsetup
# sed -i .bak -e '/adjkerntz/ s/^/#/' /etc/crontab
# sed -i .bak -e 's/127.0.0.1/127.0.2.1/g; s/localhost.my.domain/dns1.my.domain dns1/' /etc/hosts

/etc/resolv.conf中临时设置上游的 DNS服务器,以便下载 ports:

nameserver 10.0.0.62
nameserver 10.0.0.61

使用 jail 控制台安装 dns/bind99

# make -C /usr/ports/dns/bind99 install clean

通过/usr/local/etc/namedb/named.conf配置域名服务器。

创建一个访问控制列表(ACL),包含允许向此名称服务器发送DNS查询的地址和网络。这一部分被添加到文件中的options部分之前:

...
// or cause huge amounts of useless Internet traffic.

acl "trusted" {
	192.168.1.0/24;
	localhost;
	localnets;
};

options {
...

使用listen-on设置中的 jail IP地址来接受来自网络上其他计算机的DNS查询:

	listen-on	{ 192.168.1.240; };

通过修改DNS部分,创建了一个简单的仅有缓存的DNS服务器。原的文件包含:

/*
	forwarders {
		127.0.0.1;
	};
*/

删除/**/,取消该部分的注释。输入上游DNS服务器的IP地址。紧接着在forwarders部分之后,添加对先前定义的trusted ACL的引用:

	forwarders {
		10.0.0.62;
		10.0.0.61;
	};

	allow-query       { any; };
	allow-recursion   { trusted; };
	allow-query-cache { trusted; };

将此行命令添加到/etc/rc.conf来启动 namd:

named_enable="YES"

启动并测试域名服务器:

# service named start
wrote key file "/usr/local/etc/namedb/rndc.key"
Starting named.
# /usr/local/bin/dig @192.168.1.240 freebsd.org

回应中应包含以下信息

;; Got answer;

显示新的DNS服务器正在工作。长时间的延迟,然后是一个包括以下内容的响应

;; connection timed out; no servers could be reached

显示有问题。检查配置设置,确保任何本地防火墙都允许DNS访问上游DNS服务器。

新的DNS服务器可以使用自身进行本地名称解析,就像其他本地计算机一样。在客户机的/etc/resolv.conf中设置DNS服务器的地址:

nameserver 192.168.1.240

可以将本地DHCP服务器配置为为本地DNS服务器提供此地址,从而在DHCP客户端上提供自动配置。


本文档和其它文档可从这里下载: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

如果对于FreeBSD有问题,请先阅读 文档,如不能解决再联系 <questions@FreeBSD.org>.

关于本文档的问题请发信联系 <doc@FreeBSD.org>.