виртуальные серверы на основе Linux

подсистемы

Технология виртуальных серверов делает возможным изоляцию в рамках контекста исполнения всего дерева процессов гостевой системы, начиная с init. Гостевая система в виртуальном сервере изолирована по следующим подсистемам:

1. Файловая система. Как и в chroot гостевая система изолирована в рамках одного каталога базовой системы. Вместе с тем, при конфигурировании виртуальных серверов можно предоставить доступ к одному и тому же каталогу нескольким гостевым системам. Существует возможность монтирования нелокальных файловых систем внутри виртуального сервера, в том числе опробованы smb и nfs.
Ограничение ресурсов файловой системы поддерживается как на уровне базовой системы (дисковая квота для каждого виртуального сервера), так и на уровне гостевой системы (дисковые квоты для пользователей в пределах виртуального сервера).
Для гостевой ОС файловая система виртуального сервера представлена в виде блочного файла /dev/hdv1 (для vserver на ядре 2.4), на котором расположена корневая файловая система. Корневая файловая система содержит минимально необходимый набор файлов устройств в каталоге /dev/. Файловая система proc в госетвой ОС отображает параметры данной гостевой системы, в том числе выделенные ей ресурсы.

2. Процессы. Виртуальный сервер имеет свой независимый набор PID. Процессы в виртуальных серверах не видны из базовой системы при помощи обычных утилит - для управления процессами виртуальных серверов применяются их спциализированные аналоги - vps, vtop, vkill. Максимальное количество запущеных процессов регулируется, кроме того, существует возможность лимитировать количество доступной серверу оперативной памяти и процессорного времени (на ядре 2.6).

3. Сеть. Каждый виртуальный сервер имеет независимый IP-адрес (или адреса), к которому и привязываются все исполняющиеся на сервере процессы. FreeVPS позволяет при настройке определить полосу пропускания, доступную гостевой системе, в то время как в vserver необходимо использовать для этого средства Linux QoS.

4. Средства межпроцессного взаимодействия так же ограничены пределами виртуального сервера.

5. Привилегии суперпользователя. Пользователь root в виртуальном сервере ограничен в правах настолько, насколько этого требует безопасность базовой системы с сохранением необходимых возможностей, таких как привязка процесса на порт ниже 1024 и управление процессами и пользователями в пределах виртуального сервера.

6. Дополнительные средства защиты гостевой системы. Несмотря на то, что при использовании данной технологии, даже получив управление виртуальным сервером, злоумышленник, скорее всего (программ без дыр не бывает, и патчи к ядру - не исключение), нанести вред другим виртуальным серверам и базовой системе не сумет, дополнительная защита гостевой ОС лишней все же не является. Существуют интегрированные патчи vserver, включающие наработки проектов openwall и даже grsecurity.

системные вызовы

Для полной изоляции виртульного сервера в ядро были добавлены несколько новых системных вызовов. Основными являются:
new_s_context - создает контекст безопастности /* более здравого перевода для security context я не придумал – прим. автора */, служащий основой для изоляции процссов - возвращаемый им id служит отличительным признаком для всех ресурсов, принадлежащих одному виртуальному серверу. context id базовой системы в vserver равен нулю. Этот вызов является необратимым.
set_ipv4root - позволяет процессам использовать только заданный IP. Этот вызов также является необратимым.

Для ограничения суперпользователя в создаваемом виртуальном сервере применяется расширение linux capability /* ИМХО данный термин адекватному переводу не поддается – прим. автора */. Расширения касаются предоставления виртуальным серверам тех или иных возможностей базовой системы - например создания RAW-сокетов (необходимо для работы утилиты ping), монтирования файловых систем внутри виртуального сервера и т.п.
утилиты

