FreeBSD Jail

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 21:25, 19 июля 2016.

FreeBSD Jail (англ. jail — тюрьма) — механизм виртуализации в системе FreeBSD, позволяющий создавать внутри одной операционной системы FreeBSD несколько независимо работающих систем, называемых тюрьмами.

Потребность в FreeBSD Jail появилась в небольшой компании хостинг-провайдера R&D Associates для создания четкой границы между сервисными службами и приложениями своих клиентов, важными характеристиками также были безопасность и простота в управлении. Вместо добавления нового слоя конфигураций, решение Пола-Хеннинга Кампа состояло в разделении файлов и ресурсов таким образом, что пользователи получали доступ только к тем отсекам, к которым они имеют доступ.

Основные цели

FreeBSD Jail ставит перед собой задачу реализации трех парадигм:

  1. Виртуализация - каждая тюрьма представляет собой виртуальную среду со своими файлами, процессами, пользователями и администраторами. С точки зрения процесса, "тюрьма" ничем не отличается от реальной операционной системы.
  2. Безопасность - каждая тюрьма отделена от других, что обеспечивает дополнительный уровень безопасности.
  3. Удобство делегации - ограниченное количество тюрем позволяет системным администраторам делегировать несколько задач, требующих права администратора для доступа, без получения контроля над всей системой.

В отличие от обычных тюрем-каталогов, которые ограничивают процессы с точки зрения файловой системы, механизм FreeBSD Jail замыкает процесс внутри тюрьмы, не разрешая влиять на остальную систему. Этот механизм похож на принцип работы песочницы. Процессы связанны с определенными IP-адресами и не имеют доступ к переадресации и сокетам маршрутизации. Сырые сокеты также отключены по-умолчанию, но могут быть включены путем присваивания настройке security.jail.allow_raw_sockets значения sysctl.

Виртуализация

С помощью механизма тюрем можно создавать различные виртуальные машины, каждая из которых имеет свой набор установленных утилит и свою собственную конфигурацию. Это дает возможность тестировать работу новых версий программного обеспечения или их различные конфигурации.

Виртуализация особенно ценится среди поставщиков услуг, желающих предложить своим клиентам возможность иметь собственную конфигурацию систему, при этом сохраняя ее по-прежнему легкой в обслуживании.Например, два разных клиента хотят получить две различные версии одного и того же программного обеспечения. Без механизма тюрем, настройка нескольких версий ПО в разных директориях и обеспечение работы без ограничений вряд ли представляется возможным или легким для обслуживания.

Но все же FreeBSD Jail не достигает полной виртуализации; механизм не позволяет виртуальной машине работать с версией ядра отличающейся от версии базовой системы. Все виртуальные сервера имеют одни и те же ядра, следовательно, одни и те же ошибки и дыры в безопасности. Отсутствует поддержка кластеризации и миграции процессов, поэтому ошибки в машине-хосте приведут к падению всех виртуальных серверов.

Безопасность

Использование FreeBSD Jail является эффективным способом повысить уровень безопасности сервера, из-за разделения между тюрьмами и основной системой. Например, в веб-сервере без такого механизма пользователь, с помощью PHP-инъекции, может вывести из строя всю систему: злоумышленник будет иметь права пользователя, благодаря которым может изменять файлы на сервере, бродить по дереву директорий и получить огромное количество информации. Но если веб-сервер разделен на тюрьмы, то действия пользователя заперты. Даже если злоумышленник получил права администратора, то он сможет изменить только замкнутую среду, а не систему в целом.

Ограничения FreeBSD Jail:

  • Процессы одной тюрьмы не могут взаимодействовать с процессами других тюрем.
  • Модификация запущенного ядра путем прямого доступа или загрузки модулей запрещена.
  • Модификация конфигураций сети, включая интерфейсы, IP-адреса и таблицы маршрутизации запрещена. Доступ к переадресации и сокетам маршрутизации также запрещен. Доступ к сырым сокетам запрещен по-умолчанию, но может настраиваться. Тюрьма привязана к определенному IP-адресу и правила фаерволла не могут быть изменены.
  • Монтирование и размонтирование файловых систем запрещена. Тюрьмы не имеют доступ к файлам вне их директории.
  • Заключенный в тюрьме процесс не может создавать узлы устройств.

Постройка тюрьмы

Перед тем как поместить сервис в тюрьму, нужно внутрь выбранного каталога поместить минимальную копию корневой системы - чтобы сервис смогу найти требующиеся каталоги, библиотеки и исполняемые файлы. Сделать это можно путем простого копирования существующей системы, но таким образом возникает большая вероятность ошибок и угрозы безопасности. Поэтому лучше собрать окружение из исходных текстов и установить в выбранный каталог.

Создание окружения

В каталоге /usr/src и нужно выполнить следующую последовательность команд:

# JAIL=/usr/jail/base
# mkdir -p $JAIL
# make world DESTDIR=$JAIL
# make distribution DESTDIR=$JAIL
# mount -t devfs devfs $JAIL/dev

После их исполнения каталог /usr/jail/base будет содержать чистое базовое окружение FreeBSD, включая виртуальную файловую систему /dev.

Настройка корневой системы

Нужно привязать тюрьму к IP-интерфейсу, для получения трафика, и сделать так, чтобы сервисы корневой системы слушали порты только на своем IP и пропускали трафик, предназначенный заключенному сервису.

IP-псевдонимы для сетевых интерфейсов назначаются с помощью команды:

# ifconfig ed0 inet alias 192.168.0.1/16

Чтобы команда исполнялась во время загрузки, добавляем ее в /etc/rc.conf:

