СЕРГЕЙ СУПРУНОВ
FreeBSD jail: зона строгого режима
Безопасность FreeBSD всегда была на должном уровне. Но когда в Интернет нужно «выставить» один или несколько сервисов, надеяться приходится уже не только на разработчиков системы.
Обычно, когда речь заходит о безопасности, наверняка упоминается совет поместить потенциально опасные процессы в chroot-окружение. Но вызов chroot никогда не разрабатывался с оглядкой на безопасность – его создавали как средство для компиляции системы в альтернативном каталоге. В дальнейшем приспособили для нужд ftp, ограничивая с его помощью доступ к файловой системе отдельных пользователей. А потом понеслось... Безусловно, chroot не позволяет (теоретически; исключения были описаны в статье Василия Озерова «Как увеличить безопасность процессов с помощью chroot и jail», №7 за 2006 г.) процессу покинуть свой новый корневой каталог, но всё же он не обеспечивает полную изоляцию процессов. Запущенные в chroot программы сохраняют возможность использовать почти любые системные вызовы, что позволяет им наблюдать за системой (например, с помощью ps) и даже влиять на её работу (монтировать файловые системы, модифицировать ядро и т. д., вплоть до остановки системы). Конечно, всё это возможно только в случае, если в chroot-каталоге будут доступны нужные средства, хотя при наличии shell-доступа «протащить» их туда не составит особого труда. Поэтому для повышения безопасности во FreeBSD появилось специальное средство – jail (англ. «тюрьма»).
Но так уж «исторически сложилось», что для повышения безопасности всё же чаще используется chroot-окружение, а jail упоминается по большей части как средство виртуализации. Скорее всего, причина здесь в большей распространённости и универсальности вызова chroot, который реализован практически во всех UNIX-подобных системах. К тому же появился он намного раньше. Возможно, свою роль играет и несколько большая сложность организации jail-среды по сравнению с chroot, так что помимо всего прочего, постараемся в деталях разобраться и во всех тонкостях практического применения jail.
Для начала рассмотрим некоторые теоретические вопросы.
Понятия
Вызов jail значительно расширяет функции chroot, ограничивая, помимо доступа к файловой системе вне «корня», любые средства, которые могут позволить использовать какие-либо ресурсы за пределами jail. Так, в jail запрещаются: любая модификация текущего ядра (включая загрузку-выгрузку модулей и изменение параметров с помощью sysctl), монтирование-демонтирование файловых систем, изменения сетевых настроек, доступ к «сырым» сокетам, взаимодействие с процессами, запущенными вне «тюрьмы», любые действия, влияющие на работу всей системы (например, перезагрузка). Благодаря этим ограничениям, даже процесс, запущенный в jail с правами суперпользователя, будет существенно ограничен в возможности нарушить работу операционной системы в целом.
Это приводит к тому, что ряд утилит могут не работать в jail. Например, вы не сможете из jail проверить работу сети с помощью ping, поскольку эта команда использует «сырые» сокеты, которые в jail запрещены.
«Тюрьма» получает от основной системы имя хоста и IP-адрес. Одним из существенных ограничений jail-среды, которое необходимо учитывать, является то, что с ней может быть сопоставлен лишь один сетевой адрес. Как правило, в основной системе он организован в виде псевдонима к одному из существующих физических интерфейсов или к loopback-интерфейсу. То есть процессы в jail могут работать только с этим адресом, не имея доступа даже к вездесущему интерфейсу «обратной петли» – 127.0.0.1.
Смысл этого ограничения заключается в том, чтобы максимально упростить задачи контроля над сетевой активностью «заключённых» процессов и не позволить им каким-либо образом повлиять на работу сетевых приложений основной системы или других «тюрем». Один адрес, принадлежащий только jail-среде, гораздо проще контролировать с помощью межсетевого экрана.
Инструментарий
«Тюрьма» создаётся с помощью одноимённой утилиты – jail (см. man 8 jail). В качестве обязательных аргументов ей передаются путь к корневому для «тюрьмы» каталогу, имя хоста и сетевой адрес, а также команда, которая запустит в jail-окружении первый процесс, который будет родительским для всех остальных. Опционально может быть указан пользователь, с правами которого этот процесс следует запустить.
При инициализации в jail может быть запущен только один процесс. В дальнейшем он может порождать другие, которые будут дочерними по отношению к нему и унаследуют все ограничения. Нужно иметь в виду, что в jail никакие сценарии инициализации или что-то подобное не запустятся без вашего прямого на то указания. Jail – это, по сути, «усиленный» в плане безопасности chroot, а не полноценная виртуальная машина. Для создания виртуальной системы в jail следует в качестве имени команды, запускаемой в «тюрьме», указывать сценарий /etc/rc (пример будет показан ниже).
Для работы с jail будут полезны также утилиты jls (возвращает список запущенных в данный момент «тюрем» с их идентификаторами) и jexec (предоставляет возможность выполнить какую-либо команду внутри jail из основной системы). Подробности смотрите на соответствующих man-страницах.
Недостатки и проблемы
Одним из недостатков jail, впрочем, как и chroot, является дублирование необходимых файлов – любые файлы, которые могут понадобиться работающим в jail процессам, должны быть скопированы в корневой для jail каталог. Одним из приёмов, несколько смягчающим эту проблему, является вынос файлов, модификация которых из jail не предусмотрена, на отдельную файловую систему с последующим монтированием её в режиме «только для чтения». Пример создания такой jail-среды будет рассмотрен позже.
Безусловно, ряд проблем безопасности остаётся и в случае использования jail. Например, злоумышленник может использовать захваченную «тюрьму» для рассылки спама, организации ftp-файлообменников, настройки анонимных прокси-серверов и т. д. Большинство этих проблем связаны с сетевой активностью. Единственный адрес позволяет легко управлять сетевой работой «тюрьмы» из основной системы (в частности, запрещать взаимодействие со всеми портами, работа по которым для jail-системы не предусматривается). Тем не менее, нужно иметь в виду, что запуск процесса в среде jail сам по себе не является панацеей от любых внешних угроз.
Разборки
Перейдём к практическим вопросам. Подробно разберём три примера: реализация полноценной виртуальной системы, создание изолированной «внешней» среды и запуск в jail одной сетевой службы.
Пример 1. Виртуальная система
Для начала рассмотрим простейший с точки зрения реализации пример – виртуальную машину для тестирования или для предоставления пользователям полнофункционального хостинга с правами root (см. рис. 1). То есть нам нужно, фактически, создать систему в системе.
Рисунок 1. Изолированная виртуальная система
Порядок действий можно почерпнуть в man jail – создаём каталог для будущей jail-системы, собираем в него «мир» и «дистрибутив», монтируем devfs:
# mkdir -p /var/jails/system
# cd /usr/src
# make world DESTDIR=/var/jails/system
# make distribution DESTDIR=/var/jails/system
# mount_devfs devfs /var/jails/system/dev
На не слишком шустрой машине сборку мира лучше запускать на ночь – эта процедура может затянуться часов на шесть-восемь. Впрочем, если вы уже пересобирали систему (например, в ходе обновления версии или «латания дыр», подобных недавним ошибкам в crypto), то вместо повторной сборки всей системы можно ограничиться инсталляцией в альтернативный каталог:
# make installworld DESTDIR=/var/jails/system
Для запуска jail, помимо подготовленного каталога, понадобятся также IP-адрес и имя хоста. IP предварительно нужно задать как псевдоним на одном из интерфейсов основной системы (подойдёт и lo0):
# ifconfig lo0 alias 10.30.0.100 netmask 255.255.255.255
Если не терпится, то уже можно заглянуть в новую систему:
# jail /var/jails/system jail.host 10.30.0.100 /bin/csh
Раз уж мы здесь, сразу сделаем несколько полезных вещей – зададим пароль пользователю root, создадим обычного пользователя для повседневной работы, настроим sshd:
jail# passwd root
jail# adduser
Username: admin
Full name: Administrator of jail
. . .пропущено. . .
jail# echo "sshd_enable=YES" >> /etc/rc.conf
|
Для корректной работы в дальнейшем следует также выставить правильный часовой пояс, впрочем это относится к стандартной процедуре настройки любой новой системы, так что здесь мы не будем останавливаться на этих вопросах.
Продолжим – у нас осталось ещё одно серьёзное дело: нужно обеспечить автоматический запуск jail при загрузке. Для этого в /etc/rc.conf основной системы добавим следующие строки:
jail_enable="YES"
jail_list="system"
jail_system_rootdir="/var/jails/system"
jail_system_hostname="jail.host"
jail_system_ip="10.30.0.100"
jail_system_interface="lo0"
jail_system_devfs_enable="YES"
jail_system_exec_start="/bin/sh /etc/rc"
jail_system_exec_stop="/bin/sh /etc/rc.shutdown"
В параметре jail_list перечисляются все jail-системы, которые должны запускаться автоматически (у нас пока такая система одна). В дальнейшем по схеме «jail_<имя из списка>_<параметр>» задаются параметры для каждой «тюрьмы» из списка. Обязательно должны быть указаны путь, имя хоста, IP-адрес и выполняемая команда. Параметр interface задавать не обязательно, но без него сценарий /etc/rc.d/jail выдаёт ошибки о неправильном синтаксисе для ifconfig, хотя на работе это никак не отражается.
Также желательно задать автомонтирование файловой системы devfs, чтобы не модифицировать /etc/fstab. Ну и последние две строки в данном случае необязательны, поскольку повторяют значения по умолчанию – это команды, которые должны быть выполнены при старте и останове jail-системы.
Теперь можно запустить jail командой /etc/rc.d/jail start (нужно предупредить, что при разрешённом sshd первый запуск займёт довольно ощутимое время – в jail будут генерироваться необходимые для работы ключи) и попробовать подключиться к ней по ssh:
$ ssh -l admin 10.30.0.100
Здесь admin – имя пользователя, которого мы создали в jail. Войдя в «тюрьму», обратите внимание на то, как ограничены ваши права – команды ps, top и т. д. будут выдавать информацию только о процессах, исполняющихся в данной «тюрьме», ifconfig разрешает только просмотр, traceroute и ping не работают вообще, ссылаясь на «socket: Operation not permitted».
Для полноценной работы в jail ещё понадобится коллекция портов, но её можно просто скопировать из основной системы. Есть и более экономичный вариант, позволяющий «разделять» один каталог между основной системой и «тюрьмами» (его мы рассмотрим в следующем примере), но здесь копия позволит пользователю, работающему в jail, делать с этим каталогом что угодно без опасений, что это отразится на основной системе.
Пример 2. Внешняя и внутренняя зоны
Понятно, что рассмотренный выше случай удобен для хостинга, позволяя пользователю самостоятельно выполнять очень многое, вплоть до установки нужных программ. Но когда речь идёт об использовании jail как средства повышения безопасности (например, для разделения системы на «внешнюю» и «внутреннюю» области), здесь есть один недостаток – дублирование всех системных файлов. Помимо нерационального расходования дискового пространства, это также усложняет и сопровождение системы – патчи в случае выявления уязвимости нужно устанавливать во всех «тюрьмах», обновлять несколько одинаковых деревьев ports и т. д.
Но есть способ свести дублирование информации к минимуму, который и рассмотрим на данном примере: пусть у нас есть один физический сервер и требуется реализовать на нём «внешнюю» систему, которая будет предоставлять услуги абонентам, такие как электронная почта, FTP-сервер и т. д. (своего рода DMZ, но в пределах одного физического сервера), и «внутреннюю», обеспечивающую некоторыми услугами пользователей локальной сети.
Поскольку локальную сеть можно считать менее опасной, чем Интернет, то для предоставления «внутренних» услуг будем использовать основную систему, в то время как все «внешние» службы перенесём в jail-окружение (см. рис. 2).
Рисунок 2. Внешние сервисы вынесены в jail
В отличие от предыдущего примера, здесь не предполагается, что какой-то пользователь внутри jail будет выполнять модификацию системы. Поэтому львиную долю всех файлов можно сделать «только для чтения». А раз так, то вместо копирования всех системных файлов в jail можно попробовать предоставить те же файлы, которые используются основной системой. Ссылки не подойдут, поскольку суперпользователь внутри «тюрьмы» сможет выставить на файлы нужные права, так что в случае компрометации jail-системы могут быть повреждены и системные файлы.
Избежать этого позволяет механизм монтирования. Если, скажем, в каталог /bin смонтировать файловую систему только для чтения, то из jail повредить её будет нельзя. Вы же помните, что в jail операции монтирования запрещены? А раз так, то и перемонтировать на чтение-запись эту файловую систему не удастся.
Итак, что мы можем смонтировать в jail с опцией ro? Во-первых, системные файлы – каталоги /bin, /sbin, /usr/bin и т. д. Во-вторых, каталог настроек – /etc. Ведь большую часть параметров можно будет установить и из основной системы, где запись можно оставить разрешённой. Единственное, каталог /etc всё же лучше создать отдельный и монтировать уже его – иначе вы не сможете гибко разделять настройки основной и jail-систем. То есть в данном случае ro-монтирование выполняется не для экономии дискового пространства, а исключительно по соображениям безопасности.
Каталог портов /usr/ports можно будет монтировать (но на чтение-запись, поскольку это нужно для работы) только на время установки нового ПО. По большому счёту, можно вообще выполнять установку из основной системы, указав нужный PREFIX. Разве что некоторые действия придётся доделывать вручную (например, регистрацию в jail-системе нужных пользователей, поскольку при такой инсталляции они будут созданы в основной).
Теперь самое интересное – для монтирования всех этих каталогов их не нужно размещать на отдельных разделах. В FreeBSD есть очень удобный механизм mount_nullfs, позволяющий монтировать обычные каталоги. Например, ручное монтирование дерева портов может выглядеть таким образом:
# mount_nullfs /usr/ports /var/jails/outers/usr/ports
Для монтирования «только на чтение», как обычно, указывается опция -o ro.
Помимо nullfs, вы можете использовать и проверенный временем способ – NFS. Сетевая файловая система прекрасно зарекомендовала себя для предоставления ФС на одной машине другим системам, доступным по сети. Но ничто не мешает использовать её внутри одной системы. Только не забывайте, что монтировать NFS-каталоги, как и любые другие, вы должны из основной системы – в jail это запрещено. Есть ещё mount_unionfs, но в FreeBSD этот механизм пока не слишком устойчив и приводит к проблемам гораздо чаще, чем того хотелось бы.
Итак, вместо сборки «мира» в каталог jail мы ограничимся сборкой «дистрибутива» (иерархию каталогов придётся создать вручную; если что забудете, make вам напомнит):
# cd /var/jails/outers
# find / -type d -maxdepth 1 | sed 's/^\///' | xargs mkdir
# find /etc -type d -maxdepth 1 | sed 's/^\///' | xargs mkdir
# find /usr -type d -maxdepth 1 | sed 's/^\///' | xargs mkdir
# find /etc/periodic -type d -maxdepth 1 | sed 's/^\///' | xargs mkdir
# find /var -type d -maxdepth 1 | sed 's/^\///' | xargs mkdir
# find /var/named -type d -maxdepth 3 | sed 's/^\///' | xargs mkdir
# cd /usr/src
# make distribution DESTDIR=/var/jails/outers
# mv /var/jails/outers/etc /var/jails/_4mount/outers/etc
# mkdir /var/jails/outers/etc
Предпоследней строкой мы перенесли «дистрибутивный» каталог настроек за пределы jail-каталога, с тем чтобы в дальнейшем смонтировать его в режиме «только для чтения» и тем самым сделать невозможной любую модификацию настроек внутри jail. Теперь обеспечиваем автоматическое монтирование нужных каталогов, для чего в /etc/fstab добавим следующие строки:
# For jail
/bin /var/jails/outers/bin nullfs ro 0 0
/sbin /var/jails/outers/sbin nullfs ro 0 0
/lib /var/jails/outers/lib nullfs ro 0 0
/libexec /var/jails/outers/libexec nullfs ro 0 0
/usr/bin /var/jails/outers/usr/bin nullfs ro 0 0
/usr/sbin /var/jails/outers/usr/sbin nullfs ro 0 0
/usr/lib /var/jails/outers/usr/lib nullfs ro 0 0
/usr/libexec /var/jails/outers/usr/libexec nullfs ro 0 0
/usr/libdata /var/jails/outers/usr/libdata nullfs ro 0 0
/usr/include /var/jails/outers/usr/include nullfs ro 0 0
/usr/share /var/jails/outers/usr/share nullfs ro 0 0
/var/jails/_4mount/outers/etc /var/jails/outers/etc nullfs ro 0 0
При первом запуске каталог etc нужно примонтировать вручную на чтение-запись, чтобы sshd смог сохранить сгенерированные ключи. Это также может понадобиться и ряду других программ, которые сохраняют свои данные непосредственно в etc – проверьте свои пакеты на этот счёт.
Осталось подмонтировать порты, как показано выше, зайти в jail и установить необходимые программы. После этого каталог ports можно размонтировать – пока не потребуется установить что-то ещё или обновить какой-то пакет, он нам не понадобится. Кстати, если быть последовательным, то можно и /usr/local, по примеру /etc, вынести в отдельный каталог, а в jail подключать через монтирование. Или даже сделать две «тюрьмы» – одну для настроек, не имеющую выхода в Интернет, но с каталогами, монтируемыми на чтение-запись; и вторую – рабочую, куда монтирование тех же каталогов выполняется только на чтение. В общем, нет предела паранойе.
Кстати, у jail есть ещё одно ограничение, полезное при работе с «общими» файлами, – процессы, запущенные внутри «тюрьмы», не могут менять флаги уровня безопасности, выставленные на файлы. Благодаря этому файлы, которые jail разделяет с основной системой или другой «тюрьмой», можно объявить неизменяемыми. Правда, основной системе тоже придётся учитывать эти ограничения.
Небольшое замечание по работе с файлом паролей. Поскольку в jail каталог etc недоступен для записи, все изменения нужно будет вносить в /var/jails/_4mount/outers/etc. Для этого удобнее всего использовать команду pw с параметром -V, указывающим на альтернативный каталог размещения файлов:
# echo "password" | pw -V /var/jails/_4mount/outers/etc useradd me -h 0 -g wheel
Так мы добавили пользователя me. Если что-то непонятно, изучайте man pw. Нужно сказать, что описанный выше приём – это лишь конкретный пример. Очевидно, что подобным образом придётся учитывать изменённый каталог и для других конфигурационных файлов, например, баз данных sendmail. Возможно, в ряде случаев будет проще временно перемонтировать /etc на чтение-запись и выполнить необходимые модификации файлов из jail (по соображениям безопасности сетевую работу из jail на это время можно полностью заблокировать).
На этом всё, пожалуй, – нам почти ничего не пришлось дублировать, обновления системы будут автоматически распространяться и на jail-систему, и при этом злоумышленник, даже если получит внутри «тюрьмы» права суперпользователя, не сможет причинить вред ни основной, ни jail-системе. Даже изменить большинство настроек (например, чтобы обеспечить себе беспрепятственный вход во взломанную систему по ssh или открыть релей в access-файле Sendmail), и то не сможет.
В отличие от предыдущего примера, когда системные файлы в jail суперпользователь мог менять как ему вздумается, здесь мы имеем возможность ограничить ресурсы, которые будут доступны процессам в jail. Это позволит избежать перегрузки системы в случае ошибок в работающих процессах (например, неаккуратно разработанный сценарий, исполняющийся в среде FastCGI, может привести к утечке памяти) либо в случае сознательных действий взломщика. Лимиты, как известно, задаются в файле /etc/login.conf (в нашем случае это будет /var/jails/_4mount/outers/etc/login.conf) с последующим подключением «класса» в учётной записи пользователя. Например, можно использовать такие ограничения:
default:\
:cputime=1h:\
:memoryuse=50M:\
... пропущено ...
:maxproc=35:\
:coredumpsize=0:
root:\
:tc=default:
Теперь, поскольку значения, определённые в default, будут распространяться на всех пользователей с пустым 5 полем в master.passwd (а мы его пустым и оставим), то все пользователи в jail, даже суперпользователь, будут ограничены в возможности потреблять ресурсы системы.
Понятно, что это лишь пример – ваши значения и перечень ограничиваемых параметров могут быть совсем другими. При желании можно задать несколько «классов» ограничений для различных пользователей. Читайте man login.conf и проявляйте осторожность, выставляя ограничение cputime для процессов, подразумевающих постоянную работу.
Пример 3. Запускаем ftp-сервер
Для таких служб, как Sendmail, проще создать в jail полноценную систему – слишком уж много у неё зависимостей и взаимосвязанных сервисов, таких как POP3-или IMAP-серверы, антивирусные и антиспамовые фильтры, и т. д. Однако в некоторых случаях это может оказаться избыточным (см. рис. 3).
Рисунок 3. Отдельный сервис в jail
Например, вы хотите протестировать FTP-сервер wu-ftpd, но не уверены в его благонадёжности. Чтобы не подвергать риску всю систему, запустим его в jail-окружении.
На этот раз нам не понадобятся ни «мир», ни «дистрибутив». Просто создаём каталог и выполняем в него инсталляцию из портов:
# mkdir -p /var/jails/wuftpd
# cd /usr/ports/ftp/wuftpd
# make PREFIX=/var/jails/wuftpd/ install
Проверяем, от каких библиотек зависит эта программа, и копируем нужные в будущий jail-каталог согласно их размещению в дереве каталогов:
# ldd /var/jails/wuftpd/libexec/ftpd
/var/jails/wu-ftpd/libexec/ftpd:
libcrypt.so.3 => /lib/libcrypt.so.3 (0x28095000)
libopie.so.4 => /usr/lib/libopie.so.4 (0x280ad000)
libmd.so.3 => /lib/libmd.so.3 (0x280b6000)
libc.so.6 => /lib/libc.so.6 (0x280c4000)
# cp /lib/libcrypt.so.3 /var/jails/wuftpd/lib/
# cp /lib/libmd.so.3 /var/jails/wuftpd/lib
# cp /lib/libc.so.6 /var/jails/wuftpd/lib
# mkdir -p /var/jails/wuftpd/usr/lib
# cp /usr/lib/libopie.so.4 /var/jails/wuftpd/usr/lib
|
Также понадобится вручную создать некоторые рабочие каталоги, например, для размещения log-файлов (если вы недостаточно хорошо знакомы с запускаемым сервисом, то, что именно создавать, можно будет узнать методом «научного тыка»: обычно при неудачной попытке запуска jail причины ошибок можно увидеть либо прямо в консоли, либо в /var/log/messages; запускаемый демон может также «ругаться» в лог-файл внутри jail):
# mkdir -p /var/jails/wuftpd/var/log/
# mkdir -p /var/jails/wuftpd/var/run/
Переименуем конфигурационные файлы и при необходимости подредактируем:
# cd /var/jails/wuftpd/etc
# cp ftpaccess.example ftpaccess
# cp ftpgroups.example ftpgroups
# cp ftpusers.example ftpusers
# cp ftpconversions.example ftpconversions
Ещё нам понадобится файл паролей, поскольку wu-ftpd использует его для работы (для анонимного доступа нужно также завести пользователя ftp, в качестве пароля можно поставить «*» так же, как и пользователю root, – они всё равно не используются, а «с# head -3 /etc/master.passwd > master.passwd
# vipw -d
Последней командой мы как раз-таки и вносим в master.passwd необходимых пользователей. Рабочие хэш-базы при выходе из редактора будут созданы автоматически, не забудьте только указать текущий каталог директивой -d, чтобы не попортить файл паролей основной системы. Приготовления на этом можно считать завершёнными.
Однако попытка запустить jail выявляет ещё одну недоработку:
# jail /var/jails/wuftpd wuftpd 10.30.0.121 /libexec/ftpd -S
ELF interpreter /libexec/ld-elf.so.1 not found
Abort trap:
|
Исправляемся:
# cp /libexec/ld-elf.so.1 /var/jails/wuftpd/libexec/
Запускаем вручную и проверяем:
# jail /var/jails/wuftpd wuftpd 10.30.0.121 /libexec/ftpd -S
# jls
JID IP Address Hostname Path
24 10.30.0.121 wuftpd /var/jails/wuftpd
# sockstat | grep 10.30.0.121
root ftpd 8030 0 tcp4 10.30.0.121 *:*
# ps ax | grep J
8030 ?? IsJ 0:00,01 ftpd: accepting connections on port 2 (ftpd)
8156 p0 R+ 0:00,01 grep J
# killall -j 24
|
Последняя команда демонстрирует, как можно остановить jail-систему, запущенную вручную, – идентификатор возвращается утилитой jls (в нашем примере он равен 24).
Далее – уже знакомые вам процедуры: создаём псевдоним для интерфейса, задав IP-адрес, вносим несколько строк в /etc/rc.conf и запускаем jail. Готово, можно рассылать своим друзьям-хакерам IP-адрес с просьбой взломать этот сервер.
Заключение
Как видите, работать с jail достаточно просто. Но это не означает, что стоит «пихать» каждую сетевую службу в «тюрьму», – такое решение во многих случаях будет похоже на стрельбу из пушки по воробьям, особенно когда процесс работает с правами непривилегированного пользователя. Но если вы всё же считаете, что вам будет спокойнее, если все «апачи» и «сендмейлы» будут изолированы от основной системы, то используйте jail – это ненамного сложнее, чем в случае chroot, но зато вы получите все преимущества вызова, специально разработанного для решения проблем безопасности. К тому же к вашим услугам довольно удобный инструментарий для управления и надзора за вашими «тюрьмами».
Приложение
Технологии «соседей»: зоны Solaris
Начиная с 10-й версии в Solaris существует реализация так называемых зон – технологии, очень близкой по своей сущности «тюрьмам» FreeBSD. Зоны позволяют запускать в рамках одного ядра несколько изолированных экземпляров системы. Так же, как и в jail, процессы различных зон не имеют возможности влиять друг на друга и даже наблюдать за «чужими» действиями.
Сама система, в которой оказывается администратор после установки Solaris, – это тоже зона, именуемая глобальной. Процессы глобальной зоны имеют расширенные полномочия для мониторинга процессов в «обычных» зонах.
Работа с зонами реализована гораздо удобнее и последовательнее, чем средства работы с jail, – к услугам администратора мощные утилиты zoneadm и zonecfg, позволяющие создавать, инсталлировать, конфигурировать зоны и управлять их работой. Взаимодействие с зоной осуществляется через так называемую консоль зоны, подключение к которой выполняется утилитой zlogin.
По умолчанию зоны используют (с правами только на чтение с помощью loopback filesystem) ряд пакетов глобальной зоны, благодаря чему их размер сравнительно небольшой, хотя «изнутри» зона мало чем отличается от полноценной системы.
Внутри неглобальной зоны действуют ограничения, аналогичные ограничениям jail, – невозможно просмотреть информацию о процессах в других зонах, запрещены загрузка модулей ядра, настройка оборудования и т. д. Правда, «администратор» неглобальной зоны имеет возможность перезагрузить её. Или, скажем, есть возможность внутри зоны использовать «сырые» сокеты для ICMP (для других типов трафика их использование для неглобальных зон запрещено). Есть, естественно, и другие отличия.
Технологии «соседей»: VServer и Virtuozzo/OpenVZ
Операционная система Linux тоже готова порадовать своих пользователей возможностью строить изолированные среды запуска процессов. Наиболее распространённые из них – VServer и Virtuozzo, поставляемые в виде патчей к ядру и набора утилит.
VServer, достаточно близкий по своей концепции к jail в FreeBSD, подробно был описан в статье Дмитрия Столярова «Linux-VServer: настраиваем виртуальные серверы» (октябрь 2006 года).
Технология Virtuozzo, разработанная компанией SWSoft, также позволяет запускать на одном физическом сервере до нескольких сотен изолированных виртуальных сред (Virtual Environment, VE) под управлением одного ядра. Virtuozzo распространяется под проприетарной лицензией. Однако доступна также открытая система OpenVZ, являющаяся базой для Virtuozzo. По заявлениям разработчиков, накладные расходы на создание виртуальных сред не превышают 1-3%, что делает подобные технологии заметно эффективнее для ряда задач, чем виртуальные машины.
- Алексей Закиров. Использование jail для предоставления shell-доступа – http://www.opennet.ru/base/sec/freebsd_jail_setup.txt.html.
- Запуск Apache в jail-окружении под FreeBSD – http://www.inode.ru/articles/network/2006-02-09/294.
- Установка и настройка клеток (jail) на FreeBSD6.1 – http://www.lissyara.ru/?id=1197.
- Using a jail as a virtual machine – http://www.freebsddiary.org/jail.php.
- Mike DeGraw-Bertsch. FreeBSD Jails – http://www.onlamp.com/lpt/a/4139.
- Poul-Henning Kamp. Building Systems to be Shared Securely – http://www.acmqueue.org/modules.phpname=Content&pa=printer_friendly&pid=170&page=1.
- База данных login-классов login.conf – http://pascal.tsu.ru/unix/users/class.html.