Существует несколько программ, позволяющих ознакомится с механизмом работы виртуального сервера: chcontext, chbind, reducecap и vserver. chcontex позволяет запустить программу в отличном от текущего контексте.
chbind позволяет запустить приложение, представляя ему для работы определенный IP-адрес или интерфейс. Я использую его для ограничения “аппетитов” приложений, которые не могут быть сконфигурированы для использования определенного интерфейса или такая конфигурация неочевидна (известная болезнь пропиетарных приложений, в особенности писаных на Java).
Команда vserver является основной и используется для запуска и остановки виртуального сервера. Кроме того, она позволяет войти в виртуальный сервер с правами любого пользователя гостевой системы (в том числе и пользователя root) или выполнить в нем произвольную команду.

установка и настройка

Для создания виртуального сервера на основе vserver потребуются исходные тексты патча vserver для соответсвующей версии ядра. 2.4 с kernel.org. Vserver для ядра 2.6 мне пока попробовать в производственных условиях не удалось, хотя основная разработка ведется сейчас в этой ветке и значительная часть приятных возможностей присутсвует только в ней. На локальных серверах критических проблем со связкой 2.6 + Vserver у меня небыло. Патчи vserver как правило хорошо уживаются с патчами openwall, чем грех не воспользоваться. Наложить патч можно командой

patch -p1

из каталога, содержащего исходные тексты ядра.
Наложив патч на исходники, необходимо сконфигурировать ядро, выбрав в Block devices пукт enable virtual root. Остальные опции, включая openwall, - по желанию и согласно здравому смыслу. Из опций openwall нормально работают:

CONFIG_HARDEN_STACK=y
CONFIG_HARDEN_STACK_SMART=y
CONFIG_HARDEN_LINK=y
CONFIG_HARDEN_FIFO=y
CONFIG_HARDEN_PROC=y
CONFIG_HARDEN_RLIMIT_NPROC=y
CONFIG_HARDEN_SHM=y
Далее собираем ядро, на debian linux я использую команду

CC=gcc-2.95 make-kpkg binary-arch


которая создает пакеты с образом ядра и заголовочнми файлами к нему (kernel-headers). Для других дистрибутивов процедура может отличатся. Стоит отметить, что в debian sarge входит патч vserver (пакет kernel-patch-ctx) который подходит к исходникам ядра debian, однако иногда вызывает конфликты с патчем openwall. Для сборки ядра с использованием исходников ядра и патча из дистрибутива в debian можно использовать команду
make-kpkg --added_patches kernel-patch-ctx bianry-arch


в каталоге /usr/src/kernel-sources-2.4.XX/.
После перезагрузки, проверив работоспособность системы, следует установить программы для создания и управления виртуальными серверами, которые содержатся в пакеты util-vserver и vserver-debiantools (использовать пакет vserver не рекомендуется, так как в нем содержится более старый набор утилит). Пользователи других дистрибутивов, возможно, обнаружат схожие пакеты в своем дистрибутиве. utils-vserver есть в дереве портежей gentoo. Пакет rpm для Mandrake Linux находтся по адресуhttp://www.13thfloor.at/vserver/s_release/v1.28/.Возможно они подойдут и для других основных на rpm дистрибутивов. Впрочем, процедура компиляции этого набора утилит ничем особенным не отличается, никаких проблем со сборкой на RedHate Enterpise Linux 3 и Suse Linux Enterprise Server 9 у меня не возникло.

Для создания виртуального сервера в Debian можно использовать команду newvserver из пакета vserver-debiantools, которая создает новый виртуальный сервер с Debian в качестве гостевой системы, см. man 1 newvserver.
Для того, чтобы создать виртуальный сервер с гоствой ОС, отличной от базовой, необходимо написать конфигурационный файл и сделать каталог для хранения гостевой системы. По умолчанию, гостевая система должна быть в каталоге /vservers/SERVERNAME, конфигурационный файл -
/etc/vserver/SERVERNAME.conf.

