виртуализация в FreeBSD с помощью Jail

В этой статье я расскажу о том, как создавал jail в FreeBSD 5. Хотя, в настоящий момент, уже вышла 6-я версия этой операционной системы, особых изменений механизм создания jail не претерпел.
До недавнего времени для работы системы резервного копирования Bacula я пользовался выделенной машиной. В процессе обновления парка машин я заменил несколько старых одной новой, более мощной и захотел избавиться от компьютера, используемого проектом Bacula. Поскольку отдавать мощный компьютер под резервное копирование не хотелось, я решил совместить выполнение нескольких задач, при этом не пересекая их.

разделяй и властвуй

Технология jail позволяет разделить выполнение различных процессов. Например, вы можете держать Apache в jail и не бояться, что потеряете всю систему целиком в случае его компрометации. Jail может быть как полнофункциональной системой, так и набором только необходимых файлов. Я недавно приобрел машину Pentium 4 2.4GHz, это довольно мощная система, у нее много ресурсов и довольно высокое время простоя, так как я ее использую в личных целях. Вот на ней я и создам jail, в который помещу Bacula.
Находясь внутри jail, невозможно попасть на уровень выше, что очень похоже на поведение chroot, но в то же самое время создается впечатление работы с собственной полноценной операционной системой.
Запуск виртуальной системы в jail является хорошим выбором при необходимости предоставить кому-либо ресурсы системы без права хозяйничать в ней. Jail может помочь вам решить проблему безопасного доступа пользователей и повысить КПД использования ресурсов системы.

документация по Jail

Основным документом, описывающим механизм jail, является man jail. Далее я следовал инструкциям, описанным в разделе "Setting up a Jail Directory Tree". В процессе настройки вам понадобятся полные исходные тексты системы, в моем примере для сборки мира использовался каталог /usr/src/.
Был шаг, в котором я отступил от указаний man jail: я оставил Sendmail (в действительности - Postfix) запущенным, указав, какие конкретно IP- адреса прослушивать, в файле /usr/local/etc/postfix/main.cf:

inet_interfaces = $myhostname

Таким образом мы обеспечим работу в jail собственного почтового сервера.
Я поместил свою jail в каталог /home/jail/192.168.0.155.bacula. Это значение, которое я присвоил переменной D, согласно инструкции по установке:

D=/home/jail/192.168.0.155.bacula
cd /usr/src
mkdir -p $D
make world DESTDIR=$D
cd etc
make distribution DESTDIR=$D
mount_devfs devfs $D/dev
cd $D
ln -sf dev/null kernel

После того, как вы установили jail, она выглядит точно так же, как корневой каталог типичной системы FreeBSD:

[dan@dfc:/home/jail/192.168.0.155.bacula] $ ls
COPYRIGHT etc libexec root usr
bin home mnt sbin var
boot kernel proc sys
dev lib rescue tmp
[dan@dfc:/home/jail/192.168.0.155.bacula] $

терминология: Host и Jail

Host - это та машина, на которой вы первоначально устнавливаете FreeBSD, именно в этом окружении вы устанавливаете jail. И Bacula, установленная в jail, не будет иметь никакого доступа к корневой системе.
Очень важно понимать различие в окружении корневой машины и окружении jail.
В нашем примере, корневая машина имеет IP адрес 192.168.0.100, а jail имеет адрес 192.168.0.155.

модифицируем демоны

Большинство демонов будет слушать все назначенные системе IP-адреса. Например, если после установки jail вы попробуете войти на нее по ssh, то вы попадете на корневую машину. Для того, чтобы все работало как надо, необходимо:
- указать ssh корневой машины прослушивать только свой IP-адрес;
- запустить ssh в jail.
В файл конфигурации /etc/rc.conf поместите следущую строку:

syslogd_flags="-ss"

