How to Install SELinux on Ubuntu Linux

Security-Enhanced Linux (SELinux) delivers mandatory access control (MAC) security at the kernel level, enforcing strict policy rules that limit system processes and users beyond traditional discretionary access control. Originally developed by the NSA and widely used in Red Hat Enterprise Linux and Fedora, SELinux provides fine-grained control over process interactions with files and resources, comprehensive audit logging for security monitoring, and tailored policies that safeguard against both external and internal threats.

However, Ubuntu defaults to AppArmor for mandatory access control, but SELinux offers an alternative for administrators migrating from RHEL-based systems or requiring SELinux-specific policy frameworks. Additionally, this guide covers installing SELinux on Ubuntu, disabling AppArmor to prevent Linux Security Module conflicts, and configuring enforcement modes for production or testing environments.

SELinux significantly alters system behavior and can render services inaccessible if misconfigured. Before proceeding on production servers, ensure you have console access or an alternative recovery method beyond SSH, and consider testing in a virtual machine first. Always start with permissive mode to identify potential issues before switching to enforcing mode.

Disable AppArmor to Prevent Conflicts

Before installing SELinux, you must disable AppArmor since both are Linux Security Module (LSM) frameworks that compete for the same kernel hooks. Only one LSM can actively enforce policies at a time, so running both simultaneously causes conflicts. Ubuntu ships with AppArmor enabled by default, making this step essential for SELinux operation.

First, check if AppArmor is currently active on your system:

sudo systemctl status apparmor

Then, if AppArmor is running, disable it permanently to allow SELinux to take over access control enforcement:

sudo systemctl disable apparmor --now

Install SELinux Packages via APT

After disabling AppArmor, install the full SELinux toolchain with APT (Ubuntu’s package manager, similar to Windows Update). The policycoreutils, selinux-utils, and selinux-basics packages provide the management utilities and helper scripts, while selinux-policy-default supplies the actual SELinux policy database that Ubuntu needs to boot in enforcing mode. Add auditd as well so kernel denials get logged to /var/log/audit/audit.log for troubleshooting.

Install everything with a single command:

sudo apt install policycoreutils selinux-utils selinux-basics selinux-policy-default auditd

Once installation completes, Ubuntu creates the SELinux configuration directory, loads the default policy set, and enables the audit daemon required for later diagnostics.

Activate SELinux on Boot

Following package installation, you need to activate SELinux so it loads automatically during system startup. This activation step modifies your boot configuration to initialize the SELinux subsystem before other services start, enabling its security features from the earliest stages of the boot process.

Run the activation command with root privileges:

sudo selinux-activate

As a result, this command updates your system configuration to load SELinux during boot.

Keep SELinux Permissive During Initial Boot

After activation, leave SELinux in permissive mode for the first reboot so Ubuntu can relabel the filesystem without denying services. Permissive mode still logs policy violations, giving you a chance to review /var/log/audit/audit.log and confirm that critical daemons such as SSH, web servers, and database services run cleanly before enforcing access rules.

This cautious approach aligns with the earlier warning: test policies safely, build any needed custom modules, then switch to enforcing mode once audit logs show only expected activity.

Reboot to Apply SELinux Configuration

SSH connections to remote servers may be disrupted when switching to enforcing mode if SELinux policies restrict sshd_t domain access. For production servers, test in permissive mode first and monitor audit logs for SSH-related denials before enforcing policies. Additionally, maintain console access or have a recovery plan ready in case SSH becomes inaccessible.

Finally, to complete the setup, reboot your system so all configuration changes take effect. During the reboot process, SELinux will relabel the entire filesystem with appropriate security contexts, which typically takes 5-30 minutes depending on disk size and file count. Systems with millions of files may require significantly longer relabeling time.

Now, reboot the system:

sudo reboot

After the reboot completes, SELinux runs in permissive mode so you can verify services, relabel files, and review audit logs without blocking traffic. The following sections cover configuration customization and troubleshooting common issues before you enable enforcing mode later.

Configure SELinux Settings

Understanding SELinux Operational Modes

Specifically, SELinux operates in three distinct modes, each offering different levels of policy enforcement:

  • Enforcing Mode: Actively enforces security policies and denies access violations. This is the production-ready mode that provides full protection.
  • Permissive Mode: Logs policy violations without blocking them. Use this mode for testing policies or troubleshooting access issues without disrupting services.
  • Disabled Mode: Completely turns off SELinux with no policies applied or violations logged.

Edit SELinux Configuration File

