Securing Your VPS with SELinux and AppArmor: A Practical Guide to Mandatory Access Control on Linux

A standard Linux VPS runs discretionary access control (DAC) — if a process has root, it can do anything. Mandatory access control (MAC) systems like SELinux and AppArmor add a second layer of security: even processes running as root can only access what their policy allows. This guide explains how to configure both systems on your VPS, which one to choose, and how to troubleshoot the inevitable access denials.

Looking for a broader VPS security strategy? Start with our feature overview to see what performance and security features different providers offer.

SELinux vs AppArmor: Which One Should You Use?

Both systems enforce MAC, but they approach it differently. The choice often comes down to your Linux distribution:

FeatureSELinuxAppArmor
Default onRHEL, CentOS, Fedora, AlmaLinux, Rocky LinuxUbuntu, Debian, OpenSUSE
Policy modelLabel-based (every file, process, and port has a security context)Path-based (policies reference file paths and network access)
GranularityExtremely fine-grained. Every system object gets a label.Coarser but simpler. Policies target specific applications.
Learning curveSteep. Requires understanding security contexts, booleans, and policy modules.Gentle. Policies are human-readable text files.
Audit logs/var/log/audit/audit.log (use ausearch or sealert)/var/log/syslog or /var/log/kern.log (grep for “DENIED” or “ALLOWED”)

If you are on Ubuntu or Debian, AppArmor is the natural choice. On RHEL-based distributions, SELinux is the default and is deeply integrated into the system packaging (Nginx, MariaDB, and PHP all ship with SELinux policies).

Installing and Enabling AppArmor on Ubuntu/Debian

AppArmor is pre-installed on Ubuntu (since 8.04) and Debian (since 7). Verify it is running:

sudo aa-status
# Should show: "apparmor module is loaded." and a list of profiles

Installing AppArmor Utilities

sudo apt update
sudo apt install apparmor-utils apparmor-profiles

Creating a Custom AppArmor Profile for Nginx

Let us create a profile that restricts Nginx to only the files and network permissions it actually needs.

# Generate a profile template based on Nginx's actual behavior
sudo aa-genprof /usr/sbin/nginx

# Follow the interactive prompts. Run typical Nginx operations
# (request pages, reload config) then press 'S' to scan,
# and 'A' to allow each detected permission.

After genprof completes, the profile is stored at /etc/apparmor.d/usr.sbin.nginx. You can edit it directly:

# /etc/apparmor.d/usr.sbin.nginx
#include <tunables/global>

/usr/sbin/nginx {
  #include <abstractions/base>
  #include <abstractions/nameservice>

  /etc/nginx/** r,
  /var/log/nginx/* w,
  /var/www/** r,
  /run/nginx.pid rw,

  # Allow listening on port 80 and 443
  network inet tcp,
  network inet6 tcp,
}

Apply the profile:

sudo aa-enforce /usr/sbin/nginx
# Or try in complain mode first to log denials without blocking:
# sudo aa-complain /usr/sbin/nginx

Configuring SELinux on RHEL/AlmaLinux/CentOS

Check SELinux Status

getenforce
# Output: Enforcing (good) or Permissive or Disabled

If SELinux is disabled, you can enable it by editing /etc/selinux/config and setting SELINUX=enforcing, then rebooting. Note that changing from disabled to enforcing on an existing system may uncover previously hidden policy violations — test in permissive mode first.

Managing SELinux Booleans

Booleans are SELinux toggles that adjust policy without writing rules. Common ones for a web server VPS:

# Allow Nginx to connect to network services (proxying, database)
setsebool -P httpd_can_network_connect on

# Allow Nginx to send email
setsebool -P httpd_can_sendmail on

# Allow scripts to write to directories (for CMS platforms)
setsebool -P httpd_unified on

# List all booleans
getsebool -a

Fixing SELinux Denials

When SELinux blocks an operation, it logs to /var/log/audit/audit.log. Use sealert to get human-readable solutions:

# Check for denials in the last hour
sudo ausearch -m avc -ts recent | audit2allow -a

# Generate a custom policy module to allow a specific denial
sudo grep "denied" /var/log/audit/audit.log | audit2allow -M myhttpd
sudo semodule -i myhttpd.pp

Always prefer setting the correct file context over writing allow rules. If a web application needs write access to a directory, set the httpd_sys_content_t or httpd_sys_rw_content_t context:

# Change file context for a writable directory
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/myapp/uploads(/.*)?"
sudo restorecon -Rv /var/www/myapp/uploads

Common Pitfalls and How to Troubleshoot Them

ProblemLikely CauseFix
Nginx returns 403 with correct file permissionsSELinux context on document root is wrongchcon -R -t httpd_sys_content_t /var/www
PHP cannot connect to MySQLSELinux blocking httpd network accesssetsebool -P httpd_can_network_connect on
AppArmor blocking log rotationlogrotate needs write access to var/logAdd /var/log/nginx/* rw, to AppArmor profile
Cannot start NginxAppArmor profile blocks port bindingEnsure profile includes network inet tcp,

Best Practices for MAC on Your VPS

  • Start in permissive/complain mode on new installations. Review logs for a week before enforcing policies.
  • Keep profiles as narrow as possible. Granting blanket permissions defeats the purpose of MAC.
  • For containerized workloads, use SELinux or AppArmor in combination with container-specific security profiles (seccomp, capabilities drop).
  • Set up log monitoring for MAC denials. A sudden spike in denials often indicates a compromised application or misconfiguration.
  • Update policies when you update application configurations. Changing Nginx document root requires updating the corresponding profile or context.

Conclusion

Mandatory access control is one of the most effective security layers you can add to a Linux VPS. AppArmor on Ubuntu/Debian or SELinux on RHEL-based distributions prevents common attack vectors like file inclusion, privilege escalation, and network pivoting — even if an attacker gains code execution. Invest the hour to configure it properly, and your VPS will be significantly harder to compromise.

Compare VPS providers that offer security-enhanced hosting environments on our comparison table.

Leave a Reply