Работа с контейнерами во FreeBSD (Jails)

С момента выхода предыдущей статьи о системе контейнеров во FreeBSD прошло более 10 лет и с тех пор она была существенно доработана и усовершенствована. Так появились возможности настройки клеток посредством отдельных конфигурационных файлов, обработки событий создания и уничтожения клеток, существенно увеличено количество настраиваемых параметров. Одним из самых заметных изменений в системе клеток является реализация виртуализации сетевого стека (VNET/VIMAGE), позволившая создавать клетку с изолированным от основной системы сетевым стеком, в котором может работать даже брандмауэр. После этого в версии фряхи 13.3 в клетке с изолированным сетевым стеком стало возможным запускать сервер NFS.

В одной из небольших сетей мне понадобилось настроить файлопомойку с применением программного обеспечения Samba. В случае запуска Samba в клетке без включенной виртуализации сетевого стека в логи полезут ошибки о невозможности рассылки широковещательных пакетов через интерфейс, а также в локальной сети сервер не будет обнаруживаться клиентами автоматически. Конечно если данный функционал не требуется, тогда можно добавить в конфиг nmbd bind explicit broadcast = no, чтобы отключить рассылку широковещательных пакетов, и заходить на сервер по IP адресу.

Все действия я буду производить на FreeBSD версии 13.2. Для начала нам необходимо подготовить окружение, для этого скачиваем дистрибутив фряхи и распаковываем его в место будущего расположения клетки.

# mkdir -p /home/jails/samba
# cd /home/jails
# fetch https://download.freebsd.org/ftp/releases/amd64/13.2-RELEASE/base.txz
# tar -xvf /home/jails/base.txz -C /home/jails/samba

P.S. Отмечу, что у меня директория /home является символической ссылкой на /usr/home.

Далее необходимо произвести первичную настройку нового окружения. Проще всего сделать chroot в директории с новым окружением и запустить необходимые команды.

# chroot /home/jails/samba
# tzsetup
# cd /etc/mail && make aliases
# touch /etc/fstab
# echo 'nameserver your.ip' > /etc/resolv.conf

Помимо этого в новом окружении в файле /etc/rc.conf можно задать сетевые параметры и настроить запуск приложений, например так:

hostname="samba.local"
rpcbind_enable="NO"     # отключаем сервис rpcbind
syslogd_flags="-ss"     # с данным флагом демон syslogd не будет создавать сетевой сокет
inetd_enable="YES"      # для запуска демона sshd, ftpd и иных сервисов
inetd_flags="-wW -C 60 -a ip.address"

После настройки окружения клетки переходим к правке файлов в основной системе. В моей конфигурации клетке нужно работать в сети с заданным VLAN равным 7, поэтому я в основной системе в /etc/rc.conf через директиву vlans_ifname  задаю номер VLAN для интерфейса, таким образом у меня создается новый интерфейс с именем re0.7. Если интерфейс VLAN не используется, тогда чтобы выделить виртуальный интерфейс для клетки, возможно создать epair, привязанный одним "концом" через bridge к какому-нибудь интерфейсу в основной системе. Настройки клетки осуществляются посредством редактирования файла /etc/jail.conf

# В общем блоке задаем глобальные параметры
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";
exec.consolelog = "/var/log/jail/console_${name}.log";
exec.clean;
mount.devfs;

# Базовый путь для клеток
path = "/home/jails/$name";

samba {
	# Я привязываю клеткам индивидуальный идентификатор (мне так удобно)
	jid = 1; 
	host.hostname = "samba.local";
	# Файл с точками монтирования, которые будут подключены при создании клетки
	mount.fstab = "/etc/fstab.samba";

	allow.raw_sockets;
	allow.quotas;
	# Права на монтирование fdescfs в клетке необходимы для Samba версии новее 4.15
	enforce_statfs = "1";
	allow.mount;
	allow.mount.fdescfs;

	# Параметры VLAN интерфейса
	$vlan_if = "re0.7";
	$vlan_ip = "192.168.1.240/24";
	$gateway = "192.168.1.250";

	# Настройки VNET. Первой директивой включаем виртуализацию,
	# второй - указываем виртуальный либо физический интерфейс, 
	# который будет доступен в клетке для работы
	vnet;
	vnet.interface = "${vlan_if}";

	# Эти же параметры можно задать в rc.conf клетки
	exec.start    += "ifconfig ${vlan_if} inet ${vlan_ip} up";
	exec.start    += "route add default ${gateway}";
	exec.release  += "ifconfig ${vlan_if} down";
	exec.release  += "ifconfig ${vlan_if} inet ${vlan_ip} -alias";
}

