Введение
Для обеспечения дополнительного уровня безопасности сервера можно использовать мандатную модель распределения доступа. В данной публикации будет описано каким образом можно запускать apache в jail с доступом только к тем компонентам, к которым необходим доступ для корректной работы apache и php. По данному принципу можно ограничивать не только apache, а также любой другой стэк.
Подготовка
Данный метод подойдёт только для файловой системы ufs, в данном примере в основной системе будет использоваться zfs, а в jail соответственно ufs. Первым делом необходимо пересобрать ядро, при установке FreeBSD установите исходный код.
После того как система будет установлена, отредактируйте файл:
/usr/src/sys/amd64/conf/GENERIC
В данный файл необходимо добавить всего одну строку:
options MAC_MLS
Метка mls/high будет иметь доминирующее положение над меткой mls/low, приложения которые будут запущены с меткой mls/low не смогут получить доступ к файлам которые имею метку mls/high. Более подробно о всех доступных метка в системе FreeBSD можно прочитать в данном руководстве.
Далее перейдите в каталог /usr/src:
cd /usr/src
Для запуска сборки ядра выполните (в ключе j укажите количество ядер в системе):
make -j 4 buildkernel KERNCONF=GENERIC
После того как ядро будет собрано, его необходимо установит:
make installkernel KERNCONF=GENERIC
После инсталляции ядра не торопитесь перезагружать систему, так-как необходимо перевести пользователей в логин класс, предварительно его настроив. Отредактируйте файл /etc/login.conf, в данном файле необходимо отредактировать логин класс default, приведите его к виду:
default: :passwd_format=sha512: :copyright=/etc/COPYRIGHT: :welcome=/etc/motd: :setenv=MAIL=/var/mail/$,BLOCKSIZE=K: :path=/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin ~/bin: :nologin=/var/run/nologin: :cputime=unlimited: :datasize=unlimited: :stacksize=unlimited: :memorylocked=64K: :memoryuse=unlimited: :filesize=unlimited: :coredumpsize=unlimited: :openfiles=unlimited: :maxproc=unlimited: :sbsize=unlimited: :vmemoryuse=unlimited: :swapuse=unlimited: :pseudoterminals=unlimited: :kqueues=unlimited: :umtxp=unlimited: :priority=0: :ignoretime@: :umask=022: :label=mls/equal:
Строка :label=mls/equal, даст возможность пользователям которые состоят в данном классе получать доступ к файлам которые отмечены любой меткой (mls/low, mls/high). После данных манипуляций необходимо пересобрать базу данных и поместить пользователя root (а также тех которым это необходимо) в данный логин класс:
cap_mkdb /etc/login.conf
pw usermod root -L default
Для того что-бы политика касалась только файлов необходимо отредактировать файл /etc/mac.conf, оставьте в нём только одну строку:
default_labels file ?mls
Также необходимо добавить модуль mac_mls.ko в автозапуск:
echo 'mac_mls_load="YES"' >> /boot/loader.conf
После этого можно смело перезагрузить систему. Как создать jail можно прочитать в одной из моих публикаций. Но перед тем как создавать jail необходимо добавить жёсткий диск и создать на нём файловую систему и включить на нём multilabel, создайте файловую систему ufs2 с размером кластера 64kb:
newfs -O 2 -b 64kb /dev/ada1
tunefs -l enable /dev/ada1
После создания файловой системы и добавления multilabel необходимо добавить жесткий диск в /etc/fstab, добавьте строку в данный файл:
/dev/ada1 /jail ufs rw 0 1
В Mountpoint укажите каталог в который Вы будете монтировать жёсткий диск, в Pass обязательно укажите 1 (в какой последовательности будет произведена проверка данного жёсткого диска) — это необходимо, так-как файловая система ufs чувствительна к резким обрывам электро питания. После данных действий смонтируйте диск:
mount /dev/ada1 /jail
В данный каталог установите jail. После того как jail заработает, в нём необходимо проделать те же манипуляции, что и в основной системе с пользователями и файлами /etc/login.conf, /etc/mac.conf.
Настройка
Перед тем как установить необходимые метки, рекомендую установить все необходимые пакеты, в моём случаи метки будут выставлены с учётом данных пакетов:
mod_php73-7.3.4_1 PHP Scripting Language
php73-7.3.4_1 PHP Scripting Language
php73-ctype-7.3.4_1 The ctype shared extension for php
php73-curl-7.3.4_1 The curl shared extension for php
php73-dom-7.3.4_1 The dom shared extension for php
php73-extensions-1.0 "meta-port" to install PHP extensions
php73-filter-7.3.4_1 The filter shared extension for php
php73-gd-7.3.4_1 The gd shared extension for php
php73-gettext-7.3.4_1 The gettext shared extension for php
php73-hash-7.3.4_1 The hash shared extension for php
php73-iconv-7.3.4_1 The iconv shared extension for php
php73-json-7.3.4_1 The json shared extension for php
php73-mysqli-7.3.4_1 The mysqli shared extension for php
php73-opcache-7.3.4_1 The opcache shared extension for php
php73-openssl-7.3.4_1 The openssl shared extension for php
php73-pdo-7.3.4_1 The pdo shared extension for php
php73-pdo_sqlite-7.3.4_1 The pdo_sqlite shared extension for php
php73-phar-7.3.4_1 The phar shared extension for php
php73-posix-7.3.4_1 The posix shared extension for php
php73-session-7.3.4_1 The session shared extension for php
php73-simplexml-7.3.4_1 The simplexml shared extension for php
php73-sqlite3-7.3.4_1 The sqlite3 shared extension for php
php73-tokenizer-7.3.4_1 The tokenizer shared extension for php
php73-xml-7.3.4_1 The xml shared extension for php
php73-xmlreader-7.3.4_1 The xmlreader shared extension for php
php73-xmlrpc-7.3.4_1 The xmlrpc shared extension for php
php73-xmlwriter-7.3.4_1 The xmlwriter shared extension for php
php73-xsl-7.3.4_1 The xsl shared extension for php
php73-zip-7.3.4_1 The zip shared extension for php
php73-zlib-7.3.4_1 The zlib shared extension for php
apache24-2.4.39
В данном примере метки будут выставлены с учётом зависимостей данных пакетов. Можно конечно поступить проще, для папки /usr/local/lib и файлов которые находятся в данном каталоге выставить метки mls/low и последующие установленные пакеты (например дополнительные расширения для php), смогут получит доступ к библиотекам в данном каталоге, но мне кажется лучше предоставить доступ только к тем файла которые необходимы. Остановите jail и установите на все файлы метки mls/high:
setfmac -R mls/high /jail
При выставлении меток, процесс будет остановлен если setfmac наткнётся на жёсткие ссылки, в моём примере я удалял жёсткие ссылки в следующих каталогах:
/var/db/etcupdate/current/
/var/db/etcupdate/current/etc
/var/db/etcupdate/current/usr/share/openssl/man/en.ISO8859-15
/var/db/etcupdate/current/usr/share/man/en.ISO8859-15
/var/db/etcupdate/current/usr/share/man/en.UTF-8
/var/db/etcupdate/current/usr/share/nls
/etc/ssl
/usr/local/etc
/usr/local/etc/fonts/conf.d
/usr/local/openssl
После того как метки будут установлены, необходимо выставить метки mls/low для apache, первым делом необходимо выяснить какие файлы необходимы для запуска apache:
ldd /usr/local/sbin/httpd
После выполнения данной команды на экране отобразятся зависимости, но выставить на данные файлы необходимые метки будет не достаточно, так-как каталоги в которых данные файлы находятся имеют метку mls/high, поэтому на данные каталоги также необходимо выставить метку mls/low. При запуске apache также выдаст файлы которые необходимы для его запуска, а для php эти зависимости можно узнать в логе httpd-error.log.
setfmac mls/low /
setfmac mls/low /usr/local/lib/libpcre.so.1
setfmac mls/low /usr/local/lib/libaprutil-1.so.0
setfmac mls/low /usr/local/lib/libdb-5.3.so.0
setfmac mls/low /usr/local/lib/libgdbm.so.6
setfmac mls/low /usr/local/lib/libexpat.so.1
setfmac mls/low /usr/local/lib/libapr-1.so.0
setfmac mls/low /lib/libcrypt.so.5
setfmac mls/low /lib/libthr.so.3
setfmac mls/low /lib/libc.so.7
setfmac mls/low /usr/local/lib/libintl.so.8
setfmac mls/low /var
setfmac mls/low /var/run
setfmac mls/low /var/log
setfmac mls/low /var/log/httpd-access.log
setfmac mls/low /var/log/httpd-error.log
setfmac mls/low /var/run/httpd.pid
setfmac mls/low /lib
setfmac mls/low /lib/libcrypt.so.5
setfmac mls/low /usr/local/lib/db5/libdb-5.3.so.0
setfmac mls/low /usr/local/lib/db5/libdb-5.3.so.0.0.0
setfmac mls/low /usr/local/lib/db5
setfmac mls/low /usr/local/lib
setfmac mls/low /libexec
setfmac mls/low /libexec/ld-elf.so.1
setfmac mls/low /dev
setfmac mls/low /dev/random
setfmac mls/low /usr/local/libexec
setfmac mls/low /usr/local/libexec/apache24
setfmac mls/low /usr/local/libexec/apache24/*
setfmac mls/low /etc/pwd.db
setfmac mls/low /etc/passwd
setfmac mls/low /etc/group
setfmac mls/low /etc/
setfmac mls/low /usr/local/etc
setfmac -R mls/low /usr/local/etc/apache24
setfmac mls/low /usr
setfmac mls/low /usr/local
setfmac mls/low /usr/local/sbin
setfmac mls/low /usr/local/sbin/*
setfmac -R mls/low /usr/local/etc/rc.d/
setfmac mls/low /usr/local/sbin/htcacheclean
setfmac mls/low /var/log/httpd-access.log
setfmac mls/low /var/log/httpd-error.log
setfmac -R mls/low /usr/local/www
setfmac mls/low /usr/lib
setfmac mls/low /tmp
setfmac -R mls/low /usr/local/lib/php
setfmac -R mls/low /usr/local/etc/php
setfmac mls/low /usr/local/etc/php.conf
setfmac mls/low /lib/libelf.so.2
setfmac mls/low /lib/libm.so.5
setfmac mls/low /usr/local/lib/libxml2.so.2
setfmac mls/low /lib/libz.so.6
setfmac mls/low /usr/lib/liblzma.so.5
setfmac mls/low /usr/local/lib/libiconv.so.2
setfmac mls/low /usr/lib/librt.so.1
setfmac mls/low /lib/libthr.so.3
setfmac mls/low /usr/local/lib/libpng16.so.16
setfmac mls/low /usr/lib/libbz2.so.4
setfmac mls/low /usr/local/lib/libargon2.so.0
setfmac mls/low /usr/local/lib/libpcre2-8.so.0
setfmac mls/low /usr/local/lib/libsqlite3.so.0
setfmac mls/low /usr/local/lib/libgd.so.6
setfmac mls/low /usr/local/lib/libjpeg.so.8
setfmac mls/low /usr/local/lib/libfreetype.so
setfmac mls/low /usr/local/lib/libfontconfig.so.1
setfmac mls/low /usr/local/lib/libtiff.so.5
setfmac mls/low /usr/local/lib/libwebp.so.7
setfmac mls/low /usr/local/lib/libjbig.so.2
setfmac mls/low /usr/lib/libssl.so.8
setfmac mls/low /lib/libcrypto.so.8
setfmac mls/low /usr/local/lib/libzip.so.5
setfmac mls/low /etc/resolv.conf
В данном списке выставляются метки mls/low на все файлы которые необходимы для корректной работы связки apache и php (для тех пакетов которые установлены в моём примере).
Последним штрихом будет настройка запуска jail на уровне mls/equal, а apache на уровне mls/low. Для запуска jail необходимо внести изменения в скрипт /etc/rc.d/jail, найдите в данном скрипте функцию jail_start, переменную command приведите к виду:
command="setpmac mls/equal $jail_program"
Команда setpmac запускает исполняемый файл на необходимом мандатном уровне, в данном случаи mls/equal, чтобы иметь доступ к всем меткам. В apache необходимо отредактировать стартовый скрипт /usr/local/etc/rc.d/apache24. Внесите изменения в функцию apache24_prestart:
apache24_prestart() {
apache24_checkfib
apache24_precmd
eval "setpmac mls/low" ${command} ${apache24_flags}
}
В официальном руководстве указан другой пример, но мне не удалось его использовать так как постоянно выдавалось сообщение о невозможности использовать команду setpmac.
Вывод
Данный способ распределения доступа добавит дополнительный уровень защищённости apache (хотя этот способ подойдёт к любому другому стэку), который помимо этого запускается в jail, в тоже время для администратора всё это будет происходить прозрачно и не заметно.
Список источником которые мне помогли в написании данной публикации:
https://www.freebsd.org/doc/ru_RU.KOI8-R/books/handbook/mac.html
Комментарии (6)
vit41ik
19.04.2019 15:08Для запуска сборки ядра выполните (в ключе j укажите количество ядер в системе):
make -j 4 buildkernel KERNCONF=GENERIC
После того как ядро будет собрано, его необходимо установит:
make installkernel KERNCONF=GENERIC
Проще использовать make kernel KERNCONF=$NAME_CONFIG
Использовать конфиг GENERIC для кастомизации ядра не стоит, лучше дать файлу конфига ядра другое имя.
в ключе j укажите количество ядер в системе
в системе ядро то одно, его вы собираете, а вот у процессора ядер может быть больше :)Nemets85 Автор
19.04.2019 15:12Другое имя для конфига можно использовать если изменений много, а здесь всего одна строчка, не критично, если понадобиться оригинальный конфиг.
kibb
19.04.2019 15:28Будет критично, когда вы сами или кто-то после вас будет разбираться с системой и решит, что GENERIC это настоящий GENERIC, а не ваша кастомизация.
kibb
Зачем добавлять опцию в конфиг, если вы грузите модуль? Точнее, у вас после такой манипуляции будет работать модуль, влинкованный в ядро, а тот, что загрузится лоадером, проигнорирован.
Nemets85 Автор
На handbook написано, что модуль нужно подтягивать.
kibb
Нужно же понимать, что написано. В mac-mls указаны варианты с модулем и без, на выбор. Оба сразу бессмыслица.
Давайте я вам вслух зачитаю начало мана, там слов не пожалели.