Product SiteDocumentation Site

14.4. Introducción a AppArmor

14.4.1. Principios

Apparmor es un sistema de control obligatorio de acceso («Mandatory Access Control» o «MAC») basado en la interfaz LSM (módulos de seguridad de Linux: «Linux Security Modules»). En la práctica, el núcleo pregunta a AppArmor antes de cada llamada al sistema del sistema para saber si un proceso está autorizado a realizar dicha operación. A través de este mecanismo, Apparmor confina un programa a un conjunto limitado de recursos.
AppArmor aplica un conjunto de reglas (un «perfil») a cada programa. El perfil aplicado por el núcleo depende de la ruta de instalación del programa a ejecutar. Al contrario que en SELinux (descrito en Sección 14.5, “Introducción a SELinux”), las reglas que se aplican no dependen del usuario: a todos los usuarios se les aplica el mismo juego de reglas cuando ejecutan el mismo programa (aunque en cualquer caso siguen teniéndose en cuenta los permisos de usuario tradicionales, lo que puede resultar en un comportamiento distinto).
Los perfiles de AppArmor se guardan en /etc/apparmor.d/ y contienen una lista de reglas de control de acceso sobre los recursos que puede utilizar cada programa. Los perfiles se compilan y son cargados por el núcleo por la orden apparmor_parser. Cada perfil se puede cargar bien en modo estrícto (enforcing) o bien en modo relajado (complaining). El modo estricto aplica las reglas y registra las tentativas de violación, mientras que en el modo relajado sólo se registran las llamadas al sistema que hubieran sido bloqueadas, pero no se bloquean realmente.

14.4.2. Activar AppArmour y gestionar los perfiles

El soporte de AppArmor está ya integrado en los núcleos estándar proporcionados por Debian. Para activar AppArmor basta con instalar algunos paquetes adicionales y establecer algún parámetro en la línea de órdenes del núcleo:
# apt install apparmor apparmor-profiles apparmor-utils
[...]
# perl -pi -e 's,GRUB_CMDLINE_LINUX="(.*)"$,GRUB_CMDLINE_LINUX="$1 apparmor=1 security=apparmor",' /etc/default/grub
# update-grub
Después de un reinicio AppArmor estará operativo, lo cual se puede confirmar mediante aa-status:
# aa-status
apparmor module is loaded.
44 profiles are loaded.
9 profiles are in enforce mode.
   /usr/bin/lxc-start
   /usr/lib/chromium-browser/chromium-browser//browser_java
[...]
35 profiles are in complain mode.
   /sbin/klogd
[...]
3 processes have profiles defined.
1 processes are in enforce mode.
   /usr/sbin/libvirtd (1295) 
2 processes are in complain mode.
   /usr/sbin/avahi-daemon (941) 
   /usr/sbin/avahi-daemon (1000) 
0 processes are unconfined but have a profile defined.
El estado de cada perfil se puede cambair entre los modos estricto y relajado mediante las órdenes aa-enforce y aa-complain, pasándoles como parámetro bien la ruta del ejecutable o la ruta del archivo de perfil. De igual manera se puede desactivar completamente un perfil mediante aa-disable, o establecerlo en el modo de auditoría (de forma que registre incluso las llamadas del sistema aceptadas) mediante aa-audit.
# aa-enforce /usr/sbin/avahi-daemon
Setting /usr/sbin/avahi-daemon to enforce mode.
# aa-complain /etc/apparmor.d/usr.bin.lxc-start
Setting /etc/apparmor.d/usr.bin.lxc-start to complain mode.

14.4.3. Creación de un nuevo perfil

A pesar de que crear un perfil AppArmor es bastante sencillo, la mayoría de los programas no disponen de uno. Esta sección muestra cómo crear un nuevo perfil desde cero, símplemente utilizando el programa deseado y dejando que AppArmor monitorice las llamadas al sistema que realiza y los recursos a los que accede.
Los programas que deben ser confinados de forma prioritaria son aquellos expuestos a la red, puesto que estos serán los blancos más probables para atacantes remotos. Precisamente por eso AppArmor proporciona la orden aa-unconfined, que lista los programas que exponen al menos un zócalo de red (NT: ¿mejor puerto de red?) sin tener ningún perfil asociado. Con la opción --paranoid se obtienen todos los procesos que tienen activa al menos una conexión de red y no están confinados.
# aa-unconfined
801 /sbin/dhclient not confined
890 /sbin/rpcbind not confined
899 /sbin/rpc.statd not confined
929 /usr/sbin/sshd not confined
941 /usr/sbin/avahi-daemon confined by '/usr/sbin/avahi-daemon (complain)'
988 /usr/sbin/minissdpd not confined
1276 /usr/sbin/exim4 not confined
1485 /usr/lib/erlang/erts-6.2/bin/epmd not confined
1751 /usr/lib/erlang/erts-6.2/bin/beam.smp not confined
19592 /usr/lib/dleyna-renderer/dleyna-renderer-service not confined
El el ejemplo siguiente vamos a intentar crear un perfil para /sbin/dhclient. Para ello utilzamos la orden aa-genprof dhclient, que nos invita a utilizar la aplicación (en otra ventana) y a volver a aa-genprof una vez que hayamos terminado, para escrutar los registros en busca de eventos AppArmor y convertir estos registros en reglas de control de acceso. Para cada evento registrado se proponen una o varias sugerencias de reglas y será posible aprobarlas o modificarlas de distintas formas:
# aa-genprof dhclient
Writing updated profile for /sbin/dhclient.
Setting /sbin/dhclient to complain mode.

