Troubleshooting SELinux explained with Booleans

This tutorial explains how to list, enable and change SELinux Booleans in Linux step by step with practical examples. Learn SELinux Boolean types, SELinux Boolean configuration, SELinux Boolean commands (setsebool, getsebool, sealert and ausearch) and SELinux message tag (type=AVC) in detail.

SELinux Booleans are just like a switch which can be on or off as per requirement. SELinux provides several ready to use Booleans to secure the default Linux environment.

For this tutorial, I assume that you are familiar with basic concepts of SELinux. If you want to learn SELinux from scratch please go through the first part of this tutorial which explains basic concepts of SELinux such as SELinux modes, SELinux policy, SELinux context and how to run web server with SELinux in detail with examples. You can read first part of this tutorial here: -
SELinux Explained with Examples in Easy Language

How to list SELinux Booleans

To view all available Booleans in system we can use getsebool -a command.

getsebool command

Above command will list all Booleans with their current status.

To view the status of a single Boolean we have to specify its name with getsebool command.

#getsebool ftp_home_dir
ftp_home_dir -->off

We can also use grep command with getsebool to find out the Booleans associated with a specific service. For example, to find out the Booleans associated with FTP service we can use following command: -

getsebool command with grep command

To get more detailed information about available Booleans such as their current status, default status and description we can use following command

#semanage boolean -l

Just like getsebool command, we can also use this command with grep command to filter the list.

semanage command

How to change SELinux Booleans

SELinux Booleans are SELinux policy setting. A SELinux Boolean can be either on or off. If Boolean is on, SELinux will permit the associate action. If Boolean is off, SELinux will deny the associate action.

To change the Boolean setting we can use setsebool command. To enable a Boolean, we can use “on” or “1” option with this command. For example, to enable ftp_home_dir Boolean we can use any one of following commands

#setsebool ftp_home_dir on
#setsebool ftp_home_dir 1

Both commands will activate the Boolean ftp_home_dir.

In same manner to disable a Boolean, we can use “off” or “o” option with this command. For example, to disable the same Boolean we can use any one of following commands.

#setsebool ftp_home_dir off
#setsebool ftp_home_dir o

Following figure illustrates the use of setsebool command.

setsebool command

Above commands update Boolean setting in run time. Change made with above commands will not preserve after the reboot. To make a change permanent we have to use -P option. For example, following command will activate ftp_home_dir Boolean permanently.

#setsebool -P ftp_home_dir on

SELinux Booleans Directory

SELinux Booleans settings are stored in /sys/fs/selinux/booleans directory.

selinux boolean directory

When we change any Boolean setting, associate file in this directory get updated automatically. To understand it more practically let’s change the setting of ftp_home_dir Boolean and view the associate file.

Following figure illustrates this practice step by step: -

change selinux boolean

SELinux Boolean Practical Examples

Since Booleans don’t require any specific knowledge we can easily use them to change the behavior of services. No matter what the permission a service has, if the object is protected by Boolean, service will not be able access the object. Let’s understand it with an example.

In a web development company Apache web server is configured to serve websites from user’s home directory. Now suppose for some reason we are asked to block the web server from accessing user’s home directory. We have two options here; either we change apache configuration or put a protective layer between apache and home directory.

For this tutorial let’s assume that we are stepped in the world of Linux and do know anything about Apache configuration files. In this situation SELinux Booleans are life saver for us. We will use SELinux Boolean to protect the user’s home directory.

LAB Setup

For this tutorial, I assume that httpd (Apache web server) service is installed and running on test system.

httpd status running

By default, apache is not configured to access the user’s home directory. Necessary configuration is stored in /etc/httpd/conf.d/userdir.conf file. Let’s take the backup of this file and open it for editing.

backup userdir.conf  file

Update the UserDir directive as shown in following figure.

update userdir.conf file

Now do the following: -

  • Restart the httpd service.
  • Switch to a normal user account.
  • Create a public_html directory in home directory of the user.
  • Create an index.html file in public_html folder with some dummy content.
  • Change home directory permission to 711.
  • Exit from normal user account.

Following figure illustrates above steps

create index.html file in home directory

If SELinux mode is set to disable or permissive, we should be able to access the test web page (index.html) from browser. But if it is set to enforcing, we should not be able to access the web page.

In our test system, SELinux mode is set to enforcing. Let’s try to access the web page from browser.

http access deined

As above output confirms, we are not allowed to access the webpage from user’s home directory. To figure out which Boolean is protecting home directory, we can use following command.

getsebool homedir