To change SELinux modes or policy types, edit the main configuration file located at /etc/selinux/config. Open it with your preferred text editor:

sudo nano /etc/selinux/config

Then, within the file, modify the SELINUX line to set your preferred operational mode. For example, to enable enforcing mode:

SELINUX=enforcing

Apply Configuration Changes with Reboot

After saving changes to the configuration file, reboot your system for them to take effect:

sudo reboot

Additional SELinux Configuration Options

Beyond the operational mode, SELinux offers additional configuration options to customize behavior:

  • SETLOCALDEFS: Determines the use of locally defined file contexts. To use default contexts, set this to 0. Modify the /etc/selinux/config file accordingly:
SETLOCALDEFS=0
  • SELINUXTYPE: Sets the policy type. Ubuntu and Debian ship the default policy tree (plus the optional MLS variant), so leave this value set to default unless you build or install an alternative policy yourself. Update the configuration file accordingly:
SELINUXTYPE=default

Configure SELinux for Web Servers

In addition, web servers require specific SELinux configuration to allow HTTP and HTTPS traffic. The following examples demonstrate how to configure policies for Apache, Nginx, or other web services running on Ubuntu.

Install SELinux Management Tools

First, install the policycoreutils-python-utils package, which provides the semanage command for managing policies:

sudo apt install policycoreutils-python-utils

Allow Custom Web Server Ports

By default, SELinux allows web servers to bind to standard HTTP (80) and HTTPS (443) ports. However, if you need to run a web server on a custom port like 8080, you must explicitly add it to the allowed port list.

First, check currently allowed HTTP ports:

sudo semanage port -l | grep http_port_t

Next, add port 8080 for HTTP traffic:

sudo semanage port -a -t http_port_t -p tcp 8080

Additionally, this command uses the -a flag to add a new port assignment. If you need to modify an existing port binding instead, use the -m flag. The -t http_port_t parameter specifies the SELinux type for HTTP ports, while -p tcp 8080 defines the protocol and port number.

Configure Network Access for Web Applications

Additionally, web applications like WordPress often need network connectivity to download updates, connect to external APIs, or send email. Enable the httpd_can_network_connect boolean to allow these connections:

sudo setsebool -P httpd_can_network_connect 1

Specifically, the -P flag makes this change persistent across reboots.

Set File Contexts for Web Content

In particular, SELinux uses file contexts to determine what processes can access specific files. Define those contexts with semanage fcontext so they survive reboots and filesystem relabels, then apply them with restorecon:

sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/html/wp-content(/.*)?'
sudo restorecon -RFv /var/www/html/wp-content

Leave wp-config.php with the default httpd_sys_content_t label so Apache or PHP-FPM cannot rewrite your database credentials. If you edit the file and the context changes, run sudo restorecon -v /var/www/html/wp-config.php to reapply the secure default.

Alternatively, for custom web directories outside the standard /var/www path, map the correct context pattern and relabel the directory tree:

sudo semanage fcontext -a -t httpd_sys_content_t '/opt/myapp(/.*)?'
sudo restorecon -Rv /opt/myapp

Enable Additional Web Server Capabilities

Additionally, depending on your application requirements, you may need to enable additional SELinux booleans:

For example, allow the web server to send email (required for contact forms, password resets):

sudo setsebool -P httpd_can_sendmail 1

Additionally, enable FTP access for web server components (when PHP scripts or reverse proxies need to push files over FTP):

sudo setsebool -P httpd_enable_ftp_server 1

As a result, this boolean permits Apache, Nginx FastCGI, or PHP-FPM contexts to establish FTP sessions while keeping the FTP daemon confined, avoiding the broad access that allow_ftpd_full_access would grant.

Verify SELinux Status

Check Current Enforcement Mode

After rebooting your Ubuntu system, start by checking the current enforcement mode with a simple one-word status command:

getenforce

Specifically, this displays a single-word response indicating the active mode: Enforcing, Permissive, or Disabled. This quick check confirms whether SELinux is actively blocking violations (Enforcing) or only logging them (Permissive).

View Detailed SELinux Status

For comprehensive information about your SELinux configuration, use the detailed status command:

sestatus

Additionally, this command displays comprehensive details including the current operational status, active mode (enforcing, permissive, or disabled), loaded policy type, policy version, and whether the policy was loaded from the configuration file. Compare this output with your settings in /etc/selinux/config to confirm everything matches your intended configuration.

Understanding SELinux Mode Differences

