Runtime security provides active protection for your containers while they’re running. The idea is to detect and prevent malicious activity from occurring your containers.
AppArmor is an effective and easy-to-use Linux application security system. It proactively protects the operating system and applications from external or internal threats, even zero-day attacks, by enforcing good behavior and preventing both known and unknown application flaws from being exploited, AppArmor is a Linux security module similar to seccomp, but it restricts a container’s capabilities including accessing parts of the file system. It can be run in either enforcement or complain mode.
Docker automatically generates and loads a default profile for containers named docker-default. The Docker binary generates this profile in tmpfs and then loads it into the kernel.
Understand the policies
The docker-default profile is the default for running containers. It is moderately protective while providing wide application compatibility. The profile is generated from a template.
When you run a container, it uses the docker-default policy unless you override it with the security-opt option. For example, the following explicitly specifies the default policy:
$ docker run --rm -it --security-opt apparmor=docker-default simplifier
Installation
Simply run aa-status
to see if your Linux distribution already has AppArmor integrated:
$ aa-status
apparmor module is loaded.
Since it is a kernel module it is usually not something users install themselves. Individual users and system administrators might however want to manage the application profiles which define what each application is allowed to do by editing the files in /etc/apparmor.d/
.
The list of currently active profiles can be easily checked with aa-status
Load and unload profiles
To load a new profile into AppArmor for use with containers:
$ apparmor_parser -r -W /path/to/your_profile
Then, run the custom profile with --security-opt
like so:
$ docker run --rm -it --security-opt apparmor=your_profile simplifier
To unload a profile from AppArmor:
# unload the profile
$ apparmor_parser -R /path/to/profil
TRAEFIK example profile
In this example, you create a custom AppArmor profile for traefk. Below is the custom profile.
#include <tunables/global>
profile docker-traefk flags=(attach_disconnected,mediate_deleted) {
#include <abstractions/base>
network inet tcp,
network inet udp,
network inet icmp,
deny network raw,
deny network packet,
file,
umount,
deny /bin/** wl,
deny /boot/** wl,
deny /dev/** wl,
deny /etc/** wl,
deny /home/** wl,
deny /lib/** wl,
deny /lib64/** wl,
deny /media/** wl,
deny /mnt/** wl,
deny /opt/** wl,
deny /proc/** wl,
deny /root/** wl,
deny /sbin/** wl,
deny /srv/** wl,
deny /tmp/** wl,
deny /sys/** wl,
deny /usr/** wl,
audit /** w,
/var/run/traefk.pid w,
/usr/sbin/traefk ix,
deny /bin/dash mrwklx,
deny /bin/sh mrwklx,
deny /usr/bin/top mrwklx,
capability chown,
capability dac_override,
capability setuid,
capability setgid,
capability net_bind_service,
deny @{PROC}/* w, # deny write for all files directly in /proc (not in a subdir)
# deny write to files not in /proc/<number>/** or /proc/sys/**
deny @{PROC}/{[^1-9],[^1-9][^0-9],[^1-9s][^0-9y][^0-9s],[^1-9][^0-9][^0-9][^0-9]*}/** w,
deny @{PROC}/sys/[^k]** w, # deny /proc/sys except /proc/sys/k* (effectively /proc/sys/kernel)
deny @{PROC}/sys/kernel/{?,??,[^s][^h][^m]**} w, # deny everything except shm* in /proc/sys/kernel/
deny @{PROC}/sysrq-trigger rwklx,
deny @{PROC}/mem rwklx,
deny @{PROC}/kmem rwklx,
deny @{PROC}/kcore rwklx,
deny mount,
deny /sys/[^f]*/** wklx,
deny /sys/f[^s]*/** wklx,
deny /sys/fs/[^c]*/** wklx,
deny /sys/fs/c[^g]*/** wklx,
deny /sys/fs/cg[^r]*/** wklx,
deny /sys/firmware/** rwklx,
deny /sys/kernel/security/** rwklx,
}
- Save the custom profile to disk in the
/etc/apparmor.d/containers/docker-traefk
file.The file path in this example is not a requirement. In production, you could use another. - Load the profile.
$ sudo apparmor_parser -r -W /etc/apparmor.d/containers/docker-traefk
- Run a container with the profile.To run traefk in detached mode:
$ docker run --security-opt "apparmor=docker-traefk" \ -p 80:80 -d --name apparmor-traefk traefk
- Exec into the running container.
$ docker container exec -it apparmor-traefk bash
- Try some operations to test the profile.
root@simplifier:~# ping 8.8.8.8 ping: Lacking privilege for raw socket. root@simplifier:/# top bash: /usr/bin/top: Permission denied root@simplifier:~# touch ~/thing touch: cannot touch 'thing': Permission denied root@simplifier:/# sh bash: /bin/sh: Permission denied root@simplifier:/# dash bash: /bin/dash: Permission denied
Congrats! You just deployed a container secured with a custom apparmor profile!