Введение


Для обеспечения дополнительного уровня безопасности сервера можно использовать мандатную модель распределения доступа. В данной публикации будет описано каким образом можно запускать 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)


  1. kibb
    19.04.2019 11:07

    Зачем добавлять опцию в конфиг, если вы грузите модуль? Точнее, у вас после такой манипуляции будет работать модуль, влинкованный в ядро, а тот, что загрузится лоадером, проигнорирован.


    1. Nemets85 Автор
      19.04.2019 15:12

      На handbook написано, что модуль нужно подтягивать.


      1. kibb
        19.04.2019 15:26

        Нужно же понимать, что написано. В mac-mls указаны варианты с модулем и без, на выбор. Оба сразу бессмыслица.

        Давайте я вам вслух зачитаю начало мана, там слов не пожалели.

        MAC_MLS(4)             FreeBSD Kernel Interfaces Manual             MAC_MLS(4)
        
        NAME
             mac_mls  Multi-Level Security confidentiality policy
        
        SYNOPSIS
             To compile MLS into your kernel, place the following lines in your kernel
             configuration file:
        
                   options MAC
                   options MAC_MLS
        
             Alternately, to load the MLS module at boot time, place the following
             line in your kernel configuration file:
        
                   options MAC
        
             and in loader.conf(5):
        
                   mac_mls_load="YES"
        


  1. vit41ik
    19.04.2019 15:08

    Для запуска сборки ядра выполните (в ключе j укажите количество ядер в системе):

    make -j 4 buildkernel KERNCONF=GENERIC

    После того как ядро будет собрано, его необходимо установит:

    make installkernel KERNCONF=GENERIC

    Проще использовать make kernel KERNCONF=$NAME_CONFIG
    Использовать конфиг GENERIC для кастомизации ядра не стоит, лучше дать файлу конфига ядра другое имя.
    в ключе j укажите количество ядер в системе

    в системе ядро то одно, его вы собираете, а вот у процессора ядер может быть больше :)


    1. Nemets85 Автор
      19.04.2019 15:12

      Другое имя для конфига можно использовать если изменений много, а здесь всего одна строчка, не критично, если понадобиться оригинальный конфиг.


      1. kibb
        19.04.2019 15:28

        Будет критично, когда вы сами или кто-то после вас будет разбираться с системой и решит, что GENERIC это настоящий GENERIC, а не ваша кастомизация.