# echo "ifconfig_ed0_alias0=\"inet 192.168.0.1\"" >> /etc/rc.conf

Теперь о настройке сервисов корневой системы. Если тюрьма привязана ко второму внешнему IP-адресу, как иллюзия второго сервера в сети, нужно настроить все сервисы корневой системы на прослушивание только первого IP-адреса. Иначе могут случиться конфликты между приложениями, слушающими один порт (например, ssh внутри тюрьмы и в корневой системе). В большинстве случаев сделать это можно через редактирование конфигурационного файла или путем указания специальных флагов:

# echo "inetd_flags=\"-wW -a <IP-адрес корневой машины>\"" >> /etc/rc.conf

К несчастью, некоторые сервисы (rpcbind, nfsd, mountd) не позволяют указать прослушиваемый ими IP-адрес, поэтому лучше не запускать их в базовой системе и в тюрьме одновременно. С локальным IP-адресом этого делать не придется, так как заключенные сервисы извне доступны не будут, но нужно будет позаботиться о настройке брандмауэра (пример для ssh):

# ipfw add fwd 192.168.0.1,22 tcp from any to внешний-ip 22

Настройка окружения

Работающее окружение представляет собой почти точную копию настоящей FreeBSD и даже загружается через запуск стартового скрипта /etc/rc. В то же время внутри тюрьмы действуют свои ограничения и особые правила, которые необходимо учитывать. Поэтому после входа в тюрьму:

# jail /usr/jail/base base.jail 192.168.0.1 /bin/sh

Нужно выполнить следующую последовательность действий:

  1. Создать пустой файл fstab (touch /etc/fstab), чтобы скрипты инициализации не сообщали о его отсутствии.
  2. Установить пароль для суперпользователя (passwd root) и создать, если необходимо, дополнительных пользователей.
  3. Перестроить базу почтовых псевдонимов (newaliases), если необходимо использовать sendmail.
  4. Настроить временную зону (tzsetup).
  5. Отредактировать /etc/resolv.conf таким образом, чтобы сервисы, запущенные внутри тюрьмы, могли выполнять DNS-резолвинг. Можно указать адрес хост-системы, если в ней запущен кэширующий DNS-сервер.
  6. Добавляем в /etc/rc.conf следующие строки:
# vi /etc/rc.conf 

// Сетевое имя тюрьмы
hostname="base.jail"

// Отключение настройку сетевых интерфейсов (они виртуальные)
network_interfaces=""

// Включение/отключение необходимых сервисов
sendmail_enable="NO"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"
sshd_enable="YES"

Для выхода из окружения, нужно ввести exit или нажать <Ctrl+D>.

В случае использования локального IP-адреса для тюрьмы, его сетевое имя может быть любым. Но если тюрьма привязан к внешнему IP, потребуется, выбрать настоящее доменное имя, прописанное в DNS-зонах.

Пример иллюстрирует запуск ssh-сервера внутри тюрьмы. Если нужного сервиса нет в базовом дистрибутиве, лучше всего указать путь установки через переменную PREFIX во время установки порта:

# make PREFIX=/usr/jail/base make install clean<br>

Для пакетов:

# pkg_add -P /usr/jail/base пакет-1.0.0.tbz<br>

Для пользователей portinstall:

# PREFIX=/usr/jail/base portinstall -P пакет

К сожалению, в некоторых случаях прямое указание пути установки не подходит. Тогда можно применить виртуальные файловые системы вроде unionfs и nullfs для монтирования каталога /usr/ports ко всем тюрьмам:

# mount_unionfs /usr/ports /usr/jail/base/usr/ports<br>

или

# mount_nullfs /usr/ports /usr/jail/base/usr/ports

Запуск окружения

Все подготовительные работы выполнены, осталось только запустить готовый виртуальный сервер. Для этого необходимо добавить в /etc/rc.conf следующие строки:

# cat /etc/rc.conf
jail_enable="YES"
// Список окружений
jail_list="base"

// Стандартные опции тюрьмы
jail_base_rootdir="/usr/jail/base"
jail_base_hostname="base.jail"
jail_base_ip="192.168.0.1"
jail_base_interface="de0"

// Команды запуска и остановки
jail_base_exec_start="/bin/sh /etc/rc"
jail_base_exec_stop="/bin/sh /etc/rc.shutdown"

// Монтирование файловых систем
jail_base_devfs_enable="YES"
jail_base_fdescfs_enable="NO"
jail_base_procfs_enable="NO"

Запуск:

/etc/rc.d/jail start base

Список запущенных тюрем-окружений всегда доступен по команде /usr/sbin/jls. Процессы, заключенные в тюрьму, отображаются в выводах ps и top. Их отличительная черта — флаг ‘J’.

Настраиваемые константы

При использовании FreeBSD Jail процессы замыкаются внутри тюрьмы и никак не могут контактировать с процессами из других клеток. В следствие, на процессы накладываются значительные ограничения, но на уровне sysctl системы настраиваются некоторые привилегии заключенных процессов:

Константа sysctl Функциональность
security.jail.chflags_allowed Возможность менять системные флаги файлов
security.jail.allow_raw_sockets Возможность создавать низкоуровневые сокеты
security.jail.sysvipc_allowed Возможность использовать System V IPC
security.jail.set_hostname_allowed Возможность задавать собственные hostname внутри замкнутых процессов
security.jail.enforce_statfs Возможность видеть все монтированные файловые системы внутри замкнутых процессов
security.jail.socket_unixiproute_only Ограничение по возможности создания UNIX/IPv4/route сокетов
security.jail.list Список запущенных замкнутых процессов