AppArmor: Configuración de Perfiles
Introducción
AppArmor (Application Armor) es un módulo de seguridad del kernel Linux que proporciona control de acceso obligatorio (MAC) a través de perfiles por programa, ofreciendo una alternativa efectiva y fácil de usar a SELinux. A diferencia del control de acceso discrecional tradicional (DAC), AppArmor confina los programas a un conjunto limitado de recursos, reduciendo significativamente el daño potencial de vulnerabilidades de seguridad o aplicaciones comprometidas.
Desarrollado originalmente por Immunix y posteriormente adquirido por Novell, AppArmor se ha convertido en el framework de seguridad predeterminado para Ubuntu, SUSE Linux Enterprise y varias otras distribuciones. Su enfoque basado en perfiles lo hace más fácil de configurar y mantener en comparación con SELinux, mientras proporciona confinamiento robusto de aplicaciones y protección del sistema.
Esta guía completa cubre todo lo que necesitas saber sobre la configuración de perfiles AppArmor, desde comprender conceptos básicos hasta crear perfiles personalizados para tus aplicaciones. Ya sea que estés asegurando un servidor web, base de datos o aplicación personalizada, esta guía proporciona el conocimiento y las técnicas prácticas necesarias para implementar AppArmor efectivamente en entornos de producción.
Comprender AppArmor y el Contexto de Seguridad
¿Qué es AppArmor?
AppArmor es un sistema de Control de Acceso Obligatorio (MAC) implementado como un Módulo de Seguridad Linux (LSM) en el kernel. Restringe programas basándose en perfiles definidos que especifican qué archivos, capacidades, acceso a red y otros recursos puede acceder cada programa.
Cómo Funciona AppArmor
AppArmor opera usando varios mecanismos clave:
1. Seguridad Basada en Rutas
A diferencia de SELinux que usa etiquetas, AppArmor usa rutas de archivos para definir controles de acceso:
/usr/bin/application {
/etc/application/config r,
/var/log/application/** w,
/home/*/.application/ rw,
}
2. Perfiles
Cada aplicación confinada tiene un perfil que define:
- Permisos de acceso a archivos (lectura, escritura, ejecución, añadir)
- Acceso a red (TCP, UDP, protocolos específicos)
- Permisos de capacidades (capacidades Linux como CAP_NET_ADMIN)
- Límites de recursos
- Ejecución de procesos hijo
3. Modos Operacionales
Los perfiles de AppArmor pueden operar en dos modos:
- Modo enforce: La política se aplica, las violaciones se bloquean y registran
- Modo complain: Las violaciones de política se registran pero se permiten (útil para desarrollo de perfiles)
4. Directivas Include
Los perfiles pueden incluir abstracciones comunes:
#include <abstractions/base>
#include <abstractions/nameservice>
Por Qué Importa AppArmor
AppArmor proporciona beneficios de seguridad significativos:
- Contención de aplicación: Limita el daño de aplicaciones comprometidas
- Protección zero-day: Reduce la efectividad de exploits incluso sin parches
- Configuración fácil: Políticas basadas en rutas son más intuitivas que sistemas basados en etiquetas
- Baja sobrecarga: Impacto mínimo en rendimiento
- Modo complain: Permite desarrollo seguro de perfiles en producción
- Compatibilidad: Funciona con aplicaciones Linux estándar sin modificación
AppArmor vs. SELinux
| Característica | AppArmor | SELinux |
|---|---|---|
| Control de Acceso | Basado en rutas | Basado en etiquetas |
| Complejidad de Configuración | Más fácil | Más complejo |
| Por defecto en | Ubuntu, SUSE | RHEL, CentOS, Fedora |
| Curva de Aprendizaje | Moderada | Pronunciada |
| Flexibilidad | Buena | Excelente |
| Desarrollo de Política | Más simple | Más potente pero complejo |
Casos de Uso Comunes
- Confinar servidores web (Apache, Nginx)
- Asegurar servidores de base de datos (MySQL, PostgreSQL)
- Proteger servicios de red (OpenSSH, DNS, servidores de correo)
- Aislar aplicaciones containerizadas
- Restringir aplicaciones personalizadas
- Cumplimiento con frameworks de seguridad
Prerrequisitos
Antes de configurar perfiles AppArmor, asegúrate de tener:
Requisitos del Sistema
- Sistema Operativo: Ubuntu, Debian, SUSE Linux Enterprise, openSUSE, u otra distribución habilitada con AppArmor
- Kernel: Kernel Linux 2.6.36 o posterior con soporte AppArmor
- Acceso Root: Privilegios administrativos requeridos
- Espacio en Disco: Espacio adecuado para logs y archivos de perfiles
Conocimiento Requerido
- Administración básica de sistemas Linux
- Comprensión de permisos y rutas de archivos
- Competencia en línea de comandos
- Familiaridad con servicios del sistema
- Comprensión básica de conceptos de seguridad Linux
Requisitos de Software
Ubuntu/Debian:
sudo apt-get update
sudo apt-get install apparmor apparmor-utils apparmor-profiles apparmor-profiles-extra
SUSE/openSUSE:
sudo zypper install apparmor-parser apparmor-profiles apparmor-utils
Verificación:
sudo aa-status
Verificar que AppArmor está Activo
Verificar que AppArmor está cargado:
sudo systemctl status apparmor
Verificar módulo del kernel:
sudo cat /sys/module/apparmor/parameters/enabled
Debería devolver Y
Ver sistema de archivos AppArmor:
sudo ls /sys/kernel/security/apparmor/
Configuración Paso a Paso de Perfiles AppArmor
Paso 1: Verificar el Estado de AppArmor
Ver estado detallado de AppArmor:
sudo aa-status
Salida esperada:
apparmor module is loaded.
50 profiles are loaded.
40 profiles are in enforce mode.
/sbin/dhclient
/usr/bin/man
/usr/lib/NetworkManager/nm-dhcp-client.action
...
10 profiles are in complain mode.
/usr/bin/firefox
/usr/sbin/mysqld
...
5 processes have profiles defined.
5 processes are in enforce mode.
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.
Verificar si un perfil específico está cargado:
sudo aa-status | grep nginx
Ver modo del perfil:
sudo aa-status --pretty-print
Paso 2: Comprender las Ubicaciones de Perfiles
Directorios de perfiles del sistema:
/etc/apparmor.d/: Directorio principal para perfiles/etc/apparmor.d/abstractions/: Componentes de política reutilizables/etc/apparmor.d/tunables/: Definiciones de variables/etc/apparmor.d/disable/: Perfiles deshabilitados/etc/apparmor.d/local/: Personalizaciones locales
Ver perfiles disponibles:
ls -l /etc/apparmor.d/
Ver abstracciones de perfiles:
ls -l /etc/apparmor.d/abstractions/
Paso 3: Leer y Comprender un Perfil Existente
Ver un perfil de ejemplo (Nginx):
sudo cat /etc/apparmor.d/usr.sbin.nginx
Ejemplo de estructura de perfil:
#include <tunables/global>
/usr/sbin/nginx {
#include <abstractions/base>
#include <abstractions/nameservice>
#include <abstractions/openssl>
capability dac_override,
capability net_bind_service,
capability setgid,
capability setuid,
/usr/sbin/nginx mr,
/etc/nginx/** r,
/etc/ssl/openssl.cnf r,
/var/log/nginx/* w,
/var/www/html/** r,
/run/nginx.pid rw,
# Local customizations
#include <local/usr.sbin.nginx>
}
Componentes del perfil explicados:
#include <tunables/global>: Variables globales#include <abstractions/...>: Componentes de política comunescapability: Capacidades Linux que el programa necesita- Rutas de archivos con permisos:
r: lecturaw: escrituram: mapeo de memoriax: ejecutarix: heredar ejecución (heredar perfil padre)px: perfil de ejecución (usar perfil del hijo)ux: ejecución sin confinar (sin perfil)
Paso 4: Generar un Perfil Automáticamente
Usar aa-genprof para crear un nuevo perfil:
sudo aa-genprof /usr/bin/myapp
Esto lanza una herramienta interactiva de generación de perfiles:
- Iniciar la aplicación en otra terminal
- Ejercitar toda la funcionalidad de la aplicación
- Volver a la terminal aa-genprof y presionar 'S' para escanear logs
- Revisar reglas sugeridas y aceptar/rechazar cada una
- Guardar el perfil cuando esté completo
La herramienta solicitará decisiones:
Profile: /usr/bin/myapp
Execute: /etc/myapp/script.sh
(I)nherit / (P)rofile / (U)nconfined / (X) ix On / (D)eny / Abo(r)t / (F)inish
- (I)nherit: Usar perfil padre
- (P)rofile: Usar perfil separado
- (U)nconfined: Sin restricción
- (D)eny: Bloquear acceso
Paso 5: Crear un Perfil Manualmente
Crear un perfil básico para una aplicación personalizada:
sudo nano /etc/apparmor.d/usr.local.bin.myapp
Plantilla de perfil básico:
#include <tunables/global>
/usr/local/bin/myapp {
#include <abstractions/base>
#include <abstractions/nameservice>
# Executable
/usr/local/bin/myapp mr,
# Configuration files
/etc/myapp/** r,
/etc/myapp/config rw,
# Data directories
/var/lib/myapp/** rw,
# Log files
/var/log/myapp/* w,
/var/log/myapp/** rw,
# Temporary files
/tmp/myapp-* rw,
/run/myapp.pid rw,
# Capabilities
capability dac_override,
capability net_bind_service,
# Network access
network inet stream,
network inet dgram,
# Child processes
/usr/bin/bash ix,
/usr/bin/cat rix,
# Local customizations
#include <local/usr.local.bin.myapp>
}
Guardar y cargar el perfil:
sudo apparmor_parser -r /etc/apparmor.d/usr.local.bin.myapp
Paso 6: Cambiar Perfiles Entre Modos Enforce y Complain
Poner un perfil en modo complain:
sudo aa-complain /usr/sbin/nginx
Poner un perfil en modo enforce:
sudo aa-enforce /usr/sbin/nginx
Poner todos los perfiles en modo complain:
sudo aa-complain /etc/apparmor.d/*
Verificar cambio de modo:
sudo aa-status
Paso 7: Probar y Refinar Perfiles
Poner perfil en modo complain para pruebas:
sudo aa-complain /usr/local/bin/myapp
Monitorizar denegaciones en tiempo real:
sudo tail -f /var/log/syslog | grep DENIED
O en sistemas usando journald:
sudo journalctl -f | grep DENIED
Ejercitar la aplicación:
Probar toda la funcionalidad para generar logs completos.
Usar aa-logprof para actualizar perfil:
sudo aa-logprof
Esta herramienta:
- Analiza logs para denegaciones de AppArmor
- Sugiere adiciones a perfiles
- Permite aprobar/rechazar cada sugerencia
- Actualiza perfiles automáticamente
Después del refinamiento, cambiar a modo enforce:
sudo aa-enforce /usr/local/bin/myapp
Paso 8: Deshabilitar o Eliminar Perfiles
Deshabilitar un perfil (mover a directorio disabled):
sudo aa-disable /usr/sbin/nginx
Esto crea un enlace simbólico en /etc/apparmor.d/disable/
Re-habilitar un perfil deshabilitado:
sudo aa-enforce /usr/sbin/nginx
Eliminar un perfil completamente:
sudo rm /etc/apparmor.d/usr.sbin.nginx
sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.nginx
Descargar un perfil del kernel:
sudo aa-remove-unknown
Paso 9: Crear Personalizaciones Locales
En lugar de modificar perfiles principales, usar includes locales:
sudo nano /etc/apparmor.d/local/usr.sbin.nginx
Añadir reglas personalizadas:
# Allow access to custom web directory
/srv/www/** r,
# Allow PHP-FPM socket
/run/php/php8.1-fpm.sock rw,
# Custom log location
/custom/logs/nginx/* w,
Recargar el perfil:
sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.nginx
Las personalizaciones locales sobreviven a actualizaciones de paquetes.
Consejos Avanzados de Hardening con AppArmor
1. Usar Abstracciones Efectivamente
Abstracciones útiles comunes:
#include <abstractions/base> # Essential system files
#include <abstractions/nameservice> # DNS, NSS lookups
#include <abstractions/ssl_certs> # SSL certificate access
#include <abstractions/openssl> # OpenSSL libraries
#include <abstractions/mysql> # MySQL client
#include <abstractions/php> # PHP execution
#include <abstractions/apache2-common> # Apache common files
Ver contenidos de abstracción:
cat /etc/apparmor.d/abstractions/base
2. Implementar Restricciones de Red
Restringir acceso a red con precisión:
# Allow only IPv4 TCP
network inet stream,
# Allow only IPv6 UDP
network inet6 dgram,
# Allow Unix domain sockets
network unix stream,
# Deny all other network
deny network,
Restricciones específicas de protocolo:
network inet stream tcp,
network inet dgram udp,
network netlink raw,
3. Usar Variables de Perfil (Tunables)
Definir variables en /etc/apparmor.d/tunables/myapp:
@{MYAPP_HOME}=/opt/myapp
@{MYAPP_CONFIG}=/etc/myapp
@{MYAPP_DATA}=/var/lib/myapp
Usar en perfiles:
#include <tunables/myapp>
/usr/local/bin/myapp {
@{MYAPP_CONFIG}/** r,
@{MYAPP_DATA}/** rw,
@{MYAPP_HOME}/bin/* rix,
}
4. Implementar Transiciones de Perfil Hijo
Definir perfil hijo para scripts:
/usr/local/bin/myapp {
# Main application rules
/usr/local/bin/myapp mr,
# Execute helper script with separate profile
/usr/local/bin/helper.sh px -> myapp_helper,
}
profile myapp_helper {
#include <abstractions/base>
#include <abstractions/bash>
/usr/local/bin/helper.sh r,
/tmp/helper-* rw,
}
5. Usar Reglas Condicionales
Reglas específicas de plataforma:
#include <tunables/global>
/usr/bin/myapp {
#include <abstractions/base>
# Common rules
/usr/bin/myapp mr,
# Conditional include based on distribution
#include if exists <local/usr.bin.myapp>
}
6. Implementar Reglas de Denegación
Denegar explícitamente rutas sensibles:
/usr/local/bin/myapp {
#include <abstractions/base>
# Normal access
/etc/myapp/** r,
# Explicitly deny sensitive files
deny /etc/shadow r,
deny /etc/gshadow r,
deny /etc/ssh/ssh_host_* r,
# Deny write to config
deny /etc/myapp/secure.conf w,
}
7. Implementar Bloqueo de Archivos
Permitir operaciones específicas de archivo:
/var/lib/myapp/database.db rwk,
Permisos:
r: lecturaw: escriturak: bloqueol: enlace
8. Apilamiento de Perfiles para Contenedores
Crear perfiles conscientes de contenedores:
profile docker-default flags=(attach_disconnected,mediate_deleted) {
#include <abstractions/base>
network,
capability,
file,
umount,
deny @{PROC}/* w,
deny @{PROC}/{[^1]*,1/[^s]*,1/s[^y]*} w,
}
Verificación y Pruebas
Verificar Sintaxis del Perfil
Probar sintaxis del perfil antes de cargarlo:
sudo apparmor_parser -p /etc/apparmor.d/usr.local.bin.myapp
Dry-run de carga de perfil:
sudo apparmor_parser -n -r /etc/apparmor.d/usr.local.bin.myapp
Probar Aplicación del Perfil
Iniciar aplicación y verificar su confinamiento:
ps auxZ | grep myapp
Debería mostrar el nombre del perfil en lugar de unconfined.
Verificar contexto del proceso:
cat /proc/$(pidof myapp)/attr/current
Monitorizar Violaciones del Perfil
Monitorización en tiempo real:
sudo tail -f /var/log/syslog | grep apparmor
O con journald:
sudo journalctl -f | grep apparmor
Buscar denegaciones específicas:
sudo grep DENIED /var/log/syslog | grep myapp
Analizar denegaciones con aa-notify:
sudo aa-notify -p -f /var/log/syslog
Verificar Actualizaciones de Perfil
Después de hacer cambios, verificar recarga:
sudo apparmor_parser -r /etc/apparmor.d/usr.local.bin.myapp
sudo aa-status | grep myapp
Verificar caché de perfil:
ls -l /var/cache/apparmor/
Probar Funcionalidad Completa de la Aplicación
Lista de verificación de pruebas:
- Iniciar aplicación y verificar que funciona
- Probar todas las características principales
- Verificar operaciones denegadas en logs
- Verificar que procesos hijo funcionan correctamente
- Probar conectividad de red si se requiere
- Verificar permisos de acceso a archivos
- Verificar requisitos de capacidades
Solución de Problemas Comunes
Problema 1: Error de Sintaxis del Perfil
Síntomas: Errores del parser al cargar perfil
Soluciones:
-
Verificar sintaxis:
sudo apparmor_parser -p /etc/apparmor.d/usr.bin.myapp -
Problemas de sintaxis comunes:
- Coma faltante después de permisos
- Llaves sin cerrar
- Caracteres de permiso inválidos
- Formato de ruta incorrecto
-
Ejemplo de corrección:
# Wrong /etc/myapp/config rw # Correct /etc/myapp/config rw,
Problema 2: La Aplicación No Inicia
Síntomas: La aplicación falla al lanzar con AppArmor cargado
Soluciones:
-
Verificar denegaciones inmediatamente:
sudo tail -20 /var/log/syslog | grep DENIED -
Poner perfil en modo complain:
sudo aa-complain /usr/bin/myapp -
Iniciar aplicación y monitorizar:
sudo journalctl -f | grep apparmor -
Actualizar perfil con aa-logprof:
sudo aa-logprof -
Volver a modo enforce después de correcciones:
sudo aa-enforce /usr/bin/myapp
Problema 3: Errores de Permiso Denegado
Síntomas: La aplicación funciona pero falla en operaciones específicas
Soluciones:
-
Identificar permiso faltante:
sudo grep "myapp" /var/log/syslog | grep DENIED | tail -5 -
Añadir a perfil local:
sudo nano /etc/apparmor.d/local/usr.bin.myapp -
Añadir la ruta/capacidad denegada:
/path/to/denied/file rw, -
Recargar perfil:
sudo apparmor_parser -r /etc/apparmor.d/usr.bin.myapp
Problema 4: Perfil No Se Carga
Síntomas: El perfil existe pero no aparece en aa-status
Soluciones:
-
Cargar perfil manualmente:
sudo apparmor_parser -a /etc/apparmor.d/usr.bin.myapp -
Verificar errores:
sudo systemctl status apparmor -
Verificar que el perfil no está deshabilitado:
ls /etc/apparmor.d/disable/ -
Reiniciar servicio AppArmor:
sudo systemctl restart apparmor
Problema 5: Fallos de Procesos Hijo
Síntomas: La aplicación principal funciona, pero los procesos hijo fallan
Soluciones:
-
Verificar denegaciones de proceso hijo:
sudo grep DENIED /var/log/syslog | grep exec -
Añadir regla de ejecución apropiada:
# Inherit parent profile /usr/bin/child ix, # Use child's profile /usr/bin/child px, # Unconfined execution (less secure) /usr/bin/child ux, -
Crear perfil hijo separado si es necesario:
profile myapp_child { #include <abstractions/base> /usr/bin/child mr, }
Problema 6: Acceso a Red Denegado
Síntomas: La aplicación no puede conectarse a la red
Soluciones:
-
Verificar denegaciones de red:
sudo grep DENIED /var/log/syslog | grep network -
Añadir permisos de red:
network inet stream, network inet6 stream, -
Para protocolos específicos:
network inet stream tcp, network inet dgram udp,
Problema 7: Denegaciones de Capacidad
Síntomas: Operaciones que requieren capacidades Linux fallan
Soluciones:
-
Identificar capacidad requerida:
sudo grep "capability" /var/log/syslog | grep DENIED -
Añadir a perfil:
capability net_bind_service, capability sys_admin, -
Capacidades comunes:
dac_override: Bypass de permisos de archivonet_bind_service: Bind a puertos < 1024setuid/setgid: Cambiar usuario/gruposys_admin: Varias operaciones de admin
Mejores Prácticas para Gestión de AppArmor
1. Flujo de Trabajo de Desarrollo de Perfiles
- Comenzar en modo complain durante desarrollo
- Ejercitar toda la funcionalidad para capturar patrones de acceso completos
- Revisar y refinar usando aa-logprof
- Probar exhaustivamente en modo complain
- Habilitar modo enforce después de validación
- Monitorizar producción para denegaciones inesperadas
- Iterar según necesario al añadir características
2. Organización de Perfiles
- Usar abstracciones para patrones comunes
- Crear includes locales para personalizaciones
- Usar variables para rutas que puedan cambiar
- Documentar reglas inusuales con comentarios
- Control de versiones de archivos de perfiles
- Organizar por aplicación o tipo de servicio
3. Hardening de Seguridad
- Principio de mínimo privilegio: Otorgar acceso mínimo necesario
- Denegaciones explícitas: Denegar acceso a archivos sensibles del sistema
- Evitar ejecución sin confinar: Usar ix o px en lugar de ux
- Restringir capacidades: Solo otorgar capacidades requeridas
- Restricciones de red: Limitar acceso a red por protocolo/tipo
- Auditorías regulares: Revisar perfiles trimestralmente
4. Prácticas Operacionales
- Monitorizar regularmente: Configurar monitorización de logs para denegaciones
- Probar actualizaciones: Probar cambios de perfil en no-producción primero
- Backup de perfiles: Mantener backups antes de modificaciones
- Documentación: Documentar por qué existen reglas específicas
- Despliegue gradual: Implementar nuevos perfiles incrementalmente
5. Consideraciones de Rendimiento
- Caché de perfiles: AppArmor cachea perfiles compilados para rendimiento
- Evitar comodines excesivos: Reglas más específicas tienen mejor rendimiento
- Usar abstracciones: Abstracciones compartidas se cachean
- Monitorizar sobrecarga: Generalmente mínima pero monitorizar en entornos de alto rendimiento
6. Cumplimiento y Auditoría
- Inventario de perfiles: Mantener lista de todos los perfiles personalizados
- Gestión de cambios: Rastrear todas las modificaciones de perfiles
- Revisiones regulares: Auditar perfiles para permisos innecesarios
- Mapeo de cumplimiento: Documentar cómo los perfiles cumplen requisitos de seguridad
- Respuesta a incidentes: Incluir logs de AppArmor en investigaciones de seguridad
7. Seguridad de Contenedores
- Perfil de contenedor por defecto: Usar docker-default o perfiles personalizados
- Integración Kubernetes: Usar anotaciones AppArmor
- Perfil por contenedor: Crear perfiles específicos para aplicaciones de contenedor
- Probar en desarrollo: Verificar perfiles en entornos de desarrollo
Conclusión
AppArmor proporciona control de acceso obligatorio potente basado en rutas que mejora la seguridad de Linux mediante confinamiento de aplicaciones. Su sintaxis de perfil intuitiva y modo complain lo hacen más accesible que alternativas como SELinux, mientras proporciona protección robusta contra aplicaciones comprometidas y vulnerabilidades de seguridad.
Conclusiones clave:
- Enfoque basado en rutas: Más fácil de entender y configurar que sistemas basados en etiquetas
- Modo complain: Invaluable para desarrollo y pruebas seguras de perfiles
- Flexibilidad de perfiles: Soporta niveles variables de restricción por aplicación
- Personalizaciones locales: Preservar personalizaciones a través de actualizaciones
- Rendimiento: Sobrecarga mínima con beneficios de seguridad significativos
- Herramientas completas: aa-genprof, aa-logprof y aa-status simplifican la gestión
Siguiendo las prácticas delineadas en esta guía, implementas confinamiento efectivo de aplicaciones que reduce significativamente tu superficie de ataque. AppArmor es particularmente valioso para:
- Confinar servicios expuestos a red
- Proteger contra exploits zero-day
- Implementar seguridad de defensa en profundidad
- Cumplir requisitos de cumplimiento
- Asegurar aplicaciones containerizadas
Recuerda que AppArmor es más efectivo cuando los perfiles son:
- Desarrollados con comprensión completa del comportamiento de la aplicación
- Probados exhaustivamente en modo complain antes de la aplicación
- Revisados y actualizados regularmente a medida que evolucionan las aplicaciones
- Monitorizados para denegaciones que puedan indicar ataques o configuraciones incorrectas
Comienza con perfiles proporcionados por el sistema para aplicaciones comunes, personalízalos a tus necesidades usando includes locales y gradualmente extiende la protección de AppArmor a aplicaciones personalizadas. Con implementación y mantenimiento adecuados, AppArmor se convierte en un componente invaluable de tu estrategia de seguridad, proporcionando fuerte aislamiento de aplicaciones con sobrecarga administrativa manejable.


