📜 ⬆️ ⬇️

Mandatory distribution model of rights 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 apache and php to work correctly. 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, the main system will use zfs, and in jail, respectively, ufs. The first step is to rebuild the kernel, install the source code when installing FreeBSD.

After the system is installed, edit the file:

/usr/src/sys/amd64/conf/GENERIC 

Only one line should be added to this file:
')
 options MAC_MLS 

The label mls / high will have a dominant position over the label mls / low, applications that will run with the label mls / low will not be able to access files that have the label mls / high. More details about all available tags on the FreeBSD system can be found in this guide .
Next, go to the / usr / src directory:

 cd /usr/src 

To run a kernel build, execute (in the j key, specify the number of cores on 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, since it is necessary to transfer users to the login class by 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 members of this class to access files marked with any label (mls / low, mls / high). After these manipulations, you need to rebuild the database and put the root user (as well as those that need it) into this login class:

 cap_mkdb /etc/login.conf pw usermod root -L default 

In order for the policy to apply only to files, it is necessary to edit the /etc/mac.conf file, leave only one line in it:

 default_labels file ?mls 

You also need to add the mac_mls.ko module to autorun:

 echo 'mac_mls_load="YES"' >> /boot/loader.conf 

After that, you can safely restart the system. How to create a jail can be found in one of my publications. But before creating a jail, you need to add a hard disk 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 a hard disk in / etc / fstab, add a 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 you must specify 1 (in what sequence this hard drive will be checked) - this is necessary, since the ufs file system is sensitive to abrupt power outages. After these steps, mount the disk:

 mount /dev/ada1 /jail 

Install jail in this directory. After jail will work, it is necessary to do the same manipulations as in the main system with users and /etc/login.conf, /etc/mac.conf files.

Customization


Before you install the necessary labels, I recommend installing all the necessary packages, in my cases the labels will be displayed 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, labels will be set based on the dependencies of these packages. You can of course do it easier, for the / usr / local / lib folder and files that are in this directory, put mls / low tags and subsequent installed packages (for example, additional php extensions) will be able to access the libraries in this directory, but it seems to be better provide access only to those files that are required. Stop jail and install mls / high tags on all files:

 setfmac -R mls/high /jail 

When setting tags, the process will be stopped if setfmac stumbles upon hard links, in my example I deleted hard links in the following directories:

 /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 

After the labels are installed, you need to set the mls / low labels for apache, first of all you need to find out what files are needed to run apache:

 ldd /usr/local/sbin/httpd 

After executing this command, dependencies will appear on the screen, but placing the required labels on these files will not be enough, since the directories in which these files are located have the label mls / high, therefore you must also set the label mls / low on these directories. When you start apache, it will also show the files that are needed to start it, and for php you can find 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 tags are set for all files that are necessary for the apache and php bundles to work correctly (for those packages that are installed in my example).

The final touch is setting up jail launch at the level of mls / equal, and apache at the level of mls / low. To run jail, you need to make changes to the /etc/rc.d/jail script, find the jail_start function in this script, bring the command variable to the form:

 command="setpmac mls/equal $jail_program" 

The setpmac command runs the executable file at the required credential level, in this case mls / equal, to have access to all labels. In apache, you need to edit the /usr/local/etc/rc.d/apache24 startup script. Make changes to the apache24_prestart function:

 apache24_prestart() { apache24_checkfib apache24_precmd eval "setpmac mls/low" ${command} ${apache24_flags} } 

There is another example in the official manual, but I was unable to use it because the message about the inability to use the setpmac command was constantly displayed.

Conclusion


This method of access distribution will add an additional level of security for apache (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 in writing this publication:

https://www.freebsd.org/doc/ru_RU.KOI8-R/books/handbook/mac.html

Source: https://habr.com/ru/post/448642/


All Articles