As we can see there is a Boolean between web server and user home directory. If we enable this Boolean, web server will get what permission it has on home directory. If we keep this Boolean off, no matter what permission web server has, it will not be able to access the home directory.

enable_homedir_http boolean

Exercise for you

Enable and disable httpd_enable_homedir Boolean and see the result in web browser. To access webpage from home directory use following URL: -

Server IP/~UserName/WebPage

Here server IP is the IP address of your computer, UserName is name of user and WebPage is the name of file which you have created in user’s home directory.

After practice always restore the original configuration file (userdir.conf) back to its default location.

#cp /etc/httpd/conf.d/userdir.conf.bk /etc/httpd/conf.d/userdir.conf

Troubleshooting SELinux

SELinux logs each activity in /var/log/audit/audit.log file with a type=AVC (Access Vector Cache) tag. To view all SELinux messages on screen we can use following command

#grep AVC /var/log/audit/audit.log

We can also redirect these massages in a file for further investigation with following command

#grep AVC /var/log/audit/audit.log > selinux-log-file-name

In above command selinux-log-file-name is name of file where we want to store the filtered messages.

In SELinux troubleshooting we should always use these messages at first place. Let’s take a closer look at single SELinux message from this file

grep avc audit.log

To understand it more clearly, let's break this message in seven parts.

  1. First part is used to keep this message separate from other logs. It includes two pieces of information; message tag and message ID.
    • SELinux uses message tag (type=AVC) to keep its logs separate from others, since this file is also used to store the logs from other services.
    • The daemon (auditd) which controls this file uses message ID to keep separates logs from each other’s.
  2. Second part tells us what exactly happened. As we can see in output a read request was denied for process ID 12829.
  3. Third part provides more information about the process. In this process, the command “ifconfig” tried to read the file from path “/run/vmware-active-nics”.
  4. Fourth part provides the information about devices involve in this process.
  5. Fifth part provides information about the source context settings.
  6. Sixth part provides information about the target context setting.
  7. Last part provides information about target object type. In this case target object is the file.

Let’s put all these together in simple words

The (source) command “ifconfig” (which type context is set to ifconfig_t) tried to access the (target) file “/run/vmware-active-nics” (which type context is set to var_run_t) under the process ID 12829. Since the type context of source (ifconfig_t) and target (var_run_t) did not match, SELinux denied the request. This action was logged under the message ID (audit) 1491204584 in /var/log/audit/audit.log file.

If you still find it hard to read the SELinux messages from audit log, you can use sealert package. The sealert package provides several enhanced tools for SELinux troubleshooting.

To install this package use following command: -

#yum -y install setroubleshoot-server

Once package is installed restart the system

#reboot –f

After reboot whenever an SELinux message is written in audit.log file, a simplified version of same message is also written in /var/log/messages.

For example following figure illustrates the same SELinux message from /var/log/messages which we have seen from audit.log file in above example.

grep selinux var log messages

As we can see in above output, this time message has more clarity about the specific action taken by SELinux. This message also suggests us to run sealert –l command with a unique number.

Basically sealert automatically analyzes the message which triggered the SELinux alert and stores the result with a unique message ID. We can view this result with sealert –l [message ID] command.

Let’s run the suggested command. You may use copy and paste option.

sealert - l command

The output of above command contains nearly all information which we need to troubleshoot the associated issue. Usually it contains: -

  • Formatted message in easy to understand language
  • Actual message
  • SELinux mode
  • SELinux current configuration
  • Additional information including hardware and software
  • Possible fix of problem with confidence scores (Higher score has higher chance to solve the problem. But since these are only the suggestions, there is no guarantee of success).

Following figure illustrates the output of above command.

sealert command output

The ausearch command

SELinux messages can be stored on several locations for examples: -

  • If auditd daemon is running, SELinux will log the messages in /var/log/audit/audit.log file.
  • If auditd daemon is not running, SELinux will use the rsyslog daemon to log the messages in /var/log/messages.
  • If auditd daemon and sealert both are running, SELinux message will be written on both files; /var/log/audit/audit.log and /var/log/messages
  • Besides this, we can also customize the SELinux to use the custom location for logs.

So whenever we don’t know where the SELinux messages are stored or we want to check all possible locations, we can use ausearch command. Instead of a particular file, this command searches for SELinux messages on all possible locations. For example following command will search all SELinux messages associated with httd process on all possible locations.

auserch command

That’s all for this article. I hope you have enjoyed this tutorial. In next tutorial I will explain another Linux tutorial with examples.

ComputerNetworkingNotes Linux Tutorials Troubleshooting SELinux explained with Booleans