- Daily Devops Tips
- Posts
- Linux AppArmor
Linux AppArmor
👋 Hi! I’m Bibin Wilson. In each edition, I share practical tips, guides, and the latest trends in DevOps and MLOps to make your day-to-day DevOps tasks more efficient. If someone forwarded this email to you, you can subscribe here to never miss out!
In this edition, we explore AppArmor, a key Linux security concept.
We will look at,
What is AppArmor?
Example Use case
AppArmor & Mandatory Access Control (MAC)
How Does AppArmor Work (Hands on Example)
AppArmor in Container Runtimes
AppArmor is widely used in containers and Kubernetes. Also an important topic for the CKS certification.
We'll break it down with a practical example to help you understand how it works.
What is AppArmor?
AppArmor (Application Armor) is a security feature in built into some Linux systems that controls what individual programs can and cannot do.
If an application has a security flaw or is compromised by malware, AppArmor limits the damage it can do.
For example, even if a hacker exploits a vulnerability in a web server, AppArmor can prevent it from accessing sensitive system files or running harmful commands.
Example Use case
Let’s say you are running an Apache web server.
Without AppArmor, if Apache is compromised, it can read any file on the system or execute random scripts, posing a serious security risk.
With an AppArmor profile, you can restrict Apache’s access by:
Allowing it to read only files from /var/www/html (where website files are stored).
Permitting it to write logs only to /var/log/apache2.
Restricting it to listen only on port 80.
At the same time, it cannot access user files in /home/ or run unauthorized commands.
You might ask, "Can’t I do this using file permissions?"
Here is where it differs.
File permissions control access based on user/group IDs. If a user is compromised, the attacker can potentially access all the files owned by the user.
Whereas AppArmor controls access based on what a program itself is allowed to do, no matter which user is running it.
So even if Apache is compromised, it still can’t access anything outside the allowed paths.
Mandatory Access Control
AppArmor falls under Mandatory Access Control (MAC).
MAC is a security model where access to resources (files, directories, network ports, etc.) is strictly controlled by a central policy.
Unlike Discretionary Access Control (DAC), where the owner of a resource (e.g., a file) can set permissions (read, write, execute), MAC policies are enforced system-wide and cannot be overridden by users or programs, even if they have elevated privileges like root
.
For example, even if a program runs with root privileges, AppArmor can block it from modifying /etc/passwd. If an attacker compromises the program, they are still restricted by AppArmor.
How Does AppArmor Work?
AppArmor works based on profiles, similar to seccomp.
Each profile is a plain-text file that defines what a program is allowed to do.
On Linux systems, you can find existing AppArmor profiles in /etc/apparmor.d/
For example,
$ ls -p /etc/apparmor.d/ | grep -v /
lsb_release
nvidia_modprobe
sbin.dhclient
usr.bin.man
usr.bin.tcpdump
usr.lib.snapd.snap-confine.real
usr.sbin.rsyslogd
AppArmor Practical Example
Let's understand an AppArmor profile with a practical example.
We will create a simple Bash script that attempts to read /etc/shadow (a file that contains hashed passwords and should be protected).
The idea is to block the script from reading /etc/shadow, even when run as the root user.
Lets create the script.
$ echo -e '#!/bin/bash\ncat /etc/shadow' > script.sh
$ chmod +x script.sh
If you run the script as root, you will not get any error. It will display the /etc/shadow contents.
$ root@ubuntu:~# ./script.sh
root:*:19579:0:99999:7:::
daemon:*:19579:0:99999:7:::
.
.
.
Now, let's create an AppArmor profile that prevents the script from reading /etc/shadow.
We will define this profile in /etc/apparmor.d/root.script.sh.
#include <tunables/global>
profile /root/script.sh {
# Allow reading its own file
/root/script.sh r,
# Deny access to /etc/shadow
deny /etc/shadow r,
# Allow execution of Bash
/bin/bash rmix,
# Allow execution of 'cat' or any other needed commands
/usr/bin/cat rmix,
}
Lets load the profile.
sudo apparmor_parser -r /etc/apparmor.d/root.script.sh
Check the status.
$ root@ubuntu:~# sudo apparmor_status | grep script.sh
/root/script.sh
It should now show the correct path (/root/script.sh
)
Now lets run the script and see what happens. You should get a permission denied error when trying to access /etc/shadow
, even as root.
$ root@ubuntu:~# ./script.sh
./script.sh: line 2: /usr/bin/cat: Permission denied
As you can see, AppArmor restricts applications based on profiles, even if you run them as root.
Why is AppArmor Restricting Root?
Root has full system access, but AppArmor controls what an application (even one run by root) can do.
This prevents privilege escalation attacks (e.g., a compromised root script can't access sensitive files like /etc/shadow
). It enforces least privilege, allowing only the necessary permissions.
AppArmor In Containers
AppArmor is integrated into container runtimes to enforce Mandatory Access Control (MAC) on container processes.
The runtime loads these profiles when starting a container, ensuring each container operates in a sandbox.
For example, Docker comes with a default profile called docker-default. This profile is applied to every container unless overridden. You can check the profile here.
It is designed to
Allow basic operations (e.g., read/write within the container’s filesystem).
Deny dangerous actions (e.g., mounting /proc or accessing /etc/passwd on the host).
Here is a simple example that shows docker default AppArmor profile blocking reading /proc/sysrq-trigger using cat.

Tomorrow
In tomorrow's edition, we will explore how to leverage AppArmor profiles in Kubernetes pods using SecurityContext.
Reply