电子文档地址在Chapter15.Jails。
jail由四个要素组成:
- 目录子树
进入jail的起点。jail里面的进程不允许逃逸到此子树之外。
- 主机名
每个jail都有一个主机名。
- IP地址
需要为每个jail分配一个IP地址。jail的IP地址通常是现有网络接口的别名地址。
- 命令
要在jail内运行的可执行文件的路径名。路径是相对于jail环境的根目录的。
jail有一套自己的用户和用户组,仅限于jail内,这些用户和组不会对jail之外的系统进行操作。
jail很强大,但不是完全安全。jail外面的非特权用户可以通过数种方式与jail内的特权用户合作,在宿主环境中获得提升的特权。
应确保主机环境中的非特权用户无法访问jail根目录。
作为一般原则,对jail具有特权访问权限的不受信任用户不应被授予对主机环境的访问权限。
ezjail是FreeBSD官方手册中收录的一个管理jail的工具,既然能进官方手册,应该不会太差。
实际上我想当然了。尽管官网手册收录了了ezjail,而且iRedMail也以ezjail举例,但实际上ezjail从2015年的3.4.2版以后就没有再更新过了。
安装ezjail的方法很简单:pkg install ezjail
如果想要ezjail随系统自动启动,可以在/etc/rc.conf中加入以下行:ezjail_enable="YES"
然后启动它:
# service ezjail start
ezjail的官方网站
ezjail的配置文件是:/usr/local/etc/ezjail.conf
使用ezjail创建的每一个jail的配置文件放在:/usr/local/etc/ezjail/
其中比较重要的几个设置:
- ezjail_jaildir=/usr/jails
指示jail默认保存路径,如果确定使用zpool的话,可以在这里设置,比如ezjail_jaildir=/zdata/jails。
接下来的ezjail_jailtemplate和ezjail_jailbase将套用这个设置来确定自己的路径。
- ezjail_sourcetree=/usr/src
指示jail使用的内核源代码树,默认的为宿主机的源代码树。
- ezjail_ftphost=ftp.freebsd.org
指示从何处下载basejail,此处可修改为http://ftp.freebsd.cn/FreeBSD,或,https://mirrors.ustc.edu.cn/freebsd。
- ezjail_default_execute="/usr/bin/login -f root
指示进入jail控制台后自动登录root账号。
- ezjail_use_zfs="YES"
指示使用ZFS管理basejail和newjail。
- ezjail_use_zfs_for_jails="YES"
指示为每个新建的jail创建它自己的zfs。
- ezjail_jailzfs="tank/ezjail"
指示创建jail时建立的zfs挂载的位置,建议使用ezjail_jaildir目录。
注意,此文件受特别保护,vi编辑后需要用:w!保存。
修改完配置后,运行以下命令创建basejail:
# ezjail-admin install -p
-p用于接收ports tree。如果jail中需要安装一些依赖ports tree的软件,这一步很重要。
basejail创建完成之后会生成一个/$ezjail_jaildir/newjail的目录,以后创建jail都将以此为模板。
需要对这个模板中的一些文件进行修改:
- etc/pkg/FreeBSD.conf
将url行改为:url: "pkg+http://pkg.FreeBSD.cn/${ABI}/quarterly"
- etc/make.conf
加入一行:MASTER_SITE_OVERRIDE?=http://ports.freebsd.cn/ports-distfiles/${DIST_SUBDIR}/
- etc/resolv.conf
此文件需要创建,并加入一行:nameserver 8.8.8.8
- etc/portsnap.conf
修改SERVERNAME=portsnap,FreeBSD.cn
按照官方文档,为了避免jail里面的环回通讯影响到主机的lo0网口,需要在/etc/rc.conf中添加条目创建第二个环回接口:
cloned_interfaces="lo1"
并且,每创建一个jail都要先给它创建一个环回接口。
使用以下命令创建环回接口而不用重启:
# service netif cloneup
注意,每个jail都可以使用同一个环回接口,但需要给各个jail分配不同的127.0.0.0/8的IP地址。
接下来创建一个jail:
# ezjail-admin create mail.test.org 'lo1|127.0.1.1,em0|192.168.1.50'
新jail创建时会自动创建对应的zfs,但是在删除jail之后不会自动销毁对应的zfs。
然后启动它:
# ezjail-admin start mail.test.org
登录进去:
# ezjail-admin console mail.test.org
新jail创建后它的时区不会跟随宿主机,所以登录后需要使用tzsetup手动设置。
默认情况下,jail里面的raw网络套接字时被禁用的,像ping这类使用ras网络套接字的工具是无法使用的。需要在宿主机的/usr/locla/etc/ezjail/jailname修改以下参数:
export jail_jailname_parameters="allow.raw_sockets=1"
要删除一个jail,应先停止它,然后再删除:
# ezjail-admin stop mail.test.org
# ezjail-admin delete mail.test.org
或者使用-f参数强行删除:
# ezjail-admin delete -f mail.test.org
jail被删除后它的目录还在,需要手动删除。但是它有个目录 mail.test.org/var/empty是删不掉的。需要执行以下命令:
# chflags noschg empty
schg为系统不可改变标志。
然后将mail.test.org对应的zfs销毁:
# zfs destroy mail.test.org
最后,删除对应的目录:
# rmdir /zdata/jails/mail.test.org
以下命令从源代码buildworld并将其安装到basejail:
# ezjail-admin update -b
如果主机上已经编译了world,可以使用以下命令将其安装到basejail:
# ezjail-admin update -i
以下命令将basejail更新到主机上FreeBSD版本的最新修补版本:
# ezjail-admin update -u
宿主机如果升级了主要版本,当宿主机重启后就可以升级basejail。以下命令确定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版的basejail升级到宿主机当前的版本:
# ezjail-admin update -U -s 9.3-RELEASE
更新port tree:
ezjail-admin update -P
默认情况下jail会随主机启动而自动启动,可以使用以下命令禁止某个jail自动启动:
# ezjail-admin config -r norun jailname
改回自动启动:
# ezjail-admin config -r run jailname
以下操作停止并归档一个jail:
# ezjail-admin stop wwwserver
Stopping jails: wwwserver.
# ezjail-admin archive wwwserver
# ls /usr/jails/ezjail-archives/
wwwserver-201407271153.13.tar.gz
以下命令从归档文件创建一个新的jail,使用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'