SELinux
=======

Depending on the Puppet role and Hiera settings, SELinux can be enabled by
default. This is recommended especially for systems which are accessible from
outside PSI.

This section provides basic information on SELinux in general, common problems
and how to solve them.


SELinux
-------

Information on SELinux can be found here:

- `Mandatory Access Control <https://en.wikipedia.org/wiki/Mandatory_access_control>`_
- :download:`SELinux coloring book
  </_static/selinux-coloring-book_A4-Stapled.pdf>` (`original
  <https://people.redhat.com/duffy/selinux/selinux-coloring-book_A4-Stapled.pdf>`_)


SELinux modes
-------------

SELinux can be in one of three modes:

- ``enforcing``

  The SELinux policy is enforced, violations are logged.

- ``permissive``

  The SELinux policy is **not** enforced, but violations are still logged.

- ``disabled``

  SELinux is not loaded at all.


Going from ``enforcing`` or ``permissive`` to/from ``disabled`` requires a
reboot.


SELinux contexts
----------------

On an SELinux system every file has a context, and the SELinux policy controls
whether a confined service can access files of a given context.

The context of files can be listed with the :manpage:`stat(1)` command or by passing
the ``-Z`` option to ``ls(1)``::

  $ ls -Z /etc/fstab
  -rw-r--r--. root root system_u:object_r:etc_t:s0       /etc/fstab

  $ stat /etc/fstab
    File: ‘/etc/fstab’
    Size: 619       	Blocks: 8          IO Block: 4096   regular file
  Device: fd01h/64769d	Inode: 134320258   Links: 1
  Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
  Context: system_u:object_r:etc_t:s0
  Access: 2017-05-13 21:50:43.533927373 +0200
  Modify: 2016-04-03 04:19:02.289004083 +0200
  Change: 2016-04-03 04:29:29.955011505 +0200
   Birth: -



When files are created they are assigned a default context based on their path
according to the system policy.

The default contexts configured for various filesystem locations can be listed
by running :manpage:`semanage(8)`::

  $ semanage fcontext -l
  ...
  /usr/.*                                            all files          system_u:object_r:usr_t:s0 
  /var/.*                                            all files          system_u:object_r:var_t:s0 
  /run/.*                                            all files          system_u:object_r:var_run_t:s0 
  /srv/.*                                            all files          system_u:object_r:var_t:s0 
  ...


It is possible to add/list local customizations to the default contexts of the
system::


  $ semanage fcontext -a -t httpd_sys_content_t '/srv/web/data(/.*)?'
  $ semanage fcontext -a -t etc_t /srv/web/httpd.conf

  $ semanage fcontext -l -C
  /srv/web/httpd.conf                                all files          system_u:object_r:etc_t:s0 
  /srv/web/data(/.*)?                                all files          system_u:object_r:httpd_sys_content_t:s0 


Use the :manpage:`restorecon(8)` command to restore the context of a file or
directory tree according to the system policy::

  $ restorecon -v /etc/fstab
  $ restorecon -vR /etc/puppetlabs/


It is also possible to trigger a relabeling of all files with default contexts
by::

  touch /.autorelabel
  reboot


For debugging or during development the :manpage:`chcon(1)` command can be used::

  chcon -t etc_t /srv/web/httpd.conf

.. important:: This is not enough! The next ``restorecon(8)``, relabeling, or system
   redeployment will not honor the changes made with :manpage:`chcon(1)`. Use
   :manpage:`semanage(8)` as described above or change the location of the files
   in question so that they are classified correctly by the system policy.


SELinux Booleans
----------------

SELinux booleans are variables which control certain restrictions enforced by
the SELinux policy. An example would be ``httpd_can_network_connect``, which
controls whether Apache can open network connections.

The state of SELinux booleans is either ``on`` or ``off`` and can be queried
using :manpage:`getsebool(8)`::

  # List all SELinux booleans and their states
  getsebool -a

  # Show the state of a given variable
  getsebool httpd_can_network_connect


The :manpage:`setsebool(8)` command changes the state of a boolean::

  setsebool httpd_can_network_connect on


Puppet development
------------------

All Puppet modules should support SELinux. Modules which do, eg.
``profile::aaa``, must be tested with SELinux systems in enforcing mode.

SELinux configuration is done through ``role::base`` and the ``selinux``
component.
