#97
Feature Request: Enable AppArmor support on Ubuntu playground nodes (currently blocked by SELinux)
Problem
AppArmor and SELinux are mutually exclusive Linux Security Modules. The Ubuntu-based playground nodes are configured with SELinux by default, which prevents AppArmor from being used entirely.
Error Observed on node-01
After creating profile at /etc/apparmor.d/app-profile and running:
sudo apparmor_parser -r /etc/apparmor.d/app-profileGot error:
Cache read/write disabled: interface file missing.
(Kernel needs AppArmor 2.4 compatibility patch.)
Warning: unable to find a suitable fs in /proc/mounts, is it mounted?
Use --subdomainfs to override.sudo systemctl status apparmorActive: inactive (dead)mount | grep apparmor# no output — apparmor fs not mountedRoot Cause
SELinux is active on nodes, blocking AppArmor from loading.
AppArmor requires kernel boot argument: security=apparmor
This cannot be set at runtime — needs platform-level support.
What We Were Trying to Do
Step 1: AppArmor Profile created on node-01
sudo nano /etc/apparmor.d/app-profile#include <tunables/global>
profile app-profile flags=(attach_disconnected) {
#include <abstractions/base>
#include <abstractions/nameservice>
# Allow capabilities nginx needs
capability chown,
capability dac_override,
capability setuid,
capability setgid,
capability net_bind_service,
# Entrypoint and scripts
/docker-entrypoint.sh rix,
/docker-entrypoint.d/** rix,
# Nginx binary
/usr/sbin/nginx rix,
/usr/bin/** rix,
/bin/** rix,
/sbin/** rix,
# Read access
/etc/** r,
/proc/** r,
/sys/** r,
# Nginx config and web files
/usr/share/nginx/** r,
/etc/nginx/** r,
# Nginx cache
/var/cache/nginx/ rw,
/var/cache/nginx/** rw,
# Nginx logs
/var/log/nginx/** rw,
/var/log/** rw,
# Nginx PID and run files
/tmp/** rw,
/run/** rw,
/var/run/** rw,
# Network
network inet stream,
network inet dgram,
# Dev
/dev/null rw,
/dev/zero r,
/dev/random r,
/dev/urandom r,
/dev/pts/** rw,
}Step 2: Load Profile on node-01
sudo apparmor_parser -r /etc/apparmor.d/app-profile
sudo aa-status | grep app-profileExpected output:
app-profile ✅ profile loaded in enforce modeStep 3: Kubernetes Pod YAML
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
nodeSelector:
kubernetes.io/hostname: node-01 # pin pod to node-01 where profile is loaded
securityContext:
appArmorProfile:
type: Localhost # use locally loaded profile from node-01
localhostProfile: app-profile # must match /etc/apparmor.d/app-profile on node-01
containers:
- name: app-container
image: nginxStep 4: Apply Pod
kubectl apply -f app-pod.yaml
kubectl get pod app-pod -o wideExpected output:
NAME READY STATUS RESTARTS AGE NODE
app-pod 1/1 Running 0 10s node-01 ✅ pod running on node-01Step 5: Confirm Profile Active Inside Pod
kubectl exec app-pod -- cat /proc/1/attr/currentExpected output:
app-profile (enforce) ✅ profile enforcing inside podStep 6: Test DENY — Write to Restricted Path
kubectl exec app-pod -- touch /etc/testfileExpected output:
touch: cannot touch '/etc/testfile': Permission denied ✅ blocked by AppArmorStep 7: Test ALLOW — Write to /tmp
kubectl exec app-pod -- touch /tmp/testfileExpected output:
# no error ✅ allowed by AppArmorStep 8: Kernel Audit Logs Confirm Profile Loaded on node-01
sudo dmesg | grep apparmorExpected output:
audit: type=1400 apparmor="STATUS" operation="profile_load"
profile="unconfined" name="app-profile"
comm="apparmor_parser" ✅ profile loaded into kernel
audit: type=1400 apparmor="STATUS" operation="profile_replace"
info="same as current profile, skipping"
name="app-profile"
comm="apparmor_parser" ✅ profile reloaded successfullyFeature Request
Please add boot-level support to enable AppArmor on playground nodes. This requires kernel boot argument:
security=apparmorThis is critical for practicing:
- Kubernetes AppArmor profiles (CKS exam topic)
- Pod
securityContextwithlocalhostProfile apparmor_parserprofile loading on worker nodes- Testing
enforcevscomplainmode
References
Activity
0No activity yet.