AppArmor
AppArmor, SELinux and Containers.
What is AppArmor
AppArmor (Application Armor) is a Linux kernel security module that provides mandatory access control (MAC). It enforces security policies on a per-application basis, restricting what applications can do based on defined profiles, reducing the potential harm that could be caused by compromised software.
Unlike traditional permissions, AppArmor uses profiles to define access rules, such as file access, network usage, and process execution, making it a powerful tool for enhancing system security. This approach helps in securing applications by enforcing least privilege principles, preventing unauthorized actions even if the application is exploited.
AppArmor and Containers
Containers, by design, isolate applications, but this isolation isn't foolproof. AppArmor enhances container security by applying an additional layer of defense. When integrated with container runtimes like Docker or Kubernetes, AppArmor profiles define what a containerized application can or cannot do, protecting the container and host system from potential attacks. For instance, a compromised container can be prevented from accessing sensitive files or running unauthorized commands.
Different Runtimes
-
Docker: Docker supports AppArmor directly by allowing you to specify an AppArmor profile in the container's
configuration using the
--security-opt
flag. When you run a Docker container, you can assign an AppArmor profile to limit what the container can do on the host system, enhancing security by isolating the container's capabilities. - Kubernetes: In Kubernetes, you can define security policies using PodSecurityPolicies or more recently, Pod Security Admission. While Kubernetes doesn't natively support AppArmor profiles per se, you can use annotations in your pod specifications to enforce AppArmor profiles. This integration ensures that containers run with the least privileges necessary, providing an additional layer of security within the cluster environment.
Difference Between AppArmor and SELinux in Containers
- Focus of Confinement: SELinux limits access from the container to the host system, while AppArmor restricts what binaries inside the container can access.
- Policy Complexity: SELinux uses label-based rules, whereas AppArmor uses simpler path-based rules.
- Performance: AppArmor generally has less overhead than SELinux.
- Integration: AppArmor's profiles are simpler to define and apply.
- Adoption: AppArmor is more commonly used in container environments due to its straightforward integration.
Feature | AppArmor | SELinux |
---|---|---|
Focus on Confinement | Container files | Host files |
Policy Complexity | Path-based | Label-based |
Performance | Less overhead | Higher overhead |
Integration | Simpler profiles | More complex |
Adoption in Containers | More common | Less common |
How AppArmor Profiles Look
profile mycontainer flags=(attach_disconnected) {
# Allow reading from the app's configuration file
/etc/myapp/myapp.conf r,
# Allow writing to this specific log file
/var/log/myapp.log w,
# Allow executing this binary
/usr/bin/myapp ix,
}
This profile specifies a profile named mycontainer
and grants specific permissions:
- Read permissions to configuration files.
- Write permissions to a log file.
- Execution permission for a binary.
Load and Use AppArmor Profiles
Here we explains how to load and use AppArmor profiles in various deployment environments. We'll cover the profile loading process, using profiles with Docker, Docker Compose, and Helm, and tools for managing profile loading and usage.
Loading Profiles
1. Find the profile name
head -1 ./nginx.aa
profile nginx.aa flags=(attach_disconnected) {
Remember the profile name for later use in Docker, Docker Compose, and Helm configurations.
2. Load the profile
sudo mv nginx.aa /etc/apparmor.d/
sudo apparmor_parser -r /etc/apparmor.d/nginx.aa
Placing it in /etc/apparmor.d/ ensures it loads on boot.
3. Choose the profile mode
Enforce - Blocks access files not listed in the profile.
sudo aa-enforce -d /etc/apparmor.d/ /etc/apparmor.d/nginx.aa
Complain - Logs profile violations instead of blocking:
sudo aa-complain -d /etc/apparmor.d/ /etc/apparmor.d/nginx.aa
Docker
Use the --security-opt "apparmor=<profile_name>"
flag to run a container with the loaded profile:
docker run -d --security-opt "apparmor=nginx.aa" -p 80:80 --name nginx_enforced nginx
Docker Compose
Running a container with AppArmor profile in a Docker Compose environment is as simple as adding the following to the YAML file:
security_opt:
- apparmor=nginx.aa
Example: Docker Lab: AppArmor
Helm
When using AppArmor with Helm deployments, profiles must be loaded onto each worker node as described above.
Download and extract the charts:
helm pull bitnami/apache
tar xf ./apache-*tgz
Modify the extracted values.yaml file:
sed -i "/^podAnnotations.*/ s|{}|{container.apparmor.security.beta.kubernetes.io/<CONTAINER_NAME>: localhost/<PROFILE_NAME>}|" ~/<DIRECTORY_NAME>/values.yaml
Automatically Load on Worker Nodes
To load profiles automatically, use provisioners (Terraform, Pulumi) with automation tools (Ansible, Chef). More info: Security Profiles Operator.
Summary
You can create custom profiles tailored to your containerized application, or use default profiles provided by the container runtime. Each rule in an AppArmor profile must be carefully crafted to balance security with functionality, ensuring the container can perform its intended tasks while remaining secure. For those looking to streamline this process, consider using our free SaaS solution that automatically generates AppArmor profiles for containers. Additionally, our DevOps pipeline tool can be integrated into your CI/CD pipeline to generate both AppArmor and Seccomp profiles, enhancing your container security effortlessly.