Для настройки клетки можно задать следующие параметры (список не исчерпывающий и необходимо учитывать, что в старых версиях FreeBSD некоторые из них могут быть не доступны):

  • ip4 - может принимать значения:
    • inherit - использовать IP адрес основной системы;
    • new - привязать к клетке новый IP адрес с маской подсети, заданные в ip4.addr;
    • disable - не использовать сетевой протокол IPv4.
  • ip4.addr - IP адрес с маской подсети в формате IP/NETMASK.
  • ip6 и ip6.addr - смысл такой же как и у директив ip4, ip4.addr, только для протокола IPv6.
  • vnet - создать клетку с собственным виртуальным сетевым стеком (собственные сетевые интерфейсы, адреса, таблица маршрутизации и т.д.). При этом ядро должно быть скомпилировано с параметром VIMAGE. Возможные значения inherit, тогда будет использован сетевой стек основной системы, а также new, тогда будет создан новый сетевой стек.
  • vnet.interface - интерфейс, который будет доступен в клетке с включенной виртуальным стеком.
  • devfs_ruleset - номер правила devfs, применяемое при монтировании данной ФС в клетке. Нулевое значение (по умолчанию) означает отсутствие набора правил. Правила devfs наследуются в дочерних клетках. Монтирование devfs внутри клетки возможно при наличии разрешения allow.mount, allow.mount.devfs и установки enforce_statfs в значение меньше 2. При этом правила devfs нельзя просмотреть или изменить из клетки.
  • mount - подключаемые файловые системы в клетку при ее создании (формат как в fstab).
  • mount.fstab - путь к файлу с точками монтирования, которые будут подключены при создании клетки.
  • mount.fdescfs - в созданной клетке будет подключена fdescfs.
  • mount.procfs - в созданной клетке будет подключена procfs.
  • persist - при установке этого параметра возможно создать клетку без работающих процессов.
  • allow.set_hostname - разрешить изменение имени хоста в клетке.
  • allow.raw_sockets - разрешить в клетке поточные сокеты (используются в утилитах ping, traceroute и т.п.).
  • allow.chflags - без этого параметра все пользователи, в т.ч. привилегированные, не смогут менять флаги chflags.
  • allow.mount.devfs -  привилегированные пользователи внутри клетки смогут подключать и отключать файловую систему devfs. Данная опция работает только при установленной директиве allow.mount и установленном параметре enforce_statfs меньше 2. Желательно задавать ограничение через devfs_ruleset.
  • allow.mount.fdescfs, allow.mount.fusefs, allow.mount.nullfs, allow.mount.procfs, allow.mount.linprocfs, allow.mount.linsysfs, allow.mount.tmpfs, allow.mount.zfs - привилегированные пользователи внутри клетки смогут подключать и отключать указанные файловые системы fdescfs, fusefs, nullfs, procfs, linprocfs, linsysfs, tmpfs, zfs. Данные опции работают только при установленной директиве allow.mount и установленном параметре enforce_statfs меньше 2.
  • allow.quotas - разрешить управлять квотами в клетке.
  • allow.read_msgbuf - разрешить доступ к сообщениям ядра в клетке.
  • allow.reserved_ports - разрешить в клетке открыть слушающие сокеты на портах ниже 1024.
  • sysvmsg - разрешить в клетке работать с сообщениями System V IPC.
  • sysvsem, sysvshm - разрешить в клетке работать с механизмами межпроцессного взаимодействия System V IPC (семафоры и разделяемая память).
  • depend - список клеток от которых зависит клетка, то есть которые будут запущены первыми.
  • allow.vmm - клетка может получить доступ к vmm. Данный  флаг доступен когда модуль ядра vmm загружен.
  • exec.fib - запускать команды с указанным номером таблицы маршрутизации FIB.
  • exec.prepare, exec.prestart и т.п. - набор директив, которые позволяют выполнять команды оболочки на различных стадиях создания, запуска, работы и уничтожения клетки.

Предварительная настройка клетки закончена и чтобы клетка автоматом запускалась при старте системы нужно добавить несколько строк в /etc/rc.conf:

jail_enable="YES"
jail_parallel_start="YES"
jail_list="samba"
  • jail_enable - разрешить запуск клеток;
  • jail_list - список запускаемых при старте системы клеток, разделенных пробелами;
  • jail_parallel_start - запускать клетки в фоне.

Теперь можно запускать клетку. Вот как можно запустить/остановить отдельную клетку:

# service jail start samba
# service jail stop samba

А так можно запустить/остановить все клетки:

# service jail start
# service jail stop

Просмотреть список запущенных клеток можно командой jls:

# jls
  JID  IP Address      Hostname                      Path
    1                  samba.local                   /usr/home/jails/samba

У клеток, в которых создан виртуальный сетевой стек, в выводе команды jls IP адрес обычно не отображается. Запустить оболочку в запущенной клетке можно так:

# jexec -u root samba csh

После этого можно установить необходимые пакеты в систему, в моем случае Samba. Настройку Samba я здесь описывать не буду, т.к. это тема для отдельной статьи. Кроме того, на сайте есть несколько материалов по данной тематике, которые можно найти, воспользовавшись поиском. Со временем разработчики FreeBSD выпускают обновления и заплатки безопасности, которые я устанавливаю командой freebsd-update (папку с окружением клетки можно задать через ключ -b).

Отмечу, что в настоящее время создано множество утилит, которые упрощают управление клетками (создание, обновление, удаление, резервное копирование и т.п.), в частности к таким можно отнести bastille, cbsd, appjail и другие. Рекомендую почитать раздел про клетки в хэндбуке, в котором неплохо раскрыт вопрос управления клетками, в частности использования файловых систем nullfs и zfs для создания одного бинарного окружения, используемого несколькими клетками.

Добавить комментарий

CAPTCHA
Этот вопрос задается для того, чтобы выяснить, являетесь ли Вы человеком или представляете из себя автоматическую спам-рассылку.
Яндекс.Метрика