第 9.4 节 使用 qjail 管理 jail
最后更新于
最后更新于
FreeBSD 中文社区 2024
qjail 是 jail 环境的部署工具,分支自 ezjail 3.1。jail 管理工具有 ezjail、 qjail、 iocage 等。ezjail 在 2015 年更新到 3.4.2 后一直没有更新,2018 年做过一次错误更新,不过好像也不是作者写的。ezjail 的 ports 更新依赖 portsnap,这个现在已经不建议使用了,将被废弃。iocage 可依赖于 zfs 文件系统,使用 ufs 文件系统的并不能使用。qjail 则在这些方面不存在问题。ezjail 并不支持 jail 的 vnet 功能,iocage 和 qjail 则支持。ezjail 和 qjail 使用 sh 编写,iocage 使用 python 编写。
下文中部署的 jail 在概念上结构如下图:
文中会用到 pf 防火墙,使用其它防火墙的可以自行尝试进行防火墙相关配置
/etc/rc.conf
文件中写入
运行
lo1 将获得 10 个 ip 地址,下面将用 1-9 这 9 个 ip 给 jail 使用。
或者
启用 qjail
使用 qjail 前首先要部署 qjail 使用的目录结构,有两种方式:
此时 qjail 会从 FreeBSD 官网下载 base.txz 文件,示例输出如下:
因境内网络问题,也可以用镜像手动进行,以中国科学技术大学镜像为例(下载文件是注意版本号,qjail 要求文件版本与宿主机一致,这里是 FreeBSD amd64 13.1)
部署好 qjail 的目录结构后 /usr/jails
目录下会自动生成 sharedfs
template
archive
flavors
四个目录:
sharedfs 包含一份只读的操作系统可执行库文件,挂载为 nullfs ,在各 jail 之间共享,以节省存储空间的使用。
template 包含操作系统的配置文件,将被复制到每个 jail 的基本文件系统中
archive 保存 jail archive 命令产生的存档文件
flavors 包含系统风格( flavors )和用户创建的自定义风格,其实就是自己定义的配置文件等
-n
指定使用 lo1 作为网络接口,-4
指定 ipv4 地址。
生成 jail1 后,/usr/jails/
目录下对应生成 jail1
目录( /usr/jails/jail1/
),保存相应文件。
可以在上面提到的 flavors
目录中建立自己的配置文件以便在部署 jail 时复制到新的 jail 中。
如,新建 /usr/jails/flavors/default/usr/local/etc/pkg/repos/FreeBSD.conf
,那么之后再新建 jail 时,会自动把这个文件复制到对应的 jail 中,即
建立 jail2 后,自动建立 /usr/jails/jail2/usr/local/etc/pkg/repos/FreeBSD.conf
,既修改了之后所有 jail 的默认 pkg 镜像。但对应 jail1 并没有生成这个文件,因为生成 jail1 时,还没有在 flavors 目录中写入相应文件。
列出 qjail 管理的 jail
启用 jail
停止 jail
重启 jail
进入 jail 控制台
进入 jail 控制台后,此时是 jail 中的 root 帐号(进入 jail 的控制台,不需要输入密码),因 jail 可能开启对外服务,为安全考虑建议设置帐号密码
备份 jail
从备份中恢复 jail
删除 jail
下面更新 jail 的部分不针对单个 jail ,而是针对每个 jail ,因为这些文件利用 nullfs 共享一份。
既上面提到的 sharedfs 中的文件
这里有-p
(小写) 、 -P
(大写)两个选项,-p
(小写)使用 portsnap 更新 jail 的 ports tree,-P
(大写)使用宿主机的 ports tree 更新 jail 的 ports。如果主机已有 ports,则建议使用 -P
(大写),避免两次下载 ports。
或者
开始更新:
qjail 可以用 qjail config
命令对每个 jail 另作设置,运行 qjail config
前须选停用指定的 jail。
qjail config
命令选项较多,这里列出几个常用的,更多的请参考手册页
qjail -- Utility for deployment of jail environments
-h
快速开启 jail1 的 ssh 服务,新建一个 wheel 组用户,用户名和密码同 jail 名,首次用这个用户登录要求修改密码。也可以在登录 jail 控制台后,自行配置 sshd 服务。
-m
-M
设置 jail1 需手动启动(manual 状态),qjail_enable="YES"
写入 /etc/rc.conf
后在系统启动时会自动启动各个 jail ,设为手动启动后则不会在系统启动时自动启动相应的 jail ,须用 qjail start jailname
启动。
对应小写的 -m
选项,有大写的 -M
选项,作用为关闭手动启动状态,即清除 manual 状态,可以在系统启动时自动启用 jail。qjail 中有大量类似的选项,小写字母的选项启用某个功能,大写字母的选项关闭对应功能。如果下文中同时出现小写和大写的选项就不在过多作出说明。
-r
-R
将 jail1 设为不允许启动(norun 状态),相当于禁用该 jail。
-y
-Y
启用该 jail 的 SysV IPC,在 jail 中安装 postgresql 时,需要打开这个选项,postgresql 运行基于这个功能。
这里作个提示,有的教程里会教你用 qjail config -k jailname
打开 raw_sockets 功能来打开外网访问的能力,其实这里是个误解,raw_sockets 只是像 ping 一类的工具需要使用而已,并不是说网络访问一定要打开 raw_sockets 。而且在 jail 中打开 raw_sockets 本身有安全风险,这是 jail 环境默认的一种安全设计。所以除非是你一定要在 jail 中用 ping 一类的工具,不管是用什么方式构建的 jail 都是不建议打开 raw_sockets 功能的。
此时的 jail 还不能连接网络,因为 jail 绑定在 lo1 网络接口上,lo1 并不能直接访问外网,接下来通过 pf 设定网络, 其中 em0
为外网接口
在 /etc/pf.conf
中写入
此时,绑定在 lo1 上的 jail 可以访问宿主机外网络,宿主机外网络可以通过宿主机 22 号端口连接 jail1 的 22 号端口。
假设已经如上文所述预留 jail ip,并成功运行 qjail install
命令
这里以 postgresql 15 为例,其它版本也适用
宿主机中操作
编辑 /etc/pf.conf
启用 pf
进入名为 postgres 的 jail 的控制台
jail 控制台中的操作
下面命令皆在 jail 控制台下运行,pkg 安装是否使用镜像可自行决定,如果使用镜像可以在 jail 控制台中如同宿主机般进行设置,请参考相关文章。
安装:
或者
配置:
这里使用 initdb 而不是使用安装时提示的 /usr/local/etc/rc.d/postgresql initdb
是为了避免之后设置数据库密码时,来回修改 pg_hba.conf
文件,现对选项作简要说明:
-A
为本地用户指定在 pg_hba.conf 中使用的默认认证方法
-E
选择模板数据库的编码。
-W
让 initdb 提示要求为数据库超级用户给予一个口令
-D
指定数据库集簇应该存放的目录
至此 postgresql 服务已经可以运行
如果在上面的过程中忘记使用 qjail config -y postgres
命令开启 SysV IPC,那么可能会出现下面的错误:
初始化数据库集簇时的错误
启动 postgresql 时的错误
此时在宿主机控制台下执行 qjail config -y postgres
即可修正错误,具体如下:
再次进入 jail 的控制台就可以正常初始化数据库集簇和运行 postgresql 服务了。