Before you begin, you may wish to check if a
profile already exists for the application you
wish to confine. See the following wiki page for
more information:
http://wiki.apparmor.net/index.php/Profiles

Please start the application to be profiled in
another window and exercise its functionality now.

Once completed, select the "Scan" option below in 
order to scan the system logs for AppArmor events. 

For each AppArmor event, you will be given the 
opportunity to choose whether the access should be 
allowed or denied.

Profiling: /sbin/dhclient

[(S)can system log for AppArmor events] / (F)inish
Reading log entries from /var/log/audit/audit.log.

Profile:  /sbin/dhclient 1
Execute:  /usr/lib/NetworkManager/nm-dhcp-helper
Severity: unknown

(I)nherit / (C)hild / (P)rofile / (N)amed / (U)nconfined / (X) ix On / (D)eny / Abo(r)t / (F)inish
P
Should AppArmor sanitise the environment when
switching profiles?

Sanitising environment is more secure,
but some applications depend on the presence
of LD_PRELOAD or LD_LIBRARY_PATH.

(Y)es / [(N)o]
Y
Writing updated profile for /usr/lib/NetworkManager/nm-dhcp-helper.
Complain-mode changes:
WARN: unknown capability: CAP_net_raw

Profile:    /sbin/dhclient 2
Capability: net_raw
Severity:   unknown

[(A)llow] / (D)eny / (I)gnore / Audi(t) / Abo(r)t / (F)inish
A
Adding capability net_raw to profile.

Profile:  /sbin/dhclient 3
Path:     /etc/nsswitch.conf
Mode:     r
Severity: unknown

  1 - #include <abstractions/apache2-common> 
  2 - #include <abstractions/libvirt-qemu> 
  3 - #include <abstractions/nameservice> 
  4 - #include <abstractions/totem> 
 [5 - /etc/nsswitch.conf]
