Клетки


Один из самых старых механизмов защиты UNIX построен на идее измененного корневого каталога (changed root), или chroot, согласно которой пользователь или программа ограничивается подразделом файловой системы, что защищает других пользователей и остальную часть файловой системы, chroot подходит для таких служб, как named(8), но ограничивает работу сложных программных комплексов, которым необходим доступ ко всей системе. Использование механизма chroot для организации веб-сервера или почтовой службы потребует приложить немалые усилия, направленные на добавление большого числа программ в chroot-окружение. Если вы работаете в компании, предоставляющей услуги веб-хостинга, вашим клиентам точно не понравится оказаться в chroot!

Клиенты, которые понимают мощь UNIX, нередко предъявляют запросы, усложняющие жизнь администратора. Например, хотят установить то или иное программное обеспечение или переконфигурировать веб-сервер, чтобы включить последний крутой модуль Apache. В двух словах, они хотят получить доступ с правами root, а в большинстве систем UNIX нельзя раздавать доступ root клиентам на сервере с множеством пользователей.

Нельзя, если у вас не FreeBSD. Администраторы FreeBSD столкнулись с этой проблемой довольно давно и решили ее, значительно улучшив механизм chroot. По сути, они решили ее так хорошо, что в системе FreeBSD можно создавать на диске целые виртуальные машины и изолировать их от остальной части системы. Такая виртуальная машина называется клеткой (jail).

Клетку можно представить как среду клиент-сервер. Основной сервер — это хост, а каждая система-клетка — это клиент. Изменения, проводимые в хосте, можно отразить на всех системах, но изменения в клетке не затронут основную систему (если только не позволить клетке заполнить весь диск или что-либо подобное).

С точки зрения пользователя клетка очень похожа на полноценную систему FreeBSD, в которой отсутствует всего несколько устройств. Находясь в клетке, клиенты могут иметь доступ root и даже устанавливать любые программы по своему желанию. Это не окажет влияния на основную систему. Все процессы, запускаемые в клетке, ограничены ее средой. Ядро не предоставляет им доступ к информации, лежащей за пределами клетки. Поскольку программы и процессы в клетке ничего не знают о «внешнем мире» и не могут читать или получить к чему-либо доступ за его пределами, пользователь заблокирован. Мало того, что клиент не может вырваться из клетки, — если в клетку проник злоумышленник, дальше нее он не пройдет. Такой механизм позволяет обезопасить систему и удовлетворить потребности клиентов.

На современном оборудовании, с недорогими (но не дешевыми!) дисками и избытком памяти, система FreeBSD может обслуживать десятки клеток с веб-серверами. С точки зрения продвижения машина-клетка представляет собой хороший промежуточный вариант между виртуальным доменом на общем сервере и собственным локальным сервером.

Конфигурирование сервера для использования клеток

Перед использованием клеток необходимо убедиться, что сервер настроен правильно. Клетки налагают специальные требования на сервер. Самое досадное из них — демоны нельзя привязать ко всем доступным IP-адресам.

Каждая клетка привязана к определенному IP-адресу и определяется этим IP-адресом. Для каждой клетки необходимо к сетевой карте добавить псевдоним IP-адреса, как обсуждалось в главе 6.

Клетка должна иметь исключительный доступ к этому адресу; никто иной не может его использовать. Этот IP-адрес является единственным, который сможет использовать клетка.* Если в основном сервере есть демон, привязанный ко всем доступным IP-адресам системы, то этот демон воспрепятствует запуску клетки. Взглянув на вывод команды sockstat(1), можно заметить несколько записей, в которых локальный адрес включает в себя символ звездочки «*». Это означает, что демон «прослушивает» все доступные IP-адреса.

В этом примере видно, что демон inetd прослушивает все IP-адреса на порту с номером 21 (1) демон sshd — все IP-адреса на порту с номером 22 (2) и демон syslogd — все IP-адреса на порту с номером 514 (3). Нам необходимо заново сконфигурировать эти демоны, чтобы каждый из них прослушивал только один IP-адрес.

