We are committed to provide service 24 X 7

Deals, Shopping, Training, Tools

Learn how to – Manage SELinux Status, Context, Ports and Booleans Using Ansible

Learn how to – Manage SELinux Status, Context, Ports and Booleans Using Ansible.

What is SELinux and why is it important?

SELinux, Security Enhanced Linux, is a security architecture for Linux. It controls access to applications, files and processes in a Linux system. It uses security policies that define what can or cannot be accessed. For example, if a process or application (termed as a subject) wants to access an object such as a file, SELinux checks against the corresponding rule and determine whether to allow or to deny access.

The traditional Linux security used discretionary access control which defined what users, group and others can own and manipulate and users can change these permissions whenever they like. However, SELinux uses what is called Mandatory access control. Even if some permissions are defined through discretionary access control, if the same permission is not allowed by SELinux, it is not going to be permitted. This is because the policies are administratively set and fixed. This means that if an external user tries to change permissions to access files, the settings of SELinux that prevents such access will forbid the access, making your system generally save. That being said, it is important to keep SElinux in enforcing mode but learn how to manage various policies.

How does SELinux Works?

By default, SELinux uses ‘targeted policy’ and is always ‘enforcing’. Targeted means that only specific (targeted) processes are protected by SELinux. Enforcing status means that SELinux policies are applied accordingly. You can change these settings under /etc/selinux/config file. Other status options are:

  • Permissive – SElinux rules are not applied but operations are logged in case there is a breach
  • Disabled – SELinux policies not applicable

SElinux uses labelling and enforcement. Processes, files etc are labelled with a SELinux context. Files and directories have their labels stored as extended attributes on the filesystem while processes and ports labels are managed by the kernel. Labelling group the resources together such that those with the same labels access each other but are not allowed to access those with different labels. You can work around enabling access for example by changing the SELinux context of the file or process or changing the Boolean status. Booleans are basically the on/off settings of SELinux.

Managing SELinux

You can manually manage SELinux on your Linux System by running the appropriate commands directly on your terminal. Most Linux packages needed for SELinux management are installed by default, but you may need to manually install others for your use. Some packages installed by default include:

  • policycoreutils provides utilities such as restorecon, secon, setfiles, semodule, load_policy, and setsebool, for operating and managing SELinux.
  • selinux-policy provides a basic directory structure, the selinux-policy.conf file, and RPM macros.
  • selinux-policy-targeted provides the SELinux targeted policy.
  • libselinux â€“ provides an API for SELinux applications.
  • libselinux-utils provides the avcstat, getenforce, getsebool, matchpathcon, selinuxconlist, selinuxdefcon, selinuxenabled, and setenforce utilities.
  • libselinux-python provides Python bindings for developing SELinux applications.

Some optional packages that you may need to manually install are as below. Simply run ‘ sudo yum install <package-name>’

  • selinux-policy-devel provides utilities for creating a custom SELinux policy and policy modules.
  • selinux-policy-doc provides manual pages that describe how to configure SELinux altogether with various services.
  • selinux-policy-mls provides the MLS (Multi-Level Security) SELinux policy.
  • Settroubleshot and setroubleshoot-server translates denial messages, produced when access is denied by SELinux, into detailed descriptions that can be viewed with the sealert utility, also provided in this package.
  • mcstrans translates levels, such as s0-s0:c0.c1023, to a form that is easier to read, such as SystemLow-SystemHigh.
  • policycoreutils-python provides utilities such as semanage, audit2allow, audit2why, and chcat, for operating and managing SELinux.
  • policycoreutils-gui provides system-config-selinux, a graphical utility for managing SELinux.

Some of the things you can do include: change SELinux configuration settings, set Boolen on or off, change context of a file/directory and so on. Some of the useful commands include:

# Edit SELinux Configuration file
sudo vim /etc/selinux/config

# List all Booleans
getsebool -a

# Get a specific Boolean
getsebool <Boolean>

# Set a Boolean on or off
setsebool <Boolean> <on|off>
setsebool -P <Boolean> <1|0>

# Get SELinux contect of a file
ls -lZ <path-to-file>

# Change context of a file
chcon -t <context-type> <path-to-file>

# Or simply reference a known good file
chcon –reference <path-to-good-file> <path-to-ile-to-be-changed>

#Restore a directory and all its content to the default context
restorecon -vR <directory-path>

# Set the file context of a file/directory by telling SELinux what it needs to do with the file before enabling the setting with restorecon
semanage fcontext -a -e <existing-directory> <new-directory>

Managing SELinux with Ansible

Ansible is an IT management tool that is useful when working on a number of remote hosts at ago. With Ansible, you can create a single file that defines all the remote hosts you wish to manage and playbooks that contain commands to be executed on the hosts. Ansible uses ssh to access the remote hosts. Let us look at various playbooks that can help us manage SELinux using Ansible.

Changing SELinux States With Ansible

To be able to change SElinux state and policies, we need to install ansible.posix.selinux plugin on the Ansible server. The plugin is part of ansible.posix collection.

$ ansible-galaxy collection install ansible.posix
Process install dependency map
Starting collection install process
Installing 'ansible.posix:1.2.0' to '/home/lorna/.ansible/collections/ansible_collections/ansible/posix'

Now write the playbook to set SELinux in Permissive mode. Am assuming that you already have a host file for the remote hosts to be managed

---
- hosts: all
  tasks:
    - name: Set SELinux to Permissive mode
      ansible.posix.selinux:
        policy: targeted
        state: permissive

Run the playbook

$ ansible-playbook playbook.yml 

PLAY [all] ***********************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [192.168.100.161]

