Securing Linux with SELinux (or AppArmor)

SELinux and AppArmor have been around for many years, but are still essential for maintaining a secure Linux environment. This article will cover how to set them up and troubleshoot these mandatory access control (MAC) frameworks. Even if they seem overwhelming at first, learning how they work and how to manage them is an important step in securing your infrastructure.

Linux systems typically use Discretionary Access Control (DAC) where the owner defines the file permissions. But Mandatory Access Control (MAC) provides stricter security by enforcing rules beyond what the user can change (not to be confused with MAC address—Media Access Control address). So even if an attacker gets in, they’re still restricted by system-wide policies.


Terminal output listing SELinux Boolean settings and their states.

Real-world system breaches have shown that traditional DAC-based permissions are not enough. Attackers exploit misconfigured or weak permissions to escalate privileges. MAC frameworks like SELinux and AppArmor massively reduce this risk by ensuring that each process and user adheres to predefined security policies.

MAC frameworks like SELinux and AppArmor, are key for security-hardened environments. They’re used across Enterprise Linux distributions like Red Hat Enterprise Linux, Fedora, Ubuntu, Debian and SUSE. These tools help contain breaches by limiting an attacker’s ability to move around the system, reducing the impact of a compromised service.

SELinux Fundamentals

SELinux operates using security contexts, where every file, process, and directory has labels that define its permissions. These labels work within policy types which define what a process can do. Administrators can toggle security rules using Booleans, which allow flexibility in policy management.

SELinux has three modes:

  • Enforcing: Actively blocks unauthorized actions.
  • Permissive: Logs violations without enforcing rules.
  • Disabled: Turns SELinux off (not recommended).

Each mode serves a specific purpose. Enforcing is best for production systems, ensuring strict access control. Permissive is useful for debugging, allowing administrators to identify access violations without breaking functionality. Disabled should only be used in very rare cases, as it removes all security benefits.

Enabling and Configuring SELinux

Most Red Hat-based distributions ship with SELinux enabled by default. You can check its status using:

sestatus

To temporarily switch between enforcing and permissive mode:

setenforce 1  # enforcing
setenforce 0  # permissive

For a permanent change, edit /etc/selinux/config and set SELINUX=enforcing or SELINUX=permissive.

Managing SELinux Policies

SELinux policies control access at a granular level. Tools like semanage modify policies, while restorecon ensures files have correct security contexts. If access is denied, logs in /var/log/audit/audit.log provide insights. Use:

audit2allow -a

to analyze and generate new policies based on blocked actions.

Troubleshooting Example:

If a web application running on Apache cannot access a file, SELinux might be blocking it. To check, run:

ls -Z /path/to/file

If the file does not have the correct httpd_sys_content_t label, fix it with:

sudo chcon -t httpd_sys_content_t /path/to/file

This ensures Apache can serve the file while maintaining security.

Also read: Troubleshooting SELinux.

AppArmor Essentials

Unlike SELinux, which labels everything with security contexts, AppArmor applies profiles to individual applications. These profiles define what an application can access, making it a simpler approach compared to SELinux.

Enabling AppArmor

Check if AppArmor is running with:

systemctl status apparmor

If it’s not installed, add it via your package manager:

sudo apt-get install apparmor apparmor-utils

Default profiles for services like Apache and MySQL load automatically.

Managing AppArmor Profiles

Profiles can be in complain mode (logging violations) or enforce mode (blocking violations). Use the following to modify profiles:

aa-status  # View active profiles
aa-enforce /path/to/profile  # Enforce a profile
aa-complain /path/to/profile  # Set to complain mode

To create a new profile, monitor the application’s behavior with:

aa-genprof /path/to/application

Troubleshooting Example:

If MySQL fails to start, check AppArmor logs in /var/log/syslog for DENIED messages. If MySQL needs additional permissions, modify its profile in /etc/apparmor.d/usr.sbin.mysqld and reload AppArmor:

sudo systemctl restart apparmor

Also read: Confining privileges with AppArmor.

Real-World Use Cases & Step-by-Step Example

Mandatory Access Control enhances security in various scenarios:

Hosting Multiple Services

If a server hosts multiple services, MAC ensures that a compromised service cannot affect another. For example, an attacker exploiting a vulnerable web application won’t gain access to system-wide files. In an SELinux environment, even if an attacker gains control of a process running as www-data, they won’t be able to read /etc/shadow or alter system-wide configurations.

Example: Hardening a LAMP Stack with SELinux on RHEL/Fedora

  1. Check SELinux Status
