How to Install SELinux on Ubuntu (26.04, 24.04, 22.04)

Last updated Thursday, February 19, 2026 1:48 pm Joshua James 13 min read

Security-Enhanced Linux (SELinux) is a kernel-level mandatory access control (MAC) framework that enforces strict policy rules well beyond standard Linux file permissions. Installing SELinux on Ubuntu gives administrators the fine-grained process isolation and file context controls familiar to RHEL and Fedora environments — useful for CIS benchmark compliance, multi-level security policies, and environments that require the same policy model across RHEL and Ubuntu servers. Ubuntu 22.04 LTS, 24.04 LTS, and 26.04 LTS all ship SELinux packages in the default repositories. Originally developed by the NSA, SELinux confines each process to a defined domain, logs every policy denial to an audit trail, and supports complex multi-level security policies that AppArmor cannot replicate.

Ubuntu defaults to AppArmor on Ubuntu for mandatory access control, so switching requires disabling AppArmor first since only one Linux Security Module can actively enforce policies at a time. Disabling AppArmor, installing the SELinux packages, running selinux-activate, and rebooting for the initial filesystem relabel results in a working SELinux installation in permissive mode, ready to tune before switching to enforcing mode.

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.

Update Ubuntu Before Installing SELinux

Update the package index and apply any pending upgrades before installing SELinux to ensure the packages build against the latest kernel and base system libraries:

sudo apt update && sudo apt upgrade -y

All commands in this guide require sudo privileges. If your account does not have sudo access yet, follow our guide to add a user to sudoers on Ubuntu before continuing.

Disable AppArmor on Ubuntu Before Installing SELinux

Disabling AppArmor on Ubuntu is required because both AppArmor and SELinux are Linux Security Module (LSM) frameworks that compete for the same kernel hooks. Only one LSM can actively enforce policies at a time, so Ubuntu’s default AppArmor installation must be stopped before SELinux can take over.

Check whether AppArmor is currently active:

sudo systemctl status apparmor
● apparmor.service - AppArmor initialization
     Loaded: loaded (/lib/systemd/system/apparmor.service; enabled; vendor preset: enabled)
     Active: active (exited) since Mon 2025-01-15 12:00:00 UTC; 5min ago

If AppArmor is active, disable it permanently so SELinux can take over access control enforcement:

sudo systemctl disable apparmor --now

Install SELinux on Ubuntu

Install the full SELinux toolchain with a single APT command. The policycoreutils, selinux-utils, and selinux-basics packages provide management utilities and helper scripts, while selinux-policy-default supplies the policy database Ubuntu needs to boot in enforcing mode. Including auditd ensures kernel denials are logged to /var/log/audit/audit.log for troubleshooting:

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

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

Activate SELinux on Ubuntu

After installing the packages, run selinux-activate to write the SELinux parameters into the GRUB bootloader configuration so the kernel loads the security module on every subsequent boot:

sudo selinux-activate
Activating SE Linux
SE Linux is activated.  You may need to reboot now.

Reboot Ubuntu to Apply SELinux Changes

Leave SELinux in permissive mode for this first reboot. Permissive mode still logs every policy violation to /var/log/audit/audit.log without blocking anything, giving you a chance to confirm that critical services such as SSH, web servers, and databases start cleanly before enforcing access rules. Once audit logs show only expected activity, you can switch to enforcing mode.

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

Reboot the system to trigger the initial filesystem relabeling. This process assigns SELinux security contexts to every file and can take 5-30 minutes on systems with large numbers of files:

sudo reboot

After the reboot, SELinux runs in permissive mode. The following sections cover configuration customization and troubleshooting common issues before you enable enforcing mode.

Configure SELinux on Ubuntu

SELinux Operational Modes

SELinux operates in three modes. The table in the Verify SELinux Status section explains each one in detail, but in brief:

  • Enforcing: actively blocks policy violations and logs denials.
  • Permissive: logs violations without blocking them. Use this while tuning policies.
  • Disabled: SELinux is completely off with no logging or enforcement.

Edit the SELinux Configuration File

The main configuration file at /etc/selinux/config controls the active mode and policy type. Open it with your preferred text editor:

sudo nano /etc/selinux/config

The file created by selinux-activate contains these directives:

# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=permissive

# SELINUXTYPE= can take one of these two values:
# default - equivalent to the old strict and targeted policies
# mls     - Multi-Level Security (for military and educational use)
SELINUXTYPE=default

# SETLOCALDEFS= Check local definition changes
SETLOCALDEFS=0

