Jail的管理手段有很多, 包含ezjail, cbsd等; 从个人的简单需求以及对于epair的管理来看, 通过原生jail的配置进行管理是最简单的.
zfs的环境准备
创建相关的zfs
# zfs create -o compress=lz4 -o mountpoint=/jails vtank/jails
# zfs create vtank/jails/basejail
basejail环境准备
创建basejail 并且创建基础模板.
# wget https://download.freebsd.org/ftp/releases/amd64/11.2-RELEASE/base.txz
# wget https://download.freebsd.org/ftp/releases/amd64/11.2-RELEASE/lib32.txz
# tar -zxvf ~/base.txz -C /jails/basejail
# tar -zxvf ~/lib32.txz -C /jails/basejail
# freebsd-update -b /jails/basejail fetch install
# freebsd-update -b /jails/basejail IDS
创建snapshot, 制作fullbase的模板
# zfs snapshot vtank/jails/basejail@base
# zfs clone vtank/jails/basejail@base vtank/jails/fullbase
# cd /jails/fullbase
# chflags 0 lib/*
# chflags 0 sbin/*
# rm -Rf bin boot lib libexec rescue sbin
# mdkir basejail
# mount_nullfs /jails/basejail /jails/fullbase/basejail
# ln -s basejail/bin
# ln -s basejail/boot
# ln -s basejail/lib
# ln -s basejail/libexec
# ln -s basejail/rescue
# ln -s basejail/sbin
# zfs snapshot vtank/jails/fullbase@base
Jail 配置及启动
基于fullbase模板 , 创建所需的jail
# zfs clone vtank/jails/fullbase@base vtank/jails/web
每次创建jail, 需要改动/etc/jail.conf配置文件, 样例如下, 采用epair配置网络.
host.hostname = "${name}.azming.com";
path = "/jails/${name}";
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";
exec.clean;
allow.raw_sockets;
mount.devfs;
devfs_ruleset="4";
exec.system_user = "root";
exec.jail_user = "root";
vnet;
exec.consolelog = "/var/log/jail_${name}_console.log";
exec.prestart += "cp /etc/resolv.conf $path/etc";
exec.prestart += "cp /etc/hosts $path/etc";
exec.prestart += "ifconfig ${ext_epair} create up";
exec.prestart += "ifconfig bridge0 addm ${ext_epair}a";
exec.prestart += "/sbin/mount -t nullfs -o ro /jails/basejail /jails/$name/basejail" ;
exec.start += "ifconfig ${ext_epair}b $ext_ipadd netmask 255.255.255.0 ";
exec.prestop += "ifconfig ${ext_epair}b -vnet $name";
exec.poststop += "rm $path/etc/resolv.conf";
exec.poststop += "ifconfig bridge0 deletem ${ext_epair}a";
exec.poststop += "ifconfig ${ext_epair}a destroy";
exec.poststop += "umount /jails/$name/basejail";
desktop {
$ext_epair = "epair10";
$int_epair = "epair11";
$ext_ipadd = 192.168.3.250;
$int_ipadd = 192.168.1.250;
$gwv4 = "192.168.1.100";
vnet.interface = "${ext_epair}b", "${int_epair}b";
exec.prestart += "ifconfig ${int_epair} create up";
exec.prestart += "ifconfig bridge1 addm ${int_epair}a";
exec.start += "ifconfig ${int_epair}b $int_ipadd netmask 255.255.255.0 ";
exec.start += "route add default $gwv4";
exec.prestop += "ifconfig ${int_epair}b -vnet $name";
exec.poststop += "ifconfig bridge1 deletem ${int_epair}a";
exec.poststop += "ifconfig ${int_epair}a destroy";
}
cronrun {
$ext_epair = "epair20";
#$int_epair = "epair21";
$ext_ipadd = 192.168.3.200;
#$int_ipadd = 192.168.1.200;
$gwv4 = "192.168.3.1";
vnet.interface = "${ext_epair}b";
exec.start += "route add default $gwv4";
}
如果不采用epair的方式来配置网络, 配置方案如下:
interface = lo1 ;
mount.devfs ;
allow.nomount ;
allow.sysvipc = 0 ;
####
host.hostname = "$name.azming.com" ;
path = "/jail/$name" ;
ip4.addr = 192.168.1.$ip ;
####
#jail for name
jail1 {
$ip = 1 ;
}
配置PF能够使jail访问外网以及端口映射
rc.conf配置
gateway_enable="YES"
pf_enable="YES"
pf_flags=""
pf_rules="/etc/pf.conf"
pflog_enable="NO"
cloned_interfaces="bridge0 bridge1"
autobridge_interfaces="bridge0 bridge1"
autobridge_bridge0="re0"
autobridge_bridge1="re1"
ifconfig_bridge0="inet 192.168.3.254 netmask 0xffffffff"
ifconfig_bridge1="inet 192.168.1.254 netmask 0xffffffff"
pf.conf配置
set skip on lo0
#scrub in on vtnet0 all
nat on vtnet0 from 192.168.100.0/24 to any -> (vtnet0)
nat on vtnet0 from 10.0.0.0/16 to any -> (vtnet0)
#ezjail
rdr on vtnet0 inet proto tcp from any to (vtnet0) port 80 -> 192.168.100.100 port 80
rdr on vtnet0 inet proto tcp from any to (vtnet0) port 443 -> 192.168.100.100 port 443
block in on vtnet0 proto tcp from any to any
pass in on vtnet0 proto tcp from any to (vtnet0) port 22 keep state
pass in on vtnet0 proto tcp from any to 192.168.100.100 port 80 keep state
pass in on vtnet0 proto tcp from any to 192.168.100.100 port 443 keep state
pass out on vtnet0 all keep state
pass inet proto icmp all icmp-type echoreq keep state
pass in on lo0 all keep state
pass out on lo0 all keep state
后续Jail中的工作
# jls
# jexec jail_name /bin/csh
# pkg info
# pkg install nginx py37-certbot-nginx
使用ezjail来管理jail
install ezjail
use pkg install the package ezjail
pkg install ezjail
config the file
modify the /usr/local/etc/ezjail.conf
file modify the parameters like below :
ezjail_use_zfs=YES
ezjail_jailzfs=aliroot/ezjail //the zfs will create by ezjail-admin
ezjail_use_zfs_for_jails=YES
there is another parameter like : ezjail_ftphost=ftp.tw.freebsd.org
build the basejail
the basejail will be read only , and ezjail-admin will build basejail .
just install basics . not include ports , manual pages and sources code .
use the command ezjail-admin install
will install the base OS again .
and you can point the version to install for the command like below :
ezjail-admin install -r 12.0-RELEASE
if you want update and install the port or manual or source , can use
ezjail-admin install -SPM
after above .
some other parameter detail information :
ezjail-admin install [-mMpPsS] [-h host] [-r release]
-m 下载并安装 man 手册页。
-M 下载并安装 man 手册页,但不(重新)安装基本系统。用于基本系统已经安装好,增加 man 手册页。
-p 调用 portsnap 下载安装 ports 树。Tips:下载服务器在哪里设置呢?在 /etc/portsnap.conf。
-P 类似上面,不(重新)安装基本系统。
-s 下载安装源代码。
-S 类似上面,不(重新)安装基本系统。
-h 指定下载服务器。默认使用 ezjail.conf 的服务器。
-r 指定下载的版本。ezjail-admin 会调用 uname -r 来获得默认版本。
use the parameter -i
will build world from world , like ezjail-admin setup -i
then ,you can use the ezjail-admin setup -b
to instalworld.
keep the ezjail up to date
ezjail can use the freebsd-update tool to keep basejail up to date :
ezjail-admin update -u
this will upgrade the system release .
ezjail-admin update -P
this will upgrade the ports tree .
some other parameter detail information :
ezjail-admin update [-s sourcetree | sourceosversion] [-p] -b | -i | -P | -u | -U
-s 与 -b 或 -i 同用时,指定源代码路径。与 -U 同用时指定用于 freebsd-update 的版本。
-p 调用 portsnap 为基本系统提供 ports 树。
-b make buildworld; make installworld, 更新或安装基本系统。不会清理基本系统的旧文件。
-i make installworld,更新或安装基本系统。如果之前已经 make buildworld 过,这会省很多时间。
-P 仅仅更新 ports。
-u 调用 freebsd-update 更新基本系统,调用 uname -r 获得版本号。注意宿主机系统要同时更新。
-U 调用 freebsd-update 把基本系统升级到和宿主机相同的版本。或者用 UNAME_r 环境变量指定版本。
if there is some mistake with No such file or directory
you can use this command to fix it:
mount_nullfs /usr/jails/basejail /basejail
start ezjail create a new jail system
ezjail-admin create hexo 'lo1|192.168.100.11,em0|192.168.1.50'
ezjail-admin start hexo
create jail automatic by config file
create from flavours :
ezjail-admin create -f example hexo 'lo1|192.168.100.1'
use the jail to mount the data folder
modify the file /etc/fstab.*
add the line :
/opt /usr/jails/git/opt nullfs rw,late 0 0
will mount the /opt to the folder in the jail . but use the df in the jail can not see the mount status .
snapshop and restore
ezjail-admin snapshot hexo
if you want rebuild the jail in another machine, use the method:
ezjail-admin archive book
ezjail-admin create -a /usr/jails/ezjail_archives/book-201902182303.08.tar.gz book1 'lo1|192.168.100.10'
mount new disk to the os
gpart create -s GPT /dev/vtbd1
gpart add -t freebsd-ufs -a 1M /dev/vtdb1
gpart show vtdb1
newfs -U /dev/vtdb1p1
mount /dev/vtdb1p1
want use ping inside jail
edit the config per jail the path is ‘/use/local/etc/ezjail’
every will be have there direct configuration add the parameters like below: export jail_jailname_parameters=“allow.raw_sockets=1”
fix some issue when remove jail
ezjail_admin delete jail_name
then, there is a folder need to delete mannal
chflags -R noschg /usr/jails/jail_name
rm -Rf /usr/jails/jail_name