Stage 3 · Build
Observability, Tracing & Security
Seccomp, AppArmor & SELinux
Syscall filtering, mandatory access control, and container security — defense in depth.
seccomp
seccomp (secure computing) restricts which system calls a process can make. In filter mode, eBPF programs decide per-syscall whether to allow, deny, or log. Docker, systemd, and Chrome all use seccomp to sandbox untrusted code.
# Check seccomp status of a process
grep Seccomp /proc/self/status
# Seccomp: 0 (disabled)
# Seccomp_filters: 0
# Docker uses seccomp by default
docker run --rm alpine cat /proc/1/status | grep Seccomp
# Seccomp: 2 (filter mode)
# Seccomp_filters: 1
# Run without seccomp (DANGEROUS)
docker run --rm --security-opt seccomp=unconfined alpine sh
# Use a custom profile
docker run --rm --security-opt seccomp=my-profile.json alpine shseccomp mode 0 is disabled, 1 is strict (only read/write/exit/sigreturn), and 2 is filter mode (BPF programs per-syscall).
# The default Docker profile blocks ~44 syscalls including:
# - reboot, kexec_load
# - mount, umount2
# - ptrace
# - keyctl
# - add_key, request_key
# - bpf (unless privileged)
# - userfaultfd
# View the default profile
wget https://raw.githubusercontent.com/moby/moby/master/profiles/seccomp/default.jsonThe default Docker profile is conservative. For most applications, it provides adequate protection without modification.
AppArmor
AppArmor is a Linux security module that confines programs using per-application profiles. Profiles specify which files, capabilities, and network access a program can use. It is path-based and simpler to configure than SELinux.
# Check AppArmor status
sudo aa-status
# apparmor module is loaded.
# 37 profiles are loaded.
# 36 profiles are in enforce mode.
# 1 profiles are in complain mode.
# Set a profile to enforce
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
# Set a profile to complain (log only)
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx
# Reload a profile
sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.nginx
# Disable a profile
sudo ln -s /etc/apparmor.d/usr.sbin.nginx /etc/apparmor.d/disable/
sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.nginxAppArmor is the default LSM on Ubuntu and SUSE. Profiles are stored in /etc/apparmor.d/. Complain mode logs violations without enforcing.
SELinux
SELinux (Security-Enhanced Linux) provides mandatory access control through security labels on every file, process, and port. It is label-based and more granular than AppArmor but more complex to configure.
# Check SELinux status
getenforce
# Enforcing
# View security context
ls -Z /var/www/html
# system_u:object_r:httpd_sys_content_t:s0 index.html
# Change context
sudo chcon -t httpd_sys_content_t /var/www/html/custom.html
# Restore default context
sudo restorecon -Rv /var/www/html
# Set permissive for debugging
sudo setenforce 0
# Switch back to enforcing
sudo setenforce 1
# View denial logs
sudo ausearch -m AVC -ts recentSELinux labels (type enforcement) control what process types can access which file types. The three components are user:role:type:level.
Comparing LSMs
| Feature | seccomp | AppArmor | SELinux |
|---|---|---|---|
| Scope | Syscalls only | Files, capabilities, network | Everything |
| Configuration | JSON profiles | Text profiles | Labels + policies |
| Complexity | Low | Medium | High |
| Default distro | Docker/systemd | Ubuntu, SUSE | RHEL, Fedora |
| Granularity | Per-syscall | Per-path | Per-label |
| Container use | All runtimes | Kubernetes | RHEL-based |
Container Security
- Enable seccomp for all containers (default in Docker)
- Use AppArmor or SELinux for file and capability restrictions
- Drop all capabilities and add only what is needed
- Run as non-root user inside the container
- Use read-only root filesystems
- Enable user namespace remapping
Testing Policies
# Test seccomp profile
docker run --rm --security-opt seccomp=my-profile.json alpine echo test
# Test AppArmor in complain mode
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx
# Run application and check logs for violations
sudo journalctl -k | grep "apparmor"
# Test SELinux in permissive mode
sudo setenforce 0
# Run application and check for AVC denials
sudo ausearch -m AVC -ts recent
# Audit system calls
sudo auditctl -a always,exit -F arch=b64 -S mount -k mount_attempt
sudo ausearch -k mount_attemptAlways test security policies in permissive/complain mode first. Once verified, switch to enforce mode. Monitor logs for unexpected denials.
Use seccomp + AppArmor/SELinux + capabilities + namespaces for defense in depth. No single mechanism provides complete protection.
When SELinux denies access, the service fails silently. Check audit.log for AVC denials when services behave unexpectedly. Use audit2why to understand the denial.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.