Modify the SELINUX line to change the active mode. Set it to enforcing for full protection, permissive for logging-only mode, or disabled to turn SELinux off entirely. Save the file and reboot for changes to take effect.

The other two directives are explained below:

  • SELINUXTYPE: Sets the policy type. Ubuntu ships the default policy tree (plus an optional mls variant). Leave this set to default unless you build or install an alternative policy yourself.
  • SETLOCALDEFS: Controls whether locally defined file contexts override the policy. The value 0 uses standard policy contexts; leave it at the default.

Apply Configuration Changes

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

sudo reboot

Disable SELinux on Ubuntu

To disable SELinux entirely, set the SELINUX line in /etc/selinux/config to disabled and reboot. After restarting, verify SELinux is off:

getenforce
Disabled

Disabling SELinux removes all mandatory access control protection. Re-enabling it later requires running sudo selinux-activate again and rebooting for a full filesystem relabel. Use permissive mode for troubleshooting instead of disabling SELinux whenever possible.

Configure SELinux for Web Servers on Ubuntu

Web servers require specific SELinux configuration to allow HTTP and HTTPS traffic. The examples below show how to configure policies for Apache on Ubuntu, Nginx on Ubuntu, 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
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000

Next, add port 8080 for HTTP traffic:

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

This command uses the -a flag to add a new port assignment. To modify an existing binding instead, use -m. The -t http_port_t parameter specifies the SELinux type for HTTP ports; -p tcp 8080 sets the protocol and port number.

Configure Network Access for Web Applications

Web applications like WordPress on Ubuntu 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

The -P flag makes this change persistent across reboots.

Set File Contexts for Web Content

SELinux uses file contexts to determine which processes can access specific files. Define 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

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

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

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 on Ubuntu

Check Current SELinux Mode

After rebooting, check the active enforcement mode with a quick one-word status command:

getenforce
Permissive

The response is a single word: Enforcing, Permissive, or Disabled. This confirms whether SELinux is actively blocking violations or only logging them.

View Detailed SELinux Status

For the full picture of your SELinux configuration, use sestatus:

sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux mount check:            enabled
Loaded policy name:             default
Current mode:                   permissive
Mode from config file:          permissive
Policy MLS status:              disabled
Policy deny_unknown status:     allowed
Max kernel policy version:      33

sestatus shows both the current active mode and the mode stored in /etc/selinux/config. These can differ if you changed the mode at runtime with setenforce since the last reboot. Compare both values to confirm the system reflects your intended configuration.

SELinux Mode Reference

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

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 SELinux Enforcing Mode on Ubuntu

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 have the right file contexts, booleans, and custom policy modules in place before SELinux starts blocking traffic.

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

sudo selinux-config-enforcing

Reboot to apply the change and verify services continue to pass functional tests:

sudo reboot

After the reboot, confirm enforcing mode is active and watch the audit log for any new denials:

getenforce
Enforcing

Monitor /var/log/audit/audit.log immediately after enabling enforcing mode. Any new denials should be addressed promptly to keep security tight without disrupting production workloads.

Troubleshoot SELinux on Ubuntu

When applications fail after enabling SELinux, systematic troubleshooting helps identify whether policy violations are the cause. The techniques below isolate SELinux-related issues and resolve the most 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.

To fix file contexts in a web directory:

sudo restorecon -Rv /var/www/html

The -R flag applies changes recursively to all files and subdirectories; -v provides verbose output showing each file that gets relabeled.

Test with Permissive Mode

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

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 change is temporary and reverts to the configured mode at the next reboot. For a permanent change, edit /etc/selinux/config as described earlier.

Analyze SELinux Audit Logs

SELinux logs all policy violations to /var/log/audit/audit.log, maintained by the auditd service installed earlier. If /var/log/audit is missing, start the daemon:

sudo systemctl enable --now auditd

View recent audit log entries with the tail command:

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

Search for entries containing denied or AVC (Access Vector Cache) to identify specific violations using the grep command:

sudo grep 'denied' /var/log/audit/audit.log
type=AVC msg=audit(1700000000.000:100): avc:  denied  { read } for  pid=1234 comm="nginx" name="config" dev="sda1" ino=123456 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=0

Each denied entry shows the process (comm), the denied action, and the source/target security contexts. Use these details to determine whether a file context fix (restorecon), a boolean toggle (setsebool), or a custom policy module (audit2allow) is the right solution.

Create Custom SELinux Policy Modules

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

Generate and install a custom policy module from denied log entries:

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

The first command extracts denied entries and generates a policy module named mycustommodule. The second command installs it, allowing the previously denied actions. Use audit2allow carefully since overly permissive custom policies reduce security effectiveness.