TASK [Set SELinux to Permissive mode] ***********************************************************************************************************************************************************************************************************************
changed: [192.168.100.161]

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
192.168.100.161            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

To change back to enforcing mode;

---
- hosts: all
  tasks:
    - name: Set SELinux to Enforcing Mode
      ansible.posix.selinux:
        policy: targeted
        state: enforcing

To disable SELinux using Ansible:

---
- hosts: all
  tasks:
    - name: Disable SELinux
      ansible.posix.selinux:
        state: disabled

Managing SELinux File Context with Ansible

File context can be updated with chcon, restorecon and semanage. Semanage, however, just tells SElinux what it is required to do with the file/directory anytime there is a change to the file/directory but restorecon does the actual change. When updating manually, use semanage fcontext followed by restorecon to apply the changes. When using targeted policy, file context changes are written to /etc/selinux/targeted/files We require libselinux-python and policycoreutils-python installed on our remote hosts to be able to use ‘semanage’. On the Ansible server, install community.general.sefcontext plugin

$ ansible-galaxy collection install community.general
Process install dependency map
Starting collection install process
Installing 'community.general:3.4.0' to '/home/lorna/.ansible/collections/ansible_collections/community/general'

In our playbook we are going to install the packages needed and look at an example to allow Apache to modify files in /srv/git_repos

---
- hosts: all
  become: yes
  tasks:
    - name: install Required Packages
      yum:
       name:
         - "python3-libselinux"
         - "policycoreutils-python-utils"
       state: present
    - name: Allow Apache to modify files in /srv/git_repos/
      community.general.sefcontext:
        target: '/srv/git_repos(/.*)?'
        setype: httpd_sys_rw_content_t
        state: present
    - name: Apply SELinux file context
      ansible.builtin.command: restorecon -irv /srv/git_repos

Now run the playbook

$ ansible-playbook playbook.yml 

PLAY [all] ***********************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [192.168.100.161]

TASK [install Required Packages] *************************************************************************************************************************************************************************************************************
changed: [192.168.100.161]

TASK [Allow Apache to modify files in /srv/git_repos/] ***************************************************************************************************************************************************************************************
changed: [192.168.100.161]

TASK [Apply SELinux file context] ************************************************************************************************************************************************************************************************************
changed: [192.168.100.161]

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
192.168.100.161            : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Managing SELinux Network Port Type Definitions Using Ansible

To be able to change manage port definitions, we require community.general.seport plugin which is part of community.general collection. I have already shown how to install community.general collection using ansible-galaxy. We also need to install libselinux-python and policycoreutils python modules. Below is a playbook showing various examples of enabling ports.

---
- hosts: all
  become: yes
  tasks:
    - name: install Required Packages
      yum:
       name:
         - "python3-libselinux"
         - "policycoreutils-python-utils"
       state: present
    - name: Allow sshd to listen on tcp port 20222
      community.general.seport:
        ports: 20222
        proto: tcp
        setype: ssh_port_t
        state: present

    - name: Allow memcached to listen on a range of ports
      community.general.seport:
        ports: 10000-10100,10112
        proto: tcp
        setype: memcache_port_t
        state: present

Go ahead and run the playbook

$ ansible-playbook playbook.yml 

PLAY [all] ***********************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [192.168.100.161]

TASK [install Required Packages] *************************************************************************************************************************************************************************************************************
ok: [192.168.100.161]

TASK [Allow sshd to listen on tcp port 20222] ************************************************************************************************************************************************************************************************
changed: [192.168.100.161]

TASK [Allow memcached to listen on a range of ports] *****************************************************************************************************************************************************************************************
changed: [192.168.100.161]

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
192.168.100.161            : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

Managing SELinux Booleans Using Ansible

Booleans are on|off settings of SELinux policies. You can manually display all Booleans and their statuses using getsebool -a command. Once you identify the Boolean that you need to change status you can manually use the command setsebool <Boolean> <on|off>. To manage SELinux Booleans with Ansible, below is a playbook example. Note that we require ansible.posix.seboolean module which is part of ansible.posix collection. Let’s first install the collection.

$ ansible-galaxy collection install ansible.posix
Process install dependency map
Starting collection install process
Skipping 'ansible.posix' as it is already installed

We also need to install libselinux-python and libsemanage-python. The below playbook installs the required packages and sets the boolean httpd_can_connect_ftp to ‘ON’ and enable it persist on reboot.

---
- hosts: all
  become: yes
  tasks:
    - name: Install Required Packages
      yum:
       name:
         - "python3-libselinux"
         - "python3-libsemanage"
       state: present
    - name: Set httpd_can_connect_ftp flag ON and enable it to persist on reboot
      ansible.posix.seboolean:
        name: httpd_can_connect_ftp
        state: yes
        persistent: yes

Upon running the playbook:

$ ansible-playbook playbook.yml 

PLAY [all] ***********************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [192.168.100.161]

TASK [install Required Packages] *************************************************************************************************************************************************************************************************************
ok: [192.168.100.161]

TASK [Set httpd_can_connect_ftp flag ON and enable it to persist on reboot] ******************************************************************************************************************************************************************
changed: [192.168.100.161]

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
192.168.100.161            : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

In this guide, we have learnt what SELinux is and why it is important to keep it enforcing and we have also seen how SELinux works. Most of the time during our operations, we disable SELinux to prevent it from interfering with our Linux operations little do we know that it is actually an important security aspect in Linux. It is important to understand how to manage SElinx instead of totally disabling it.

Best Courses to Learn Ansible Automation:

I hope this guide has helped you to appreciate the importance of SELinux and has taught you how to play around SELinux policies to suit your setup needs. Check more interesting guides below:

Cart

Your Cart is Empty

Back To Shop