SELinux operates in three distinct modes, each serving different purposes for security and troubleshooting:

ModeBehaviorUse Case
EnforcingActively blocks policy violations and logs denialsProduction systems requiring active security enforcement
PermissiveLogs policy violations without blocking themTesting policies, troubleshooting access issues, policy development
DisabledSELinux is completely inactive, no logging or enforcementTemporary diagnostic purposes or complete removal

Alternatively, use getenforce to check the current active mode quickly, or sestatus to see both the current mode and the boot configuration mode, which can differ if changed with setenforce since the last reboot.

Enable Enforcing Mode After Validation

Once audit logs show no unexpected denials and services operate normally in permissive mode, switch SELinux to enforcing mode for full protection. This timing ensures legitimate workloads are covered by the right file contexts, booleans, and custom policy modules before SELinux starts blocking traffic.

Update the SELinux configuration so it boots directly into enforcing mode:

sudo selinux-config-enforcing

Then reboot to apply the change and verify the system still passes your functional tests:

sudo reboot

After the reboot, rerun getenforce or sestatus and monitor /var/log/audit/audit.log. Any new denials should be addressed immediately to keep security tight without disrupting production workloads.

Troubleshoot SELinux Issues

When applications fail after enabling SELinux, systematic troubleshooting helps identify whether policy violations cause the problem. The following techniques isolate SELinux-related issues and provide solutions for common scenarios.

Restore Correct File Contexts

Incorrect file contexts frequently cause SELinux to deny access, preventing applications from reading or writing required files. The restorecon command resets contexts to their default values based on installed policies.

Therefore, to fix file contexts in a web directory:

sudo restorecon -Rv /var/www/html

Additionally, the -R flag applies changes recursively to all files and subdirectories, while -v provides verbose output showing each file that gets relabeled.

Test with Permissive Mode

When troubleshooting application failures, temporarily switching to permissive mode helps determine whether SELinux policies cause the issue. In permissive mode, violations are logged but not enforced, allowing you to observe which actions would normally be blocked.

Then, switch to permissive mode temporarily:

sudo setenforce 0

Test your application to see if the issue disappears. If it does, SELinux policies are the cause. After testing, return to enforcing mode:

sudo setenforce 1

This command is temporary and only lasts until the next reboot. For permanent changes, edit /etc/selinux/config as described earlier.

Analyze SELinux Audit Logs

SELinux logs all policy violations to /var/log/audit/audit.log, providing detailed information about what was denied and why. Examining these logs reveals the specific policies blocking your application.

This log file is maintained by the auditd service installed earlier. If /var/log/audit is missing, confirm the daemon is running and enable it:

sudo systemctl enable --now auditd

Next, view recent audit log entries:

sudo tail /var/log/audit/audit.log

Then, search for entries containing “denied” or “AVC” (Access Vector Cache) to identify specific violations:

sudo grep 'denied' /var/log/audit/audit.log

Create Custom Policy Modules

When legitimate application behavior triggers policy violations, you can generate a custom policy module using audit2allow. This tool analyzes audit logs and creates policy rules to permit the denied actions.

Next, generate and install a custom policy module:

sudo grep 'denied' /var/log/audit/audit.log | audit2allow -M mycustommodule
sudo semodule -i mycustommodule.pp

The first command extracts denied entries from the audit log and generates a policy module named “mycustommodule”. The second command installs this policy, allowing the previously denied actions. Use this approach carefully, as overly permissive custom policies can reduce security effectiveness.

Manage SELinux Booleans

SELinux booleans provide simple on/off switches for common policy adjustments without requiring custom modules. They control specific functionalities like network access, email sending, or database connections.

To begin, list all available booleans and their current states:

sudo getsebool -a

Then, to change a boolean value, such as allowing the web server to make network connections:

sudo setsebool -P httpd_can_network_connect 1

Importantly, the -P flag makes the change persistent across reboots. Without it, the boolean reverts to its default value after restarting.

Conclusion

Overall, SELinux provides mandatory access control at the kernel level with fine-grained policy enforcement and comprehensive audit logging. Installation on Ubuntu requires disabling AppArmor, installing the SELinux packages, activating the subsystem, and rebooting so the filesystem can be relabeled. Keep the system in permissive mode while you review audit logs, tune file contexts, and enable only the booleans your workloads need, then switch to enforcing mode once tests look clean. At that point Ubuntu benefits from SELinux’s default policy framework, limiting process capabilities and logging violations for continuous monitoring.

Leave a Comment