sestatus

Verify it’s set to “enforcing” or “permissive.”

  1. Assign Correct File Contexts
    Ensure your web directory has the correct context:
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/html(/.*)?"
sudo restorecon -Rv /var/www/html
  1. Troubleshoot Blocked Actions
    Check /var/log/audit/audit.log if services are denied access. Generate custom rules using audit2allow.
  2. Validate
    Reload or restart web services and verify functionality. Switch SELinux fully to “enforcing” if previously permissive.

Also read: Configuring SELinux. Alternatively, for AppArmor.

Common Pitfalls and How to Avoid Them

One of the common mistakes administrators make is to disable SELinux or AppArmor at the first sign of trouble. Instead of disabling these security layers, sysadmins should use permissive (SELinux) or complain (AppArmor) modes to debug. Leaving SELinux or AppArmor disabled leaves systems open to privilege escalation attacks.

Using old policies is another pitfall. System updates may introduce changes that require policy tweaking. Maintaining and updating your system’s MAC policies along with system updates ensures that security remains intact.

Distribution-specific differences also matter. RHEL-based distros use SELinux, while Ubuntu and Debian use AppArmor. Administrators should familiarize themselves with their distribution’s security framework to avoid misconfigurations.

Conclusion

SELinux and AppArmor add an extra layer of security by enforcing strict access rules beyond standard file permissions. Despite the initial learning curve, these frameworks dramatically reduce risks and limit damage from security breaches. Regularly update your knowledge through these resources:

Tags: , , , ,

Comments from Our Members

  1. What would you recommend for Debian/Ubuntu and Arch? AppArmor or SELinux?

  2. Thanks for asking! I missed mentioning any of that.

    For Debian/Ubuntu and *SUSE, AppArmor is the way to go as it’s the system default and well integrated. For RHEL and derivatives they default to SELinux .

    For Arch, SELinux is possible, but not commonly used because of the complexity of setup and maintenance. AppArmor is easier to config, but most Arch users (not a popular distro for servers) rely on traditional DAC (Discretionary Access Control) security instead of MAC (Mandatory Access Control) frameworks.

    If you’re running a server and require serious security, SELinux is worth considering. For desktops and workstations, AppArmor is more practical.

    Also see:

  3. Thank you @hydn. Really interesting and good to know.

    A few days ago I got a VPS again and decided to use Ubuntu (I had Fedora, Debian, Rocky Linux, openSUSE and Alma Linux to choose from).

    I have no idea what exactly I want to do productively with it, but I want to make it as secure as possible.

  4. Really good article, took me down some rabbit holes :blush: you did have one error in the command for Deb/Unbun, it’s apt install <program> -y not apt-get, that command has been “depreciated” and used mostly for scripting purposes now. Also AppArmor comes installed on Debian when you install it. You can verify it’s running by putting systemctl status apparmor.
    You also didn’t mention the Debian Administrators handbookwhich has a great section on AppArmor. Or the Debian project’s home page which has a great search function that points you to Chapter 14 of the Debian Administrators guide. which has most of the answers on setting up a Debian based system. and of course there’s always man apparmor for any distro worth a darn.

  5. Nice article!

    On Linux Mint I have been running AppArmor for a few years, and it has been problem free.

    Initially, I wanted to add an additional MAC sandbox for Firefox, and it never caused any issues with Firefox. The audit log showed a little log noise, but I have never attributed any Firefox issue directly to AppArmor.

    A few years later, Ubuntu switched Firefox from a Debian package to Snap. I think Ubuntu provides the AppArmor profiles inherited by Linux Mint because the Snap conversion was when I lost the Firefox AppArmor profile in Linux Mint. I have not verified this, but Ubuntu probably created a new AppArmor profile for their Snap installation of Firefox. Perhaps Snap has its own sandboxing, but I do not know. I say all this to point out that you may find that popular AppArmor profiles are removed with little to no warning.

    I have generated a few basic AppArmor profiles for console applications, but I did not want to tackle creating an AppArmor profile for something as complicated as Firefox. I considered borrowing Debian’s AppArmor profile for Firefox to use in Linux Mint, but I figured that would probably not end well. After significant research and not finding an easy AppArmor way to move forward, I found Firejail. Firejail provides a profile for Firefox, and that has worked well. Technically, from what I have read, Firejail combines with AppArmor to create restrictions for Firefox.

    Long story short, if you cannot find an AppArmor profile for an application, and you do not want to tackle generating your own profile, consider Firejail.



Top ↑