Прикладная демонология, практические рецепты

Подготовка базовой системы

Скачиваем дистрибутивные файлы выбранного релиза:

sh -ceu 'export ARCH=amd64 REL=11.1-RELEASE; for x in base lib32 src; do curl -O https://download.freebsd.org/ftp/releases/$ARCH/$REL/$x.txz; done'

Готовим разделы для базовой системы и шаблона:

zfs create tank/jails/11.1-RELEASE-amd64
zfs create tank/jails/newjail

Разворачиваем базовую систему в каталог шаблона джейла:

sh -ceu 'for x in base lib32 src; do tar -C /jails/newjail -xpf $x.txz; done'

Создаем каталоги для монтирований:

cd /jails/newjail
mkdir -p export import/base usr/ports

Перемещаем каталоги с бинарными файлами из каталога шаблона в каталог базовой системы:

sh -ceu 'for x in bin boot lib libexec rescue sbin usr/*; do [ $x = usr/local -o $x = usr/obj -o $x = usr/ports ] && continue; find $x | cpio -dmp /jails/11.1-RELEASE-amd64; chflags -R noschg $x; rm -r $x; ln -s /import/base/$x $x; done'

Сразу выключаем ненужное:

echo 'cron_enable="NO"'       >> etc/rc.conf
echo 'sendmail_enable="NONE"' >> etc/rc.conf
echo 'syslogd_enable="NO"'    >> etc/rc.conf

Хорошим стилем является явное запрещение пароля для root:

echo \* | pw usermod -V etc root -H0

Копируем свой ключ в домашний каталог root (впоследствии это упростит эмуляцию доступности джейла по ssh):

mkdir root/.ssh
cp ~user/.ssh/authorized_keys root/.ssh

Создаем символическую ссылку для совместимости со старыми скриптами, ищущими интерпретатор Perl по предопределенному пути в базовой системе:

cd /jails/11.1-RELEASE-amd64
ln -s /usr/local/bin/perl usr/bin

Делаем результирующие snapshots:

zfs snapshot tank/jails/11.1-RELEASE-amd64@ready
zfs snapshot tank/jails/newjail@ready

Размонтируем раздел шаблона и удаляем его каталог:

umount /jails/newjail
rmdir /jails/newjail
zfs set mountpoint=legacy tank/jails/newjail

Создание нового джейла

Включаем запуск джейлов:

echo 'jail_enable="YES" >> /etc/rc.conf

Создаем файловую систему нового джейла из шаблона:

zfs send tank/jails/newjail@ready | zfs recv -v tank/jails/logger
zfs destroy tank/jails/logger@ready

Создаем конфигурацию джейла:

# cat /etc/jail.conf

# defaults
exec.clean;
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";
host.hostname = "$name";
interface = "lo1";
mount.devfs;
mount.fstab = "/etc/fstab.$name";
path = "/jails/$name";
#persist;

# jails
logger {
    interface = "lo1";
    ip4.addr = "192.168.0.20/24";
}

Создаем файл монтирования при старте джейла:

# cat /etc/fstab.logger

/jails/11.1-RELEASE-amd64 /jails/logger/import/base nullfs ro 0 0

Подготавливаем сетевой интерфейс:

# fgrep cloned /etc/rc.conf
cloned_interfaces="lo1"

# service netif cloneup

Запускаем джейл:

service jail start logger

Проверяем его статус:

jls -N

Настраиваем доступ в джейл по ssh (если это нужно, например для ansible):

# cat ~/.ssh/config

Host logger.example.com
    ProxyCommand ssh host.example.com sudo jexec logger sshd -i -o PermitRootLogin=yes
    User root