Она укажет демону syslogd корневой машины не открывать UDP-порт для приема сообщений с удаленных систем, что позволит запустить syslogd в окружении jail.
Настройка inetd корневой системы заключается в том, чтобы прописать в /etc/rc.conf строку:

inetd_flags="-wW -C 60 -a 192.168.0.100"

Обратите внимание, что первая половина взята из /etc/defaults/rc.conf:

inetd_flags="-wW -C 60" # Optional flags to inetd

Настройка sshd корневой системы потребует прописать в /etc/ssh/sshd_config такой параметр:

ListenAddress 192.168.0.100

Внеся изменения, необходимо перезапустить процесс:

kill -HUP `cat /var/run/sshd.pid`

Для проверки того, что IP-адрес jail не прослушивается в настоящий момент корневой системой, воспользуйтесь утилитой telnet:

$ telnet 192.168.0.155 22
Trying 192.168.0.155...
telnet: connect to address 192.168.0.155: Connection refused
telnet: Unable to connect to remote host

Если результат такой, как указано выше, то вы все сделали правильно.
Для запуска sshd в окружении jail необходимо отредактировать файл rc.conf обычным порядком:

sshd_enable="YES"

Я изменил конфигурацию syslogd jail таким образом, чтобы он выводил сообщения не на консоль, а в /var/log/messages, добавив следущие строки:
#*.err;kern.warning;auth.notice;mail.crit /dev/console
*.err;kern.warning;auth.notice;mail.crit /var/log/messages

конфигурирование jail

Настала пора прочитать часть руководства man, озаглавленную "Configuring the Jail". В ней рассказано, как сконфигурировать несколько параметров, необходимых для функционирования jail. Я внес изменения с корневой машины, без запуска jail. Запустить оболочку в jail можно следующей командой:

jail /data/jail/192.168.11.100 testhostname 192.168.11.100 /bin/sh

Если не появилось сообщение о ошибках, то вы попадете в оболочку jail. Вы можете запустить утилиту /usr/sbin/sysinstall для дальнейшего конфигурирования или вручную отредактировать /etc/rc.conf. Изменить можно такие параметры как:
- создать пустой файл /etc/fstab для того, чтобы избежать сообщений о ошибках при запуске;
- отключить портмаппер (rpcbind_enable="NO");
- выполнить newaliases для устранения ошибок sendmail;
- отключить конфигурирование сетевых интерфейсов для устранения предупреждений ifconfig (network_interfaces="");
- отредактировать /etc/resolv.conf;
- установить пароль пользователя root, отличный от пароля корневой системы;
- установить временную зону;
- добавить пользователей;
- установить необходимые пакеты.

автоматический запуск и останов jail

Я нашел довольно интересный инструментарий для работы с jail - sysutils/jailutils и установил его в корневую систему. Используя этот инструмент, я создал следущий сценарий:

#!/bin/sh
case "$1" in
start)
mount_devfs devfs /usr/jails/192.168.0.155/dev && \
mount -t procfs proc /usr/jails/192.168.0.155/proc && \
/usr/local/sbin/jstart /usr/jails/192.168.0.155 bacula.example.org 192.168.0.155 \
/bin/sh /etc/rc >/dev/null && echo -n ' jail bacula.example.org'
;;
stop)
/usr/local/sbin/jkill bacula.example.org >/dev/null && echo -n ' jail' && \
umount /usr/jails/192.168.0.155/proc && \
umount /usr/jails/192.168.0.155/dev
;;
*)
echo "Usage: `basename $0 {start|stop}" >&2
;;
esac
exit 0

Это довольно примитивный сценарий, например, он не проверяет, запущена ли в настоящий момент jail или нет.
Возможно вы захотите выставить эту переменную в /etc/sysctl.conf корневой машины:

security.jail.set_hostname_allowed




Dan Langille, перевод Михаила Сгибнева.


Сетевые решения. Статья была опубликована в номере 03 за 2006 год в рубрике sysadmin

©1999-2024 Сетевые решения