Some compliance baselines and RHEL-aligned workflows expect SELinux labels, booleans, and AVC audit logs instead of Ubuntu’s default AppArmor profiles. You can install SELinux on Ubuntu 26.04, 24.04, and 22.04 from Ubuntu’s repositories, but the switch changes the active Linux Security Module and requires a relabeling reboot.
Ubuntu does not use SELinux by default. It ships AppArmor on Ubuntu as the default mandatory access control layer, while SELinux is an optional package set from Ubuntu’s Universe component for administrators who specifically need the SELinux policy model.
SELinux can block service access, SSH sessions, web content, and local administration when policies or labels are wrong. Start in permissive mode, keep console or provider recovery access available, and test critical services before switching to enforcing mode.
Install SELinux on Ubuntu
Start by confirming AppArmor state, refreshing APT metadata, installing the SELinux policy tools, then activating the SELinux boot parameters for the next restart.
Update Ubuntu Before Installing SELinux
Refresh the package index so APT sees the current SELinux packages and dependencies.
sudo apt update
These commands use
sudofor system-wide package and bootloader changes. If your account does not have administrator access yet, add a user to sudoers on Ubuntu before continuing.
The SELinux packages are in Ubuntu’s Universe component. Standard desktop and server installs usually have Universe enabled; minimal or customized systems may need to enable Universe on Ubuntu first if APT cannot find the packages.
Check AppArmor Before Activating SELinux on Ubuntu
Check AppArmor first so you know whether Ubuntu is still using its default MAC layer.
systemctl is-active apparmor
systemctl is-enabled apparmor
On a normal AppArmor-enabled Ubuntu system, the output is:
active enabled
Disabling AppArmor removes AppArmor profile enforcement until you enable it again. Back up any custom profiles under
/etc/apparmor.d/before switching a production host to SELinux.
Disable AppArmor before SELinux becomes the active security module.
sudo systemctl disable --now apparmor
Confirm that AppArmor is disabled before continuing.
systemctl is-active apparmor
systemctl is-enabled apparmor
inactive disabled
Install SELinux Packages with APT
Install the base SELinux utilities, Ubuntu’s default SELinux policy, the audit daemon, and the Python helper package that provides semanage and audit2allow.
sudo apt install policycoreutils selinux-utils selinux-basics selinux-policy-default auditd policycoreutils-python-utils
APT also installs supporting policy tools such as setools and semodule-utils. Check the core command files after installation.
dpkg -L policycoreutils policycoreutils-python-utils | grep -E '^/usr/bin/sestatus$|^/usr/bin/audit2allow$|^/usr/sbin/semanage$'
/usr/bin/sestatus /usr/bin/audit2allow /usr/sbin/semanage
semanage lives in /usr/sbin. If a regular shell reports semanage: command not found, run it with sudo semanage or use the full path /usr/sbin/semanage.
Activate SELinux on Ubuntu
Run the activation helper once. It adds the SELinux boot parameter to GRUB, updates the bootloader configuration, and creates /.autorelabel so the next boot labels the filesystem.
sudo selinux-activate
Relevant output includes:
Activating SE Linux SE Linux is activated. You may need to reboot now.
Reboot and Verify SELinux on Ubuntu
Reboot after activation. The first SELinux boot can take several minutes because Ubuntu relabels files before services finish starting.
sudo reboot
After the host comes back, check the detailed SELinux status.
sestatus
A successful first boot should include these lines.
SELinux status: enabled Loaded policy name: default Current mode: permissive Mode from config file: permissive
Permissive mode is expected after the initial boot. It logs denials without blocking services, which gives you time to fix labels and booleans before enforcement starts.
Configure SELinux on Ubuntu
SELinux configuration has two layers: the persistent boot mode in /etc/selinux/config and the current runtime mode controlled by setenforce.
Understand SELinux Modes on Ubuntu
- Enforcing: blocks and logs policy violations. Use it after services run cleanly in permissive mode.
- Permissive: logs denials without blocking them. This is the safest mode for first boot and policy tuning.
- Disabled: turns SELinux off. Re-enabling SELinux later requires another activation and relabel cycle.
Edit the SELinux Configuration File on Ubuntu
Open the main SELinux configuration file before changing the persistent mode.
sudo nano /etc/selinux/config
Keep the default policy type unless you intentionally installed and tested a different policy package.
SELINUX=permissive
SELINUXTYPE=default
SETLOCALDEFS=0
Ubuntu’s SELinux policy package uses
defaultas the normal policy name. Do not changeSELINUXTYPEtotargeted; that Red Hat policy name is not the Ubuntu policy tree.
Set SELINUX=enforcing only after permissive-mode testing is clean. Set SELINUX=disabled only when removing SELinux or backing out of the migration.
Change SELinux Runtime Mode on Ubuntu
Use runtime mode changes for short tests. They take effect immediately but revert to the value in /etc/selinux/config at the next boot.
Switch to permissive mode temporarily:
sudo setenforce 0
getenforce
Permissive
Switch back to enforcing mode after you fix the denial being tested:
sudo setenforce 1
getenforce
Enforcing
Enable SELinux Enforcing Mode on Ubuntu
Use enforcing mode after SSH, web services, databases, scheduled jobs, and application logs show no unexpected denials in permissive mode.
sudo selinux-config-enforcing
Configured enforcing mode in /etc/selinux/config for the next boot. This can be overridden by "enforcing=0" on the kernel command line.
Reboot, then confirm that enforcing mode is active.
sudo reboot
getenforce
Enforcing
Configure SELinux Policy for Web Servers on Ubuntu
Web services often need extra SELinux policy work when you move document roots, use non-standard ports, or let applications connect to remote services. These examples fit common Apache on Ubuntu, Nginx on Ubuntu, and WordPress on Ubuntu deployments.
Check SELinux HTTP Port Labels on Ubuntu
Check the HTTP ports that the installed SELinux policy already allows before adding a custom listener.
sudo semanage port -l | grep '^http_port_t'
http_port_t tcp 80, 443, 488, 8008, 8009, 8443, 8448
Add a custom TCP port, such as 18080, only when your web service actually listens there.
sudo semanage port -a -t http_port_t -p tcp 18080
If SELinux reports that the port is already defined, the port already has a label. Use
sudo semanage port -m -t http_port_t -p tcp 18080to modify the existing mapping instead of adding a duplicate.
SELinux port labels do not open the local firewall or any cloud security group. If the service must accept network traffic, configure that access separately with UFW firewall on Ubuntu or the firewall tool that owns your host.
Label Custom Web Content on Ubuntu
When web content lives outside the standard paths already covered by the policy, add a file-context rule and relabel the existing files.
sudo semanage fcontext -a -t httpd_sys_content_t "/opt/myapp(/.*)?"
sudo restorecon -Rv /opt/myapp
restorecon prints relabeled files when it changes contexts. If it prints nothing, the files already matched the policy.
Enable SELinux Web Server Booleans on Ubuntu
List the relevant HTTP booleans before changing them so you can see the current and persistent values.
sudo semanage boolean -l | grep -E '^(httpd_can_network_connect|httpd_can_sendmail|httpd_enable_ftp_server)\b'
httpd_can_network_connect (off , off) Determine whether httpd scripts and modules can connect to the network using TCP. httpd_can_sendmail (off , off) Determine whether httpd can send mail. httpd_enable_ftp_server (off , off) Determine whether httpd can act as a FTP server by listening on the ftp port.
Enable only the boolean your application needs. For example, allow outbound TCP connections for update checks, APIs, or remote databases:
sudo setsebool -P httpd_can_network_connect 1
Allow web applications to send email only when the site needs mail delivery from the web server context:
sudo setsebool -P httpd_can_sendmail 1
The -P flag saves the boolean change so it survives reboots.
Undo SELinux Web Policy Changes on Ubuntu
Remove local policy changes when a test port, content path, or boolean is no longer needed.
sudo semanage port -d -t http_port_t -p tcp 18080
sudo semanage fcontext -d "/opt/myapp(/.*)?"
sudo setsebool -P httpd_can_network_connect 0
Run the delete commands only for settings you actually added. If a command reports that the record is not defined, that setting was already absent.
Verify SELinux Status on Ubuntu
Use getenforce for a quick mode check and sestatus when you need the loaded policy and boot configuration values.
Check the Current SELinux Mode on Ubuntu
getenforce
The command returns one of these values.
Enforcing Permissive Disabled
Check Detailed SELinux Status on Ubuntu
sestatus
Compare Current mode with Mode from config file. A mismatch usually means someone changed the runtime mode with setenforce after boot.
Troubleshoot SELinux on Ubuntu
Most SELinux problems on Ubuntu come from missing labels, services running outside their expected paths, or booleans that still deny legitimate application behavior.
Fix semanage Command Not Found on Ubuntu
The semanage command comes from policycoreutils-python-utils. Install that package if the command is missing.
sudo apt install policycoreutils-python-utils
If the package is installed but the shell still cannot find the command, run sudo semanage or /usr/sbin/semanage because the binary is installed under /usr/sbin.
Restore SELinux File Contexts on Ubuntu
Reset labels first when a service breaks after moving files or copying content into a path that SELinux already knows how to manage.
sudo restorecon -Rv /var/www/html
The -R flag applies the relabel recursively, while -v prints files whose contexts changed.
Review SELinux Audit Logs on Ubuntu
Start with the audit daemon because SELinux denials are recorded in /var/log/audit/audit.log.
sudo systemctl status auditd --no-pager
Query recent AVC records with ausearch.
sudo ausearch -m AVC,USER_AVC -ts recent
For a quick log scan, combine the grep command in Linux with the tail command in Linux.
sudo grep 'denied' /var/log/audit/audit.log | tail -20
An AVC record identifies the process, denied action, source context, target context, and target class. Use that detail to decide whether the fix belongs in a file label, a boolean, or a custom policy module.
Create Custom SELinux Policy Modules on Ubuntu
Create a local module only after you understand the denial and decide the access should be allowed permanently.
sudo grep 'denied' /var/log/audit/audit.log | audit2allow -M mycustommodule
sudo semodule -i mycustommodule.pp
The first command reads root-owned audit logs and writes a module in the current directory. The second command loads the compiled policy module.
sudo semodule -l | grep mycustommodule
mycustommodule
Review the generated mycustommodule.te file before loading it on production systems. Blindly allowing every denial can make the final policy broader than the service actually needs.
Fix Failed to Load SELinux Policy on Ubuntu
If Ubuntu stops at Failed to load SELinux policy. Freezing., the bootloader is trying to load SELinux but the policy files are missing or broken. Boot from a recovery entry or provider console, then reinstall the default policy package.
sudo apt install --reinstall selinux-policy-default
If the system needs to boot before you finish repairs, add enforcing=0 to the kernel line from the GRUB edit screen so SELinux starts in permissive mode for that boot.
Fix SELinux Not Detected After Reboot on Ubuntu
If getenforce returns Disabled after installation, check the three common causes first.
sudo selinux-activatewas not run before rebooting.- The host has not rebooted since
selinux-activateupdated GRUB and created/.autorelabel. SELINUX=disabledis still set in/etc/selinux/config.
After correcting the cause, run sudo selinux-activate again when needed and reboot so the kernel loads SELinux at startup.
Disable or Remove SELinux from Ubuntu
Disable SELinux in stages so Ubuntu does not keep SELinux boot parameters after the policy packages are gone. If you only want to disable SELinux and keep the packages installed, skip the package purge after removing the boot parameters and re-enabling AppArmor.
Disable SELinux on Ubuntu
If SELinux is enforcing, move it to permissive mode before removing packages.
sudo setenforce 0
Edit the persistent configuration and set SELinux to disabled.
sudo nano /etc/selinux/config
SELINUX=disabled
Remove SELinux Boot Parameters on Ubuntu
Use the same activation helper with the disable argument so it removes the SELinux kernel parameters from GRUB cleanly.
sudo selinux-activate disable
Deactivating SE Linux SE Linux is deactivated. You may need to reboot now.
Purge SELinux Packages from Ubuntu
Purge the SELinux packages only when you want a full removal after disabling SELinux.
sudo apt remove --purge selinux-basics selinux-policy-default policycoreutils policycoreutils-python-utils selinux-utils
If auditd was installed only for this SELinux setup, remove it separately. Keep it installed when other compliance or logging workflows already use Linux audit events.
sudo apt remove --purge auditd
Preview dependency cleanup before removing automatically installed packages, especially on shared servers where other tools may use the same libraries.
sudo apt autoremove --purge --dry-run
If the dry run only lists packages you no longer need, run the cleanup without --dry-run.
sudo apt autoremove --purge
Re-enable AppArmor on Ubuntu
Enable AppArmor so Ubuntu returns to its default MAC layer after the next reboot.
sudo systemctl enable apparmor
Reboot once the cleanup finishes.
sudo reboot
After Ubuntu starts again, confirm that AppArmor is active.
systemctl is-active apparmor
active
Check that the main SELinux packages are no longer installed.
dpkg -l selinux-basics selinux-utils policycoreutils policycoreutils-python-utils 2>/dev/null | grep '^ii' || echo 'SELinux packages are not installed'
SELinux packages are not installed
Conclusion
SELinux is installed on Ubuntu with AppArmor disabled, the default policy loaded, and permissive testing available before enforcement. Keep audit reviews part of routine maintenance, then use the related guides to configure unattended upgrades on Ubuntu and install Fail2Ban on Ubuntu for patching and brute-force response.


Formatting tips for your comment
You can use basic HTML to format your comment. Useful tags currently allowed in published comments:
<code>command</code>command<strong>bold</strong><em>italic</em><blockquote>quote</blockquote>