Manage SELinux Booleans

SELinux booleans provide simple on/off switches for common policy adjustments without requiring custom modules. They control specific capabilities such as network access, email sending, and database connections.

List all available booleans and their current states:

sudo getsebool -a

To change a boolean value, for example allowing the web server to make network connections:

sudo setsebool -P httpd_can_network_connect 1

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

Fix “Failed to Load SELinux Policy” Boot Freeze

If Ubuntu freezes at boot with the error Failed to load SELinux policy. Freezing., the bootloader contains the security=selinux parameter but the policy files are missing or corrupted. Boot into recovery mode by holding Shift during startup to open the GRUB menu, select an advanced/recovery entry, then mount the filesystem read-write and reinstall the policy package:

sudo apt install --reinstall selinux-policy-default

Alternatively, add enforcing=0 to the GRUB kernel parameters at boot to enter permissive mode and investigate from a running system. If selinux-activate was run before the policy package was installed, reinstall the package and run sudo selinux-activate again, then reboot.

Fix SELinux Not Detected After Installation

If getenforce returns Disabled or sestatus reports SELinux as disabled after installation, the most common causes are:

  • selinux-activate was not run before rebooting. Run sudo selinux-activate and reboot.
  • The system has not been rebooted after running selinux-activate. A reboot is required for the GRUB changes and filesystem relabeling.
  • SELINUX=disabled is set in /etc/selinux/config. Change the value to permissive or enforcing and reboot.

Remove SELinux from Ubuntu

To fully remove SELinux and restore AppArmor as the active Linux Security Module, first disable SELinux in the configuration file and then uninstall the packages. Open /etc/selinux/config and set SELINUX=disabled, then remove the SELinux packages:

sudo apt remove --purge selinux-basics selinux-policy-default selinux-utils policycoreutils policycoreutils-python-utils auditd
sudo apt autoremove

Re-enable AppArmor so Ubuntu returns to its default security module:

sudo systemctl enable apparmor --now

Reboot to complete the transition back to AppArmor-only operation:

sudo reboot

Frequently Asked Questions

Does Ubuntu use SELinux by default?

No. Ubuntu uses AppArmor on Ubuntu as its default Linux Security Module. SELinux is available in the Ubuntu repositories but requires manual installation and AppArmor must be disabled first since only one LSM can enforce policies at a time.

How do I check SELinux status on Ubuntu?

Run getenforce for a one-word response (Enforcing, Permissive, or Disabled), or run sestatus for detailed output including the loaded policy name, the mode from the configuration file, and the active runtime mode.

How do I disable SELinux on Ubuntu?

Edit /etc/selinux/config and change SELINUX=enforcing to SELINUX=permissive for logging-only mode, or SELINUX=disabled to turn SELinux off entirely. Save the file and reboot. To confirm the change, run getenforce after rebooting. Prefer permissive mode over disabled when troubleshooting so audit logging continues.

Why does “semanage: command not found” appear after installing SELinux?

semanage is part of the policycoreutils-python-utils package, which is not installed by default with the SELinux packages. Install it separately with sudo apt install policycoreutils-python-utils.

Can I change SELinux modes without rebooting?

Yes, for runtime changes. Run sudo setenforce 1 to switch to enforcing mode or sudo setenforce 0 for permissive mode — the change takes effect immediately. However, the mode reverts to the value in /etc/selinux/config on the next boot. To make a permanent change, edit that file and set SELINUX=enforcing or SELINUX=permissive, then reboot.

Conclusion

SELinux on Ubuntu provides kernel-level mandatory access control with fine-grained policy enforcement and comprehensive audit logging that goes well beyond AppArmor’s path-based profile model. Installing SELinux on Ubuntu requires disabling AppArmor, installing the core packages, running selinux-activate, and rebooting for the initial filesystem relabel. Keep the system in permissive mode while reviewing audit logs, tuning file contexts, and enabling the booleans your workloads need, then switch to enforcing mode once tests are clean. For further Ubuntu security hardening, see our guides on Fail2Ban on Ubuntu and UFW firewall on Ubuntu.

Found this guide useful?

Support LinuxCapable to keep tutorials free and up to date.

Buy me a coffee Buy me a coffee

Before commenting, please review our Comments Policy.
Formatting tips for your comment

You can use basic HTML to format your comment. Useful tags currently allowed:

You type Result
<code>command</code> command
<strong>bold</strong> bold
<em>italic</em> italic
<blockquote>quote</blockquote> quote block

Leave a Comment

We read and reply to every comment - let us know how we can help or improve this guide.

Let us know you are human: