SELinux (Security-Enhanced Linux) was [created by the NSA](https://en.wikipedia.org/wiki/Security-Enhanced_Linux#Overview) to add stronger access control to Linux. It uses [Mandatory Access Control (MAC)](https://csrc.nist.gov/glossary/term/mandatory_access_control) to define what each program can access, which means stricter security controls than traditional user permissions. For those short on time, here's a [NotebookLM](https://notebooklm.google.com/) one-click podcast created from this write-up. ![](c3bfc79ac4ce0e7b648303cd2bf28467_MD5.wav) # Setting up SELinux SELinux needs to be configured properly before it can be enforced on a system. ## Config SELinux configuration is controlled by the `/etc/selinux/config` file. The *uncommented* lines should look something like this: ```conf SELINUX=enforcing SELINUXTYPE=targeted ``` - `SELINUX=enforcing`: Ensures that SELinux runs in enforcing mode. - `SELINUXTYPE=targeted`: The most common policy, targeting a specific set of services. You can check the current status of SELinux enforcement with the `getenforce` or `sestatus` commands. ## Grub We should also ensure that the bootloader is configured to load SELinux policies. As a handy trick, instead of directly editing GRUB's config file, you can use `grubby` to manage GRUB command line options. ```bash grubby --update-kernel=ALL --args="selinux=1 security=selinux enforcing=1" ``` If you ever need to remove the parameters again, you can run this: ```bash grubby --update-kernel=ALL --remove-args="selinux=1 security=selinux enforcing=1" ``` In either case, remember to update grub: ```bash update-grub ``` And, finally, reboot the system for changes to take effect. # Modes SELinux operates in three different modes. Each mode determines how SELinux enforces its policies on the system. ## Disabled In this mode, SELinux is completely turned off. No policies are enforced, and the system operates as if SELinux is not installed. This should be avoided unless absolutely necessary, as it removes the security benefits of SELinux. In other words, please [stop disabling SELinux](https://stopdisablingselinux.com/). That doesn't mean disabling it can't be handy and you should never do it, however. I often find it handy to run a quick `setenforce 0` to drop to permissive mode while I work on installing new software to make sure any issues I encounter are due to the software or my own incompetence rather than SELinux itself. After the install is done, I will set the system back with `setenforce 1` and verify everything is still working. Then, I use the SETroubleshoot daemon to check for and correct any errors. To disable SELinux for the current boot, simply run `setenforce 0`. To disable it permanently, modify `/etc/selinux/config`: ```conf SELINUX=disabled ``` ## Enforcing This is the default and most secure mode. In enforcing mode, SELinux policies are actively applied, and any actions not explicitly allowed by a policy are blocked. To enable SELinux for the current boot, just run `setenforce 1`. To enable it permanently, modify `/etc/selinux/config`: ```conf SELINUX=enforcing ``` This should be your configuration for the vast majority of your system's life. If it's not, please re-evaluate your configuration and try to understand why and what you can do to fix it. ## Permissive In permissive mode, SELinux policies are loaded, but violations are not enforced, but they are still logged. This is useful for troubleshooting and fine-tuning policies without disrupting the system. To set SELinux to permissive mode for the current boot, just run `setenforce 0` and ensure your boot parameters have SELinux enabled. To set it to permissive permanently, modify `/etc/selinux/config`: ```conf SELINUX=permissive ``` This would be a very strange thing to do permanently, but it is just a tiny bit more secure than disabled at least, so there's that. # Rules SELinux policies (rules) can be adjusted using a few key tools. These allow you to manage permissions, contexts, and make temporary or permanent changes to how the system behaves. ## Setsebool `setsebool` is used to enable or disable SELinux Booleans. Booleans are toggles for various common SELinux settings ([based on the software you have installed](https://unix.stackexchange.com/questions/599380/list-only-the-active-selinux-booleans)) that allow you to adjust the behavior of specific services without needing to change entire policies. To check the status of booleans, use `getsebool -a` or `semanage boolean -l`. The latter command gives more information as to what, exactly, each boolean is supposed to allow or disallow. To enable a boolean **for the current boot**: ```bash setsebool httpd_can_network_connect on ``` To enable a boolean **permanently**: ```bash setsebool -P httpd_can_network_connect on ``` ## Chcon / Fcontext `chcon` (change context) is used to change the SELinux security context of files and directories. This is one of the more frequent commands you'll be running when fixing eg. file access denials on a system. For example, to set the context for a web directory **for the current boot**: ```bash chcon -R -t httpd_sys_content_t /var/www/html ``` And to set **the default context** for that same directory: ```bash semanage fcontext -a -R -t httpd_sys_content_t /var/www/html ``` > [!note] > Fcontext doesn't actually apply the changes until you run `restorecon`, detailed below. It's changing the default context, not setting the current context. ## Audit2allow When SELinux denies an action, it logs the denial in the audit logs. `audit2allow` is a tool that can analyze those logs and generate rules to allow the previously denied actions. First, search for denials related to a specific process or service: ```bash ausearch -c 'process_name' --raw | audit2allow -M my_policy ``` For example, to handle denials for the `hostname` command: ```bash ausearch -c 'hostname' --raw | audit2allow -M my-hostname ``` Then apply the generated policy: ```bash semodule -X 300 -i my-hostname.pp ``` ## Restorecon `restorecon` is used to restore the default SELinux security context for files and directories based on the current policy. This is especially useful after restoring files from a backup or moving them to a new location, or when changing the default context via the `fcontext` subcommand described above. To recursively restore contexts for a directory: ```bash restorecon -Rv /var/www/html ``` # Troubleshooting When SELinux issues arise, knowing how to troubleshoot them effectively is essential. SELinux provides various tools to help identify and fix problems. ## CLI Tools Several command-line tools are useful for troubleshooting SELinux: - `sestatus`: Check the current status of SELinux, including the mode and policy being used. `getenforce` is similar, but only provides the current mode. - `getsebool`: View the status of SELinux booleans, which can control specific behaviors. - `semanage`: Manage SELinux settings, including file contexts and booleans. - `sealert`: A helpful command provided by `setroubleshoot`. Gives you human-readable summaries of SELinux denials. ## SETroubleshoot `setroubleshootd` provides real-time notifications and human-readable explanations for SELinux denials. It can be extremely helpful when diagnosing issues. As its name implies, it runs as a daemon, usually under the `setroubleshootd` system service. To install `setroubleshoot`: ```bash dnf install setroubleshoot ``` After installation, SELinux denials will be logged in `/var/log/messages` with a summary and recommended fix. For example, you might see: ``` SELinux is preventing /usr/sbin/httpd from name_connect access on the tcp_socket port 80. ``` `setroubleshoot` will often suggest solutions, such as running `setsebool` to adjust a boolean or using `audit2allow` to create a policy exception. You can see these alerts and fix suggestions in a nice GUI (or CLI depending on your setup) by running `sealert`. ![](a653e65f7d28caab5bb96f0d87259251_MD5.png) ## Autorelabel Sometimes, eg. after restoring your system from a backup or making significant changes to the system, SELinux contexts can become out of sync. You can fix this by relabeling the filesystem. To trigger a full system relabel on the next boot, create the `/.autorelabel` file: ```bash touch /.autorelabel ``` Then reboot the system, and SELinux will automatically relabel the entire filesystem based on the current policy. This is also useful because it can be much easier than running a lot of `restorecon` commands.