В конфигурационном файле необходимо задать следующие параметры:
S_HOSTNAME="vhostname" - имя хоста для гостевой ОС.
IPROOT="10.0.0.10" - IP-адрес, который будет иметь гостевая система.
IPROOTDEV="eth0" - интерфейс для гостевой системы.

После запуска виртуального сервера в базовой системе будет виден виртуальный интерфейс вида eth0:SERVERNAME.
Broadcast и netmask можно задать параметрами IPROOTMASK и IPROOTBCAST. В случае, если эти параметры не указаны, они вычисляются на основании параметров IPROOTDEV.
Возможено задание нескольких IP-адресов, масок и интерфейсов в одной строке:

IPROOT="eth0:10.1.2.3/255.255.255.0 eth0:10.1.3.12/255.255.255.128"

ONBOOT=”yes” - указывает базовой системе на необходимость старта данного виртуального сервера при загрузке.
Параметр S_NICE задает приоритет, с которым будут выполнятся процессы в виртуальном сервере. Суперпользователь гостевой системы не может назначить nice выше этого значения.
Параметр S_FLAGS="lock nproc" задает флаги контекста.
Флаг lock запрещает гостевой ОС порождать новые виртуальные серверы внутри себя.
Флаг nproc разрешает ограничение количества процессов в виртуальном сервере. Количество процессов задается в параметре ULIMIT. Данный флаг является устарешим в vserver на ядре 2.6 и может быть убран в будущем.
Флаг private запрещает вход в гостевую систему из базовой.
Флаг sched указывает планировщику ядра на необходимость учитывать все процессы виртуального сервера как один процесс базовой системы, что позволяет предотвратить чрезмерное потребление процессорного времени гостевой системой. Кроме того, в Vserver на ядре 2.6 можно регулировать потребление процессорного времени при помощи квот.
Флаг fakeinit позвляет использовать /sbin/init гостевой системы в качестве init-процесса для этой системы.
Параметр ULIMIT задает базовые значение ulimit для виртуального сервера, например ULIMIT=”-H -u 1000” при установленом флаге nproc ограничивает количество процессов в виртуальном сервере тысячей.
Параметр S_CAPS определяет набор возможностей (capabilities), которые доступны виртуальному серверу. Наиболее часто используются следующие: CAP_NET_RAW - позволяет использовать RAW-сокеты.
CAP_SYS_TIME - позволяет изменять время, необходимо для работы ntp.
CAP_SYS_RESOURCE - позволяет процессу в виртуальном сервере изменять свои значения ulimit. Существует мнение, что опция необходима для работы bind9, хотя у меня bind работал и без нее.
CAP_NET_BROADCAST - разрешает использование broadcast- и multicast-передачи пакетов.
CAP_NET_ADMIN позволяет менять параметры сетевого интерфейса, маршрутизации, включать режим прослушивания сети (promiscuous mode).
Более полное описание доступных специфичных для vserver возможностей доступно в документации vserver.

По умолчанию уже включены следующие фичи:
CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH, CAP_FOWNER, CAP_FSETID, CAP_KILL, CAP_SETGID, CAP_SETUID, CAP_NET_BIND_SERVICE,
CAP_SYS_CHROOT, CAP_SYS_PTRACE, CAP_SYS_TTY_CONFIG, CAP_LEASE - их описание можно посмотреть в файле /usr/src/linux-
2.x.x/include/linux/capability.h

После написания конфигурационного файл следует развернуть в каталог /vservers/SERVERNAME/ образ гостевой системы. Эти образы доступны для загрузки, кроме того в пакет utils-vserver входит ряд скриптов, находящихся в /usr/lib/util-vserver/ и позволяющих создать образ гостевой системы с помощью дистрибутивных компакт-дисков. К сожалению, данные скрипты предназначены для не поддерживаемых производителями в настоящий момент дистрибутивов. Архивы с образами доступны например наhttp://www.lycos-vds.com/dists/(redhat, debian).

