Мандатная модель распределения прав в FreeBSD v.2.0

    Введение


    В данной публикации пойдёт речь о мандатной модели bsdextended, на handbook её описывают как брандмауэр файловой системы. Преимущество данного подхода над тем который я описывал в данном руководстве является тот факт, что не имеет значения какая файловая система используется, так как ограничения будут происходить не по меткам на файлах, а по uid и gid пользователей.

    Подготовка


    Все действия будут произведены в jail, поэтому необходимо изначально настроить jail. Данное руководство написано с учётом того, что jail установлен в каталог /jails/famp. Первым делом установим необходимые модули в «автозапуск», а также запустим их(данные действия необходимо проделывать не в jail) и установим возможность использовать порты 80, 443 пользователю www без root прав:

    echo 'mac_portacl_load="YES"' >>/boot/loader.conf
    echo 'mac_bsdextended_load="YES"' >> /boot/loader.conf
    
    kldload mac_portacl.ko
    kldload mac_bsdextended.ko
    
    sysctl net.inet.ip.portrange.reservedlow=0 
    sysctl net.inet.ip.portrange.reservedhigh=0
    sysctl security.mac.portacl.rules=uid:80:tcp:80,uid:80:tcp:443
    
    echo 'net.inet.ip.portrange.reservedlow=0' >> /etc/sysctl.conf 
    echo 'net.inet.ip.portrange.reservedhigh=0' >> /etc/sysctl.conf
    echo 'security.mac.portacl.rules=uid:80:tcp:80,uid:80:tcp:443' >> /etc/sysctl.conf
    
    

    Далее в jail необходимо установить зависимости для сборки apache и php, а также установить порты:

    pkg install apr autoconf autoconf-wrapper automake ca_root_nss cmake curl db5 dialog4ports expat fontconfig freetype2 gdbm gettext-runtime gettext-tools giflib gmake gmp gperf help2man indexinfo jbigkit jpeg-turbo jsoncpp libarchive libargon2 libffi libgcrypt libgd libgpg-error libiconv liblz4 libnghttp2 libtextstyle libtool libuv libxml2 libxslt libzip lzo2 m4 meson nasm ninja oniguruma p5-Locale-gettext p5-Locale-libintl p5-Text-Unidecode p5-Unicode-EastAsianWidth pcre pcre2 perl5 pkgconf png py37-Babel py37-Jinja2 py37-MarkupSafe py37-alabaster py37-asn1crypto py37-certifi py37-cffi py37-chardet py37-cryptography py37-cython py37-docutils py37-idna py37-imagesize py37-openssl py37-pycparser py37-pygments py37-pysocks py37-pystemmer py37-pytz py37-requests py37-setuptools py37-six py37-snowballstemmer py37-sphinx py37-sphinx_rtd_theme py37-sphinxcontrib-websupport py37-urllib3 python37 re2c readline rhash sqlite3 texinfo tiff webp openssl wget
    
    portsnap fetch extract
    

    Сборка


    Перейдём в каталог порта apache, в данном каталоге необходимо выполнить «конфигурирование» порта таким образом, что-бы он установился в каталог /famp:

    mkdir /famp
    cd /usr/ports/www/apache24
    make config
    make configure
    cd work
    cd httpd-2.4.43
    ./configure --prefix=/famp
    cd ..//..
    make BATCH=yes PREFIX=/famp install clean
    

    После данных манипуляций apache установится в каталог /famp, php таким образом не установить, поэтому установим из исходного кода:

    cd /
    wget https://www.php.net/distributions/php-7.4.5.tar.xz
    xz -d php-7.4.5.tar.xz
    tar -xvf php-7.4.5.tar
    cd php-7.4.5
    

    После данных манипуляций необходимо выполнить сборку php указав корректный путь до apxs:

    ./configure --prefix=/famp --with-apxs2=/famp/sbin/apxs --with-openssl --with-zlib --with-curl --enable-mbstring --with-zip --enable-mysqlnd --enable-maintainer-zts --with-mysqli
    
    gmake install
    

    Настройка


    Дальнейшим действием будет корректная настройка httpd.conf (а также остальных необходимых «конифигов»), копирование каталога rc.d и создание необходимых каталогов:

    mkdir /famp/log
    mkdir /famp/run
    
    cp -R /famp/etc/rc.d/ /usr/local/etc/rc.d
    #в скрипте инициализации /usr/local/etc/rc.d/apache24 необходимо отредактировать одну строку, для корректного использования pid`а процесса
    _pidprefix="/famp/run/httpd"
    
    #в httpd.conf отредактируйте следующие строки
    
    Mutex default:/famp/run
    PidFile "/famp/run/httpd.pid"
    ErrorLog "/famp/log/httpd-error.log"
    CustomLog "/famp/log/httpd-access.log
    
    #httpd-ssl.conf (также необходимо отредактировать пути до сертификатов)
    SSLSessionCache        "shmcb:/famp/run/ssl_scache(512000)"
    DocumentRoot "/famp/www/apache24/data"
    ErrorLog "/famp/log/httpd-error.log"
    TransferLog "/famp/log/httpd-access.log"
    CustomLog "/famp/log/httpd-ssl_request.log"
    <Directory "/famp/www/apache24/cgi-bin">
    

    Для того что-бы все процессы apache запускались из под имени www необходимо на файл httpd установить setuid бит, а также необходимо выставить рекурсивно владельца на каталог famp пользователю www и запустить apache:

    chown -R www:www /famp
    chmod 4755 /famp/sbin/httpd
    

    После того как apache будет запущен и созданы необходимые файлы логов, можно изменить права на необходимые каталоги и файлы, но перед эти необходимо отредактировать ldconfig. Данная утилита отвечает за пути до каталогов с различными библиотеками, после изменения прав на каталоги /lib, /usr/lib, usr/local/lib утилита ldconfig будет считать данные каталоги не легитимными, по этой причине данную утилиту необходимо запускать в не защищённом режиме. Для просмотра путей необходимо выполнить команду:

    ldconfig -r
    

    Для запуска ldconfig в не защищённом режиме необходимо запустить данную утилиту с ключём i:

    ldconfig -iR /lib /usr/lib /usr/lib/compat /usr/local/lib /usr/local/lib/compat/pkg /usr/local/lib/perl5/5.30/mach/CORE
    

    Также необходимо скопировать файл /usr/local/lib/libnghttp2.so.14 в каталог /usr/lib (не совсем понятно почему apache его не видет в каталоге /usr/local/lib)

    cp /usr/local/lib/libnghttp2.so.14 /usr/lib/libnghttp2.so.14
    

    Изменим права на каталоги и файлы необходимые для корректной работы apache:

    #необходимо выполнить не из jail
    chflags noschg /jails/famp/lib/libcrypt.so.5
    chflags noschg /jails/famp/lib/libc.so.7
    chflags noschg /jails/famp/lib/libthr.so.3
    chflags noschg /jails/famp/usr/lib/librt.so.1
    
    #необходимо выполнять из jail
    chown www:wheel /
    chown -R www:www /famp
    chown www:wheel /etc
    chown www:wheel /tmp
    chown -R www:wheel /dev
    chown www:wheel /etc/passwd
    chown www:wheel /etc/group
    chown www:wheel /etc/pwd.db
    chown www:wheel /lib
    chown www:wheel /usr
    chown www:wheel /usr/lib
    chown www:wheel /usr/local
    chown www:wheel /usr/local/lib
    chown -R www:wheel /lib
    chown -R www:wheel /usr/lib
    chown -R www:wheel /usr/local/lib
    
    sysrc apache24_enable="YES"
    service apache24 start
    

    После данным манипуляций apache будет иметь доступ ко всем файл которые необходимы для его работы в изолированной среде, но на мой взгляд не совсем корректно то, что все эти файлы принадлежат пользователю www, по этой причине можно использовать флаги неизменяемости, данные флаги необходимо устанавливать не и из jail, так как по умолчанию jail запускается с ограниченными правами:

    chflags schg /jails/famp
    chflags schg /jails/famp/etc
    chflags schg /jails/famp/etc/passwd
    chflags schg /jails/famp/etc/group
    chflags schg /jails/famp/etc/pwd.db
    
    chflags schg /jails/famp/lib
    chflags schg /jails/famp/usr
    chflags schg /jails/famp/usr/lib
    chflags schg /jails/famp/usr/local
    chflags schg /jails/famp/usr/local/lib
    
    chflags -R schg /jails/famp/lib
    chflags -R schg /jails/famp/usr/lib
    chflags -R schg /jails/famp/usr/local/lib
    
    chflags -R schg /jails/famp/famp
    #на данные каталоги не нужно устанавливать данные флаги, так как в них должны быть права на запись
    chflags -R noschg /jails/famp/famp/log
    chflags -R noschg /jails/famp/famp/run
    chflags -R noschg /jails/famp/famp/www/apache24/data/cache
    
    #Флаг sunlink запретит удалять каталоги, или файлы (в данном случаи каталоги tmp, cache, log, run не имеют флагов неизменяемости, по этому чисто теоретически apache имеет права на удалени данных каталогов) 
    chflags sunlink /jails/famp/dev
    chflags sunlink /jails/famp/tmp
    chflags sunlink /jails/famp/famp/www/apache24/data/cache
    chflags -R sunlink /jails/famp/famp/log
    chflags sunlink /jails/famp/famp/run
    
    # Флаг sappend разрешает только дозапись в файл, т.е. в логи apache можно только дописывать данные, но не удалять и не редактировать.
    chflags -R sappend /jails/famp/famp/log
    

    Предпоследним штрихом будет создание исполняемого файла для высталение необходимых прав и запуска apache, а также запуска ldconfig в не защищённом режиме(выполнить в jail):

    touch /etc/rc.d/0
    chmod +x /etc/rc.d/0
    #следующие строки необходимо внести в данный файл
    ldconfig -iR /lib /usr/lib /usr/lib/compat /usr/local/lib /usr/local/lib/compat/pkg /usr/local/lib/perl5/5.30/mach/CORE
    #Доступ в каталог в /dev необходим в том случаи если в системе установлен парамет sysctl для рандомизации pid`а и использования ssl
    chown -R www:wheel /dev
    service apache24 start
    

    И наконец последним штрихом будет выставление параметра для bsdextended, также необходимо создать исполняемый файл для того что бы данные ограничения срабатывали при каждой загрузке системы (выполнять не в jail):

    touch /etc/rc.d/0
    chmod +x /etc/rc.d/0
    #В данный файл поместите строку
    ugidfw set 2 subject uid www object ! uid www mode n
    #для немедленого применения ограничений выполните данную строку
    ugidfw set 2 subject uid www object ! uid www mode n
    

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

    Вывод


    Как видно из данной публикации такой метод для ограничения процессов приведёт к высокой степени защищённости вэб сервера (а также любого другого стека к которому будет применён данный метод).

    Список источников которые мне очень помогли в написании данной публикации.
    www.freebsd.org/doc/ru_RU.KOI8-R/books/handbook/mac-bsdextended.html
    www.freebsd.org/doc/ru_RU.KOI8-R/books/handbook/mac-portacl.html
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 9

      0
      По сравнению с selinux, выглядит как полные костыли.
        0
        SeLinux, к сожалению, отсутствует в FreeBSD
          0

          это тот selinux, который первым делом отключают при инсталляции кубернетис? да-а — selinux полезен.

            0
            если руки из ж чем поможет кубернетис? разрабы всегда обожают пускать свои писульки с максимальными правами и с отключенными firewall.
              0

              какие разрабы? — СКА! "первым делом выключаем selinux" ©
              поэтому если изделие N1 анб так хорошо, отчего ж его первым делом-то выключать?
              и это не только кубик… в knowledge base самого redhat'а при проблемах с их же (RH) продуктами (которые, правда, только обновились) первейший совет — попробовать без selinux :)
              ой, не умеют, видать, в RH его готовить...

                0
                Это не означает что выключить совсем и забыть, а временно для проверки. Если проблема в нем, то ковырять надо уже его. Не всегда ибо очевидно, что именно selinux мешает.
                В любом случае идея с лейблами гораздо разумнее chown-а на системные файлы, только для работы apache из под jail. Как мне кажется, после этого, смысл jail уже теряется. Какой смысл что-то защищать, если процесс апача может системные либы как хочешь крутить — он же овнер.
                  0

                  "временно" в 90% случает означает "навсегда".
                  работает — не трожь (С), не так ли? :)
                  и вам действительно "сильно кажется", что смысл jail теряется…
                  добавлю, что root внутри docker == root в host-системе.
                  в отличие от jail.

                    0
                    Видимо Вы не внимательно читали статью, повнимательней прочитайте про «флаги» неизменяемости, с установленным данным флагом даже root не чего не сможет с этими файлами сделать, по умолчанию в jail данные «флаги» нельзя снимать, или устанавливать, поэтому у меня написано устанавливать данные «флаги» не из jail, по этой причине данные системные файлы не как не удалить и не модифицировать даже владельцу.
                      0
                      Я после этого комментария все внимательнее пересмотрел, да флаги стоят и запрещают модифицировать данные файлы, и снять их можно только вне jail из под root.
                      Кстати, это не запрещает апачу размещать новые файлы в либах…
                      И еще один момент не понял:
                      chflags schg /jails/famp/lib
                      chflags schg /jails/famp/usr
                      chflags schg /jails/famp/usr/lib
                      chflags schg /jails/famp/usr/local
                      chflags schg /jails/famp/usr/local/lib

                      chflags -R schg /jails/famp/lib
                      chflags -R schg /jails/famp/usr/lib
                      chflags -R schg /jails/famp/usr/local/lib

                      Разве есть смысл в 1,3,5 строках, ниже делается это же рекурсивно?

                      И все же, свое мнение из первого комментария, я не изменил — выглядит как один большой костыль.

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