Для правильной настройки сервера клеток следует понять, что основной сервер — это лишь хост для клеток и не предоставляет никаких других услуг. Вам необходимы службы sendmail, named и другие? Нет проблем! Создайте клетку для этих служб и заключите в нее все необходимые демоны. Это не только упростит настройку всех этих программ, но и обеспечит дополнительную защиту для остальных клеток. В случае вторжения в хост-систему злоумышленник автоматически получает доступ ко всем клеткам, а вторжение в единственную клетку сильно ограничит его возможности границами единственной клетки.

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

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

syslogd

syslogd — это системный регистратор (system logger), который открывает сокет, а значит, может посылать регистрируемые сообщения другим серверам, даже если они не принимают никаких сообщений. Чтобы подключить syslogd(8) к конкретному IP-адресу, следует использовать ключ -b, в файле rc.conf:

syslogd_flags="-b 192.168.1.1"

Чтобы заставить замолчать syslogd, следует использовать ключ -ss. Однако в этом случае невозможным будет удаленное ведение протоколов. Программа syslogd(8) подробно рассмотрена в главе 19.

inetd

Вообще говоря, этот демон лучше запускать именно в клетке. Демон inetd(8) тоже может быть настроен на использование единственного IP-адреса с помощью ключа -a, например:

inetd_flags="-wW -С 60 -а 192.168.1.1"

Обратите внимание: inetd обычно запускается с ключами по умолчанию, которые определены в файле /etc/defaults/rc.conf. В моей версии FreeBSD inetd по умолчанию запускается с ключами -wW -С 60. Поэтому, помимо ограничения привязкой к единственному IP-адресу, я добавил еще и эти ключи.

sshd

Параметр настройки ListenAddress в файле /etc/sshd/sshd_config указывает IP-адрес, который может использоваться демоном sshd для приема запросов на соединение.

ListenAddress 192.168.1.1

Будет очень разумно обеспечить работу службы SSH на сервере клеток. Если sshd(8) — это единственная служба, предоставляемая сервером, значит вы все сделали правильно.

NFS

Программы NFS, такие как rpcbind(8) и nfsd(8), прослушивают все IP-адреса системы, и повлиять на такое их поведение очень сложно. Не запускайте сервер NFS на сервере клеток. Тем не менее NFS можно использовать внутри клетки. Если вам все-таки необходимо иметь сервер NFS, не используйте основной сервер, а настройте работу NFS внутри клетки.

Клетки и ядро

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

Система клеток имеет свое дерево параметров sysctl, security.jail. Эти параметры можно изменять только из основной системы, поскольку из клеток они недоступны, а изменения затрагивают все клетки, запущенные на сервере.

security.jail.set_hostname_allowed

По умолчанию в клетке пользователь root может устанавливать имя хоста для этой клетки. Поскольку клетка использует это имя для взаимодействия с «основным» хостом, изменение имени хоста может легко запутать администратора, ответственного за управление клетками. Если установить этот sysctl в значение 0, изменение имени хоста будет запрещено.

security.jail.socket_unixiproute_only

По умолчанию с клеткой можно взаимодействовать только через протокол IP и локальные сокеты UNIX. Хотя маловероятно, что пользователь будет применять, скажем, протокол IPX, теоретически это вполне возможно. Однако система клеток поддерживает только IP. Позволить пользователям применять другие протоколы — значит, позволить им «выбираться» из клетки. Система клеток виртуализирует только IP, но не IPX или другие сетевые протоколы, поэтому все остальные протоколы, за исключением IP, можно использовать для доступа ко всем клеткам. Такой доступ, в общем, безопасен, однако неразумно считать себя умнее любого злоумышленника. Значение 1, используемое по умолчанию, ограничивает доступ к системе только протоколом IP; значение 0 позволит использовать любой сетевой протокол, отличный от IP.

security.jail.sysvipc_allowed

System V IPC — это стандарт UNIX для разрешения межпроцессного взаимодействия (Interprocess Communication, IPC) через сегменты разделяемой памяти. По существу, связанные друг с другом программы могут использовать один участок памяти для хранения информации. Многие приложения баз данных используют IPC. Система клеток не создает отдельные области памяти для каждой клетки. Разрешение IPC позволило бы информации просачиваться из клетки и обратно. Впрочем, воспользоваться таким слабым местом способен лишь квалифицированный взломщик. Значение 0, принятое по умолчанию, запрещает использование механизмов IPC, значение 1 — разрешает.

security.jail.enforce_statfs

Данный параметр управляет возможностью пользователя, находящегося в клетке, видеть информацию о файловой системе. По умолчанию (security.jail.enfоrce_statfs=2) программы в клетках могут видеть только точки монтирования, находящиеся непосредственно в клетке, а путь к корневому каталогу усечен так, что из клетки нельзя определить, где на диске находится каталог, заключенный в клетку. Если значение этого параметра установить равным 1, пользователь по- прежнему сможет видеть только точки монтирования, находящиеся непосредственно в клетке, но при этом он сможет узнать полный путь к своему каталогу в хост-системе. Если значение этого параметра установить равным 0, пользователь сможет видеть все точки монтирования. Причины, которые могли бы служить веским основанием для изменения значения по умолчанию, встречаются крайне редко.

security.jail.allow_raw_sockets

Низкоуровневые сокеты обеспечивают прямой доступ к сетевой подсистеме. Если пользователи и программы, заключенные в клетки, не вызывают доверия, не разрешайте им доступ к низкоуровневым сокетам. Низкоуровневые сокеты TCP/IP используются такими программами, как ping и traceroute, поэтому некоторые клиенты могут изъявить желание иметь такую возможность. Однако, с точки зрения безопасности, слишком мало причин за то, чтобы разрешать эту возможность, и слишком много причин против. Значение 0, используемое по умолчанию, запрещает доступ к низкоуровневым сокетам, 1 — разрешает.

security.jail.chflags_allowed

По умолчанию пользователи, заключенные в клетки, не могут использовать флаги файловой системы и утилиту chflags(1) (глава 7). Напомню, что многие из этих флагов невозможно сбросить без перезагрузки в однопользовательском режиме. При неумелом обращении с chflags(1) ваши клиенты могут навлечь на себя неприятности, и только вы сможете ликвидировать их. Это верное средство для службы поддержки заработать себе головную боль. Чтобы разрешить использование утилиты chflags(1), измените значение по умолчанию 0 на 1.

security.jail.jailed

Это значение, доступное только для чтения, покажет, запускается ли sysctl(8) из хост-системы (0) или из клетки (1).

security.jail.list

В хост-системе этот параметр содержит список всех активных клеток.

Установка клиента

Для начала необходимо решить, где будут размещаться клетки. Я рекомендую использовать для этих целей отдельный раздел, чтобы расходование дискового пространства вашими клиентами никак не сказывалось на хост-системе. Некоторые администраторы пристально следят за своими клиентами и поднимают плату для пожирателей дискового пространства. Файловые диски (глава 8) — это самый простой способ создания отдельных разделов для клеток, который не требует создания дополнительных физических разделов на диске. В данном примере мы установим первую клетку в каталог /var/jail/jail1.

Процесс установки клетки по своей сути напоминает процесс обновления FreeBSD: сборка исполняемых файлов из исходных текстов и их установка. Только в случае с клеткой установка производится в другое местоположение. Если вы производили обновление системы, значит вы уже выполняли сборку программ, если нет — перейдите в каталог /usr/src и запустите команду:

# make buildworld

После того как система будет собрана, ее нужно просто установить. Для выбора иного каталога установки следует использовать параметр командной строки DESTDIR. Однако, чтобы установить каталоги /etc и /var, нам придется выполнить дополнительные действия. (Они не требуются при обновлении системы, так как в хост-системе эти каталоги уже присутствуют.)

# make installworld DESTDIR=/vaг/jail/jail1
# make distribution DESTDIR=/var/jail/jail1
# mount -t devfs devfs /var/jail/jail1/dev

Последняя команда производит установку файлов устройств в клетку. Хотя это и не является необходимым, тем не менее многие программы предполагают наличие доступа к таким основным устройствам, как терминалы, генераторы случайных чисел и т. п. Файловая система devfs в клетке вам потребуется как минимум на этапе установки.

Уменьшение дискового пространства, занимаемого клеткой

В Интернете можно найти множество рекомендаций по уменьшению дискового пространства, требуемого клетке. Объединение точек монтирования и NFS поможет снизить требования, предъявляемые к объему дискового пространства, однако чем больше уловок вы будете использовать, тем меньше поддержки от сообщества FreeBSD вы получите.

Комментарии запрещены.