Mandatory Distribution of Rights Model in FreeBSD
Introduction
To provide an additional level of server security, you can use the mandatory access distribution model . This publication will describe how you can run apache in jail with access only to those components that need access for the correct operation of apache and php. By this principle, you can limit not only apache, but also any other stack.
Training
This method is suitable only for the ufs file system, in this example, zfs will be used in the main system, and ufs in jail, respectively. The first step is to rebuild the kernel; when installing FreeBSD, install the source code.
After the system is installed, edit the file:
/usr/src/sys/amd64/conf/GENERIC
You need to add only one line to this file:
options MAC_MLS
The mls / high mark will dominate the mls / low mark, applications that will run with the mls / low mark will not be able to access files that have the mls / high mark. You can read more about all available labels in the FreeBSD system in this guide .
Next, go to the / usr / src directory:
cd /usr/src
To start the kernel assembly, do (in the j key, specify the number of cores for the processor):
make -j 4 buildkernel KERNCONF=GENERIC
After the kernel is assembled, it must be installed:
make installkernel KERNCONF=GENERIC
After installing the kernel, do not rush to reboot the system, as it is necessary to transfer users to the login class, after setting it up first. Edit the file /etc/login.conf, in this file you need to edit the login class default, bring it to the form:
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:
Line: label = mls / equal, will allow users who are in this class to access files that are marked with any label (mls / low, mls / high). After these manipulations, it is necessary to rebuild the database and place the root user (as well as those who need it) in this login class:
cap_mkdb /etc/login.conf
pw usermod root -L default
In order for the policy to concern only files, you need to edit the /etc/mac.conf file, leave only one line in it:
default_labels file ?mls
If there is no desire to rebuild the kernel, then you can use the module:
echo 'mac_mls_load="YES"' >> /boot/loader.conf
After that, you can safely reboot the system. How to create jail can be found in one of my publications. But before creating jail you need to add a hard drive and create a file system on it and enable multilabel on it, create a ufs2 file system with a cluster size of 64kb:
newfs -O 2 -b 64kb /dev/ada1
tunefs -l enable /dev/ada1
After creating the file system and adding multilabel, you need to add the hard drive to / etc / fstab, add the line to this file:
/dev/ada1 /jail ufs rw 0 1
In Mountpoint, specify the directory in which you will mount the hard drive, in Pass, be sure to specify 1 (in what order the given hard drive will be checked) - this is necessary, since the ufs file system is sensitive to sudden power outages. After these steps, mount the disk:
mount /dev/ada1 /jail
Install jail in this directory. After jail is working, it is necessary to do the same manipulations in it as in the main system with users and files /etc/login.conf, /etc/mac.conf.
Customization
Before you install the necessary labels, I recommend installing all the necessary packages, in my case the labels will be set taking into account these packages:
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
In this example, the labels will be set taking into account the dependencies of these packages. Of course, it’s easier to do this, for the / usr / local / lib folder and files located in this directory, set the mls / low labels and subsequent installed packages (for example, additional extensions for php), will be able to access the libraries in this directory, but it seems to me better grant access only to those files that are needed. Stop jail and set the mls / high label on all files, to do this, create a file with the name, for example, mac and add one line to it:
touche /mac
echo ‘.* mls/high’ > /mac
After that, run the command:
setfsmac -ef /mac /
After the labels are set, you need to set the mls / low labels for apache, the first thing you need to find out what files are needed to run apache:
ldd /usr/local/sbin/httpd
After executing this command, dependencies will be displayed on the screen, but putting the necessary labels on these files will not be enough, since the directories in which these files are located have the mls / high label, so you also need to put the mls / low label on these directories. When you start apache will also give out the files that are needed to run it, and for php you can find out these dependencies in the httpd-error.log 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
In this list, mls / low labels are set for all files that are necessary for the apache and php bundle to work correctly (for those packages that are installed in my example).
The final touch will be to configure jail to run at the mls / equal level, and apache at the mls / low level. To run jail, you need to make changes to the /etc/rc.d/jail script, find the jail_start function in this script, and bring the command variable to the following:
command="setpmac mls/equal $jail_program"
The setpmac command runs the executable at the required credential level, in this case mls / equal, in order to have access to all labels. In apache, you need to edit the start script /usr/local/etc/rc.d/apache24. Make changes to the apache24_prestart function:
apache24_prestart() {
apache24_checkfib
apache24_precmd
eval "setpmac mls/low" ${command} ${apache24_flags}
}
In the official manual, another example is indicated, but I was not able to use it because I constantly received a message about the inability to use the setpmac command.
Conclusion
This method of access distribution will add an additional level of apache security (although this method will suit any other stack), which, in addition, runs in jail, at the same time for the administrator, all this will be transparent and not noticeable.
List of sources that helped me write this publication:
https://www.freebsd.org/doc/ru_RU.KOI8-R/books/handbook/mac.html