--- title: "Cómo crear y gestionar perfiles AppArmor en Ubuntu 24.04" description: "Revisa el estado de AppArmor en Ubuntu 24.04, escribe un perfil para confinar un programa, pásalo entre modo complain y enforce y ajusta perfiles del sistema." category: "Seguridad del Servidor" language: es source: https://cubepath.com/es/docs/seguridad-del-servidor/configuracion-de-perfiles-apparmor updated: 2026-09-25 --- # Cómo crear y gestionar perfiles AppArmor en Ubuntu 24.04 AppArmor es el módulo de seguridad del kernel que Ubuntu y Debian activan por defecto para aplicar control de acceso obligatorio (MAC). A diferencia de SELinux, que etiqueta cada archivo, AppArmor funciona con perfiles basados en rutas: cada perfil indica qué archivos, capacidades y accesos de red puede usar un programa concreto, y todo lo demás se deniega. En este tutorial comprobarás el estado de AppArmor en Ubuntu 24.04, escribirás un perfil desde cero para confinar un script, lo probarás en modo complain y enforce, y aprenderás a ajustar los perfiles que instalan los paquetes sin modificar sus archivos. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath. - Un usuario no root con privilegios `sudo`. - Conocimientos básicos de la línea de comandos y de un editor como `nano`. ## Conceptos básicos - **Perfil**: archivo de texto en `/etc/apparmor.d/` que define los permisos de un programa. Por convención se nombra con la ruta del ejecutable cambiando `/` por `.`, por ejemplo `usr.sbin.mysqld`. - **Modo enforce**: el perfil se aplica y las acciones no permitidas se bloquean y se registran. - **Modo complain**: el perfil no bloquea nada, solo registra lo que habría denegado. Sirve para desarrollar y ajustar perfiles. - **Abstracciones**: fragmentos reutilizables en `/etc/apparmor.d/abstractions/` (por ejemplo `base`, `nameservice` o `ssl_certs`) que agrupan los accesos que casi todos los programas necesitan. - **Overrides locales**: archivos en `/etc/apparmor.d/local/` que los perfiles del sistema incluyen, pensados para añadir permisos sin editar el perfil original. Los permisos de archivo más usados son `r` (leer), `w` (escribir), `a` (añadir), `k` (bloquear), `m` (mapear como ejecutable) e `ix` (ejecutar otro programa heredando el mismo perfil). ## Paso 1: Comprobar el estado de AppArmor Instala las utilidades de administración. El paquete `apparmor` ya viene instalado, pero `apparmor-utils` añade `aa-complain`, `aa-enforce`, `aa-genprof` y `aa-logprof`: ```bash sudo apt update sudo apt install apparmor-utils ``` Comprueba que el servicio está activo y qué perfiles hay cargados: ```bash systemctl is-active apparmor sudo aa-status ``` ```output apparmor module is loaded. 112 profiles are loaded. 33 profiles are in enforce mode. /usr/bin/man /usr/lib/snapd/snap-confine rsyslogd ... 0 profiles are in complain mode. 3 processes have profiles defined. 3 processes are in enforce mode. /usr/sbin/rsyslogd (812) rsyslogd ... ``` Las cifras varían según los paquetes instalados. La parte útil es la lista de procesos confinados y el modo de cada uno. Para ver con qué perfil corre cada proceso, usa `ps` con la columna de etiqueta: ```bash ps -eo label,pid,comm | grep -v unconfined ``` ## Paso 2: Crear un programa de ejemplo Para trabajar con un caso controlado, crea un pequeño script que genera un informe del sistema y lo guarda en `/var/lib/reportgen`. Acepta una ruta de salida opcional, lo que te permitirá comprobar después que el perfil impide escribir fuera de su directorio. ```bash sudo nano /usr/local/bin/reportgen ``` ```bash #!/usr/bin/bash set -euo pipefail out="${1:-/var/lib/reportgen/report.txt}" { echo "Host: $(cat /etc/hostname)" echo "Kernel: $(uname -r)" echo "Fecha: $(date --iso-8601=seconds)" } > "$out" echo "Informe escrito en $out" ``` Hazlo ejecutable, crea el directorio de salida y pruébalo sin perfil: ```bash sudo chmod 755 /usr/local/bin/reportgen sudo mkdir -p /var/lib/reportgen sudo /usr/local/bin/reportgen sudo /usr/local/bin/reportgen /etc/reportgen-test.txt ``` ```output Informe escrito en /var/lib/reportgen/report.txt Informe escrito en /etc/reportgen-test.txt ``` Sin confinamiento, un script que se ejecuta como root puede escribir en cualquier parte. Borra el archivo de prueba: ```bash sudo rm /etc/reportgen-test.txt ``` ## Paso 3: Escribir el perfil Crea el perfil en `/etc/apparmor.d/` siguiendo la convención de nombres: ```bash sudo nano /etc/apparmor.d/usr.local.bin.reportgen ``` ```text abi , include profile reportgen /usr/local/bin/reportgen { include include include # El propio script y los binarios que ejecuta /usr/local/bin/reportgen r, /usr/bin/bash ix, /usr/bin/{cat,date,uname} ix, # Datos que lee y escribe /etc/hostname r, /var/lib/reportgen/ r, /var/lib/reportgen/** rw, include if exists } ``` Qué hace cada parte: - `abi ` fija la versión de las reglas; Ubuntu 24.04 incluye AppArmor 4. - `profile reportgen /usr/local/bin/reportgen` da nombre al perfil y lo asocia a esa ruta. - Las abstracciones `base`, `bash` y `consoles` cubren bibliotecas, locales, archivos de inicio de Bash y la terminal. - `ix` permite ejecutar `bash`, `cat`, `date` y `uname` dentro del mismo perfil, así heredan las mismas restricciones. - Solo se permite leer `/etc/hostname` y escribir dentro de `/var/lib/reportgen/`. - La última línea incluye un override local si existe, igual que hacen los perfiles del sistema. Carga el perfil en el kernel. `apparmor_parser -r` lo compila y lo reemplaza si ya estaba cargado; si hay un error de sintaxis, te dirá la línea: ```bash sudo apparmor_parser -r /etc/apparmor.d/usr.local.bin.reportgen sudo aa-status | grep reportgen ``` ```output reportgen ``` Los perfiles nuevos se cargan en modo enforce. ## Paso 4: Probar el perfil en modo enforce Ejecuta el script con la ruta permitida: ```bash sudo /usr/local/bin/reportgen cat /var/lib/reportgen/report.txt ``` ```output Informe escrito en /var/lib/reportgen/report.txt Host: servidor01 Kernel: 6.8.0-45-generic Fecha: 2026-09-25T10:15:02+00:00 ``` Ahora intenta escribir fuera de su directorio, aunque lo ejecutes como root: ```bash sudo /usr/local/bin/reportgen /etc/reportgen-test.txt ``` ```output /usr/local/bin/reportgen: line 10: /etc/reportgen-test.txt: Permission denied ``` La denegación queda registrada en el log del kernel: ```bash sudo journalctl -k --since "5 minutes ago" | grep 'apparmor="DENIED"' ``` ```output audit: type=1400 audit(1727259302.512:210): apparmor="DENIED" operation="mknod" class="file" profile="reportgen" name="/etc/reportgen-test.txt" pid=4312 comm="reportgen" requested_mask="c" denied_mask="c" fsuid=0 ouid=0 ``` Los campos clave son `profile` (qué perfil denegó), `name` (el recurso) y `denied_mask` (el permiso que faltaba: `c` crear, `r` leer, `w` escribir, `x` ejecutar). ## Paso 5: Ajustar un perfil con el modo complain Cuando confinas un programa real no sueles conocer de antemano todo lo que necesita. El flujo recomendado es poner el perfil en complain, usar el programa con normalidad y dejar que `aa-logprof` proponga las reglas que faltan. Supón que el script tiene que leer también `/etc/os-release`. Añade esta línea dentro del bloque `{ }` del script, justo después del echo del kernel: ```bash echo "Sistema: $(grep PRETTY_NAME /etc/os-release)" ``` Pon el perfil en complain y ejecuta el script: ```bash sudo aa-complain /usr/local/bin/reportgen sudo /usr/local/bin/reportgen ``` En complain el script funciona, pero cada acceso no previsto se registra con `apparmor="ALLOWED"`. Revisa esos eventos con `aa-logprof`, que lee los logs del sistema y te pregunta regla por regla: ```bash sudo aa-logprof ``` Para cada evento puedes elegir `(A)llow` para aceptar la regla propuesta, `(D)eny` para denegarla explícitamente o `(G)lob` para generalizar la ruta. Al final pulsa `S` para guardar los cambios en el perfil. Comprueba el resultado y vuelve a enforce: ```bash sudo cat /etc/apparmor.d/usr.local.bin.reportgen sudo aa-enforce /usr/local/bin/reportgen ``` > Consejo: para un programa nuevo sin ningún perfil, `sudo aa-genprof /ruta/al/programa` crea un perfil básico, lo pone en complain y te guía para ejecutar el programa en otra terminal y responder a las preguntas. Es el mismo flujo que `aa-logprof`, pero partiendo de cero. ## Paso 6: Ajustar perfiles del sistema con overrides locales Los paquetes instalan sus propios perfiles, y si los editas directamente, la próxima actualización puede sobrescribir tus cambios. Por eso casi todos incluyen una línea como `include if exists ` para que añadas permisos en `/etc/apparmor.d/local/`. Un ejemplo típico: mueves el directorio de datos de MySQL a `/srv/mysql` y el servicio deja de arrancar porque el perfil `usr.sbin.mysqld` no permite esa ruta. Con MySQL instalado desde los repositorios de Ubuntu, edita el override local: ```bash sudo nano /etc/apparmor.d/local/usr.sbin.mysqld ``` ```text /srv/mysql/ r, /srv/mysql/** rwk, ``` Recarga el perfil principal, que incluye el override: ```bash sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld sudo systemctl restart mysql ``` El mismo patrón sirve para cualquier perfil del sistema: busca la línea `include if exists ` en el perfil y crea ese archivo. ## Paso 7: Desactivar o eliminar un perfil Si un perfil da problemas y necesitas desactivarlo mientras lo investigas, prefiere el modo complain, que sigue registrando. Si realmente necesitas desactivarlo, usa `aa-disable`, que descarga el perfil y crea un enlace en `/etc/apparmor.d/disable/` para que no se cargue en el siguiente arranque: ```bash sudo aa-disable /usr/local/bin/reportgen ``` Para reactivarlo, elimina el enlace y vuelve a cargarlo: ```bash sudo rm /etc/apparmor.d/disable/usr.local.bin.reportgen sudo apparmor_parser -r /etc/apparmor.d/usr.local.bin.reportgen ``` Para eliminar el perfil de ejemplo por completo: ```bash sudo apparmor_parser -R /etc/apparmor.d/usr.local.bin.reportgen sudo rm /etc/apparmor.d/usr.local.bin.reportgen ``` ## Solución de problemas - **`apparmor_parser` muestra un error de sintaxis**: revisa la línea indicada. Los errores más comunes son olvidar la coma al final de una regla o cerrar mal las llaves. - **El programa falla sin mensaje claro**: busca denegaciones con `sudo journalctl -k | grep 'apparmor="DENIED"'` filtrando por el nombre del perfil. Si no aparece nada, AppArmor no es la causa. - **`aa-logprof` no encuentra eventos**: lee `/var/log/syslog` o, si tienes `auditd` instalado, `/var/log/audit/audit.log`. Si usas otro log, indícalo con `sudo aa-logprof -f /ruta/al/log`. - **Un cambio en el perfil no tiene efecto**: los cambios en disco no se aplican hasta recargar el perfil con `sudo apparmor_parser -r` o reiniciar el servicio `apparmor`. Los procesos que ya estaban en ejecución deben reiniciarse. ## Conclusión Has comprobado el estado de AppArmor, escrito y cargado un perfil propio, verificado que bloquea escrituras no permitidas incluso para root, ajustado el perfil con `aa-logprof` en modo complain y añadido permisos a perfiles del sistema mediante overrides locales. Como siguientes pasos, puedes aplicar el mismo flujo con `aa-genprof` a un servicio propio que ejecutes con systemd, revisar los perfiles adicionales del paquete `apparmor-profiles` y combinar AppArmor con un cortafuegos UFW bien configurado.