По соображениям безопасности необходимо установить права доступа 000. Для Vserver на ядре 2.6 необходимо запретить совмещение “хвостов” файлов в пределах одного блока (chattr +t /vserver на ядре 2.6) и установить атрибут “barrier” (setattr --barrier /vservers). При переходе с vserver для ядра 2.4 на vserver для ядра 2.6 следует помнить, что в связи с изменениями в механизме виртуализации файловой системы, на каталог /vservers обязательно должен быть установлен атрибут “barrier”, так как ограничение “chmod 000” в этом случае уже не является эффективным и может повлечь нарушение chroot-барьера администратором гостевой системы. Эксплойт данной уязвимости общедоступен в архивах списка рассылки проекта. Для использования с vserver рекомендуются файловые системы ext2/ext3 и reiserfs с поддержкой extended attributes, работоспособность на других файловых системах не гарантируется, на jfs не будет работать точно, на xfs примерно год назад поведение vserver было несколько неадекватным, с тех пор, насколько я знаю, лучше не стало.

Перед запуском виртуального сервера необходимо подготовить базовую систему таким образом, чтобы ее процессы не мешали процессам виртуальных серверов. Основной проблемой являются демоны, слушающие по умолчанию адрес 0.0.0.0, так как ими кроме сетевых интерфейсов базовой системы также будут использоваться сетевые интерфейсы виртуальных серверов (которые в базовой системе доступны как алиасы к существующим физическим интерфейсам).
После всего этого можно запустить виртуальный сервер командой vserver SERVERNAME start (регистр имеет значение). После старта виртуального сервера в него можно войти командой vserver enter, которая запускает shell в контексте виртуального сервера, если в конфигурационном файле не указан флаг private. Ряд сервисов (такие, как apmd, acpid, networking и т.п. теряют смысл, поэтом их можно убрать из используемого runlevel). Для того, чтобы позволить адмиистратору гостевой ОС перезагружать ее, в базовой системе должен быть запущен rebootmgr, рестарт гостевой системы производится командой /sbin/vrestart.
В Vserver для ядра 2.6 (а так же в нестабильной ветке 1.3 для ядра 2.4) появился ряд возможностей, недоступных в стабильной версии vserver для ядра 2.4.
Так, появилась возможность определять, какие файлы в из /proc базовой системы будут доступны в виртуальном сервере. По умолчанию, в vserver 2.4 доступны файлы процессов виртуального сервера + многие общесистемные файлы, например /proc/cpuinfo. Для контроля доступа к фалам /proc в Vserver можно использовать утилиту setattr из нестабильной версии util-vserver. Пример:

setattr --hide --admin /proc/cpuinfo


Флаг --hide указывает на необходимость скрыть файл в /proc и делает этот файл доступным в контексте 0 (базовой системе).
В нестабильной версии util-vserver появился скрипт vprocunhide, который выставляет довольно приемлемые и безопасные ограничения на /proc.

заключение

Создание виртуальных серверов несколько снижает производительность системы за счет того, что для каждой из гостевых систем в памяти хранятся свои копии загруженых библиотек, дополнительная нагрузка на процессор незначительна за счет того, что не используется ни трансляция команд процессора, ни эмуляция оборудования компьютера. В целом, использование vserver позволяет повыстить безопастность системы и более эффективно расходовать ее ресурсы. Например, при установке публичных серверов я стараюсь в базовой системе держать только демон ssh с авторизацией сугубо по ключам. На случай падения sshd его запуск прописан в /etc/inittab на respawn. Все публично доступные вынесены в гостевую систему. Базовая система используется для мониторинга, настройки firewall и резевного копирования. При вышеописанной настройке контроль за системой будет сохранен даже в случае взлома гостевой системы и смены ксаскепами пароля/ключа суперпользователя.



Богдан Рудас, системный аминистратор отделения интернет-технологий СП ЗАО "Международный деловой альянс" (IBA).¶

обсуждение статьи


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

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