[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore
3

Profile:  /sbin/dhclient
Path:     /etc/nsswitch.conf
Mode:     r
Severity: unknown

  1 - #include <abstractions/apache2-common> 
  2 - #include <abstractions/libvirt-qemu> 
 [3 - #include <abstractions/nameservice>]
  4 - #include <abstractions/totem> 
  5 - /etc/nsswitch.conf 
[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore
A
Adding #include <abstractions/nameservice> to profile.

Profile:  /sbin/dhclient
Path:     /proc/7252/net/dev
Mode:     r
Severity: 6

  1 - /proc/7252/net/dev 
 [2 - /proc/*/net/dev]
[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore
A
Adding /proc/*/net/dev r to profile

[...]
Profile:  /sbin/dhclient 4
Path:     /run/dhclient-eth0.pid
Mode:     w
Severity: unknown

 [1 - /run/dhclient-eth0.pid]
[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore
N

Enter new path: /run/dhclient*.pid

Profile:  /sbin/dhclient
Path:     /run/dhclient-eth0.pid
Mode:     w
Severity: unknown

  1 - /run/dhclient-eth0.pid 
 [2 - /run/dhclient*.pid]
[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore
A
Adding /run/dhclient*.pid w to profile

[...]
Profile:  /usr/lib/NetworkManager/nm-dhcp-helper 5
Path:     /proc/filesystems
Mode:     r
Severity: 6

 [1 - /proc/filesystems]
[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore
A
Adding /proc/filesystems r to profile

= Changed Local Profiles =

The following local profiles were changed. Would you like to save them?

 [1 - /sbin/dhclient]
  2 - /usr/lib/NetworkManager/nm-dhcp-helper 
(S)ave Changes / Save Selec(t)ed Profile / [(V)iew Changes] / View Changes b/w (C)lean profiles / Abo(r)t
S
Writing updated profile for /sbin/dhclient.
Writing updated profile for /usr/lib/NetworkManager/nm-dhcp-helper.

Profiling: /sbin/dhclient

[(S)can system log for AppArmor events] / (F)inish
F
Setting /sbin/dhclient to enforce mode.
Setting /usr/lib/NetworkManager/nm-dhcp-helper to enforce mode.

Reloaded AppArmor profiles in enforce mode.

Please consider contributing your new profile!
See the following wiki page for more information:
http://wiki.apparmor.net/index.php/Profiles

Finished generating profile for /sbin/dhclient.
Tenga en cuenta que el programa no muestra los caracteres de control que Vd. teclea; los hemos incluido en la transcripción anterior para aclarar las elecciones realizadas en cada paso.

1

El primer evento detectado es la ejecución de otro programa. En este caso se ofrecen varias opciones: puede lanzar el programa con el perfil del programa padre (“Inherit”), con un perfil dedicado (“Profile” o “Name”, que sólo se diferencian por la posibilidad de elegir un nombre de perfil arbitrario), con un sub-perfil del proceso padre (“Child”), o bien puede lanzar sin nigún perfil (“Unconfined”). También puede impedir que el programa se ejecute (“Deny”).
Cuando se elije lanzar el proceso hijo con un perfil de dedicado que no exista aún, la herramienta creará el perfil que falta y propondrá sugerencias de reglas en la misma sesión de trabajo.

2

A nivel del núcelo, los permisos especiales del usuario root se han separado en "capacidades" («capabilities»). Cuando una llamada del sistema requiere una capacidad específica, AppArmor verifica que el perfil permite al programa utilizar esta capacidad.

3

Aquí el programa requiere el permiso de lectura sobre el archivo /etc/nsswitch.conf. aa-genprof ha detectado que este permiso ya se había concedido por varias «abstracciones» y las ofrece como alternativas posibles. Una abstracción proporciona un conjunto reutilizable de reglas de control de acceso, agrupando reglas que duelen utilizarse conjuntamente. En este caso específico el archivo se utiliza normalmente por las funciones relativas a la resolución de nombres de la biblioteca estándar C, y por lo tanto elegimos la opcion «3» para incluir la opción «#include <abstractions/nameservice> » y después «A» para autorizarlo.

4

El programa intenta crear el archivo /run/dhclient-eth0.pid. Si autorizamos únicamente la creación de este archivo, el programa no funcionará si el usuario intenta utilizarlo en otra interfaz de red. Por lo tanto habrá que selecionar «New» para reemplazar el nombre del archivo por un nombre más genérico, « /run/dhclient*.pid », antes de guardar la regla con «Allow».

5

Hay que tener en cuenta que este intento de acceso no forma parte del perfil dhclient, sino del nuevo perfil que hemos creado cuando hemos autorizado a /usr/lib/NetworkManager/nm-dhcp-helper para que funcione bajo el suyo propio.
Después de examinar todos los eventos registrados, el programa propone guardar todos los perfiles que se han creado durante la ejecución. En este caso tenemos dos perfiles que guardamos simultáneamente mediante «Save» antes de cerrar el programa con «Finish» (pero podríamos igualmente haberlos guardados individualmente).
aa-genprof no es sino un pequeño script inteligente que utiliza aa-logprof: crea un perfil vacío, lo carga en modo relajado y después ejecuta aa-logprof. Esta última es una utilidad que actualiza un perfil en función de las violaciones que han sido registradas. Por lo tanto se puede volver a ejecutar esta herramienta para mejorar el perfil que se ha creado.
Si se quiere que el perfil generado sea completo, se debería utilizar el programa de todas las formas legítimas posibles. En el caso de dhcliente esto significa ejecutarlo a través de Network Manager, pero también mediante ifupdown, a mano, etc. Finalmente se obtendrá un /etc/apparmor.d/sbin.dhclient parecido al siguiente:
# Last Modified: Tue Sep  8 21:40:02 2015
#include <tunables/global>

/sbin/dhclient {
  #include <abstractions/base>
  #include <abstractions/nameservice>

  capability net_bind_service,
  capability net_raw,

  /bin/dash r,
  /etc/dhcp/* r,
  /etc/dhcp/dhclient-enter-hooks.d/* r,
  /etc/dhcp/dhclient-exit-hooks.d/* r,
  /etc/resolv.conf.* w,
  /etc/samba/dhcp.conf.* w,
  /proc/*/net/dev r,
  /proc/filesystems r,
  /run/dhclient*.pid w,
  /sbin/dhclient mr,
  /sbin/dhclient-script rCx,
  /usr/lib/NetworkManager/nm-dhcp-helper Px,
  /var/lib/NetworkManager/* r,
  /var/lib/NetworkManager/*.lease rw,
  /var/lib/dhcp/*.leases rw,

  profile /sbin/dhclient-script flags=(complain) {
    #include <abstractions/base>
    #include <abstractions/bash>

    /bin/dash rix,
    /etc/dhcp/dhclient-enter-hooks.d/* r,
    /etc/dhcp/dhclient-exit-hooks.d/* r,
    /sbin/dhclient-script r,

  }
}