AppArmor es un módulo de seguridad del kernel de Linux que puedes usar para restringir las funciones de los procesos que se ejecutan en el sistema operativo host. Cada proceso puede tener su propio perfil de seguridad. El perfil de seguridad permite o deniega funciones específicas, como el acceso a la red o los permisos de lectura, escritura o ejecución de archivos.
Puedes usar AppArmor con los contenedores de Docker que se ejecutan en tus instancias de Container-Optimized OS. En cualquier contenedor, puedes aplicar el perfil de seguridad de AppArmor predeterminado que viene con Docker o un perfil de seguridad personalizado que proporciones.
Usar el perfil de seguridad predeterminado de AppArmor de Docker
Cuando inicias un contenedor en tu instancia de Container-Optimized OS, el sistema aplica automáticamente el perfil de seguridad docker-default
AppArmor. El siguiente comando de ejemplo ejecuta un contenedor con el perfil de seguridad docker-default
:
docker run --rm -it debian:jessie bash -i
Para probar el perfil de seguridad docker-default
, puedes intentar leer el archivo /proc/sysrq-trigger
con el comando cat
, como se indica a continuación:
root@88cef496c1a5:/# cat /proc/sysrq-trigger
La salida debería contener un error "Permission Denied" (Permiso denegado), similar al siguiente:
cat: /proc/sysrq-trigger: Permission denied
Aplicar un perfil de seguridad personalizado
Para aplicar otro perfil de seguridad, usa la opción de línea de comandos apparmor=<profile-name>
cuando ejecutes el contenedor. El siguiente comando de ejemplo ejecuta un contenedor con un perfil de seguridad llamado no-ping
:
docker run --rm -i --security-opt apparmor=no-ping debian:jessie bash -i
Consulta la sección Crear un perfil de seguridad personalizado más adelante en este tema para obtener más información sobre cómo crear el perfil no-ping
especificado en el ejemplo.
También puedes especificar unconfined
con la opción apparmor
para indicar que el contenedor se debe ejecutar sin perfil de seguridad, como en el siguiente ejemplo:
docker run --rm -it --security-opt apparmor=unconfined debian:jessie bash -i
Ver los perfiles de seguridad de AppArmor activos
Para ver qué perfil de AppArmor se aplica a los procesos de tu instancia de Container-Optimized OS (si es que se aplica alguno), inspecciona el archivo /proc/<pid>/attr/current
, donde <pid>
es el ID del proceso.
Supongamos que tienes los siguientes procesos en ejecución en tu instancia (mostrados por el comando ps -ef | grep '[b]ash -i'
):
root 1903 1897 0 21:58 pts/3 00:00:00 docker run --rm -it debian:jessie bash -i
root 1927 1913 0 21:58 pts/4 00:00:00 bash -i
root 1978 1001 0 22:01 pts/0 00:00:00 docker run --rm -it --security-opt apparmor=unconfined debian:jessie bash -i
root 2001 1988 0 22:01 pts/2 00:00:00 bash -i
Si inspeccionas /proc/1927/attr/current
, deberías ver el siguiente resultado, que indica que el proceso (pid 1927
) se ha ejecutado con el perfil de seguridad predeterminado de Docker:
# cat /proc/1927/attr/current
docker-default (enforce)
Si inspeccionas /proc/2001/attr/current
, deberías ver el siguiente resultado, que indica que el proceso (pid 2001
) se ha ejecutado sin perfil de seguridad (es decir, con la opción apparmor=unconfined
):
# cat /proc/2001/attr/current
unconfined
Crear un perfil de seguridad personalizado
Si el proceso requiere un perfil de seguridad diferente al de docker-default
,
puedes escribir tu propio perfil personalizado. Para usar un perfil personalizado, debes crear el archivo de perfil y, a continuación, cargarlo en AppArmor.
Por ejemplo, supongamos que quieres un perfil de seguridad que no permita todo el tráfico de red sin procesar. La siguiente secuencia de comandos crea un archivo para un perfil de seguridad llamado no-ping
en /etc/apparmor.d/no_raw_net
:
cat > /etc/apparmor.d/no_raw_net <<EOF
#include <tunables/global>
profile no-ping flags=(attach_disconnected,mediate_deleted) {
#include <abstractions/base>
network inet tcp,
network inet udp,
network inet icmp,
deny network raw,
deny network packet,
file,
mount,
}
EOF
Una vez que hayas creado el archivo de perfil de seguridad, puedes usar apparmor_parser
para
cargar el perfil en AppArmor:
/sbin/apparmor_parser --replace --write-cache /etc/apparmor.d/no_raw_net
Una vez cargado, puede probar el perfil no-ping
de la siguiente manera:
$ docker run --rm -i --security-opt apparmor=no-ping debian:jessie ping -c3 8.8.8.8
El comando crea un contenedor con el perfil de seguridad no-ping
e intenta ejecutar ping
desde el contenedor. El perfil de seguridad debe rechazar el tráfico, lo que provocará un error como el siguiente:
ping: Lacking privilege for raw socket.
Para asegurarte de que tu perfil de seguridad personalizado esté presente cuando se inicie tu instancia de SO optimizado para contenedores y se mantenga persistente en los reinicios, puedes usar cloud-init
para instalar el perfil en /etc/apparmor.d
. Para ello, añade una secuencia de comandos cloud-config
a los metadatos de tu instancia como valor de la clave user-data
.
La siguiente secuencia de comandos cloud-config
añade el perfil no-ping
a /etc/apparmor.d
:
#cloud-configs
write_files:
- path: /etc/apparmor.d/no_raw_net
permissions: 0644
owner: root
content: |
#include <tunables/global>
profile no-ping flags=(attach_disconnected,mediate_deleted) {
#include <abstractions/base>
network inet tcp,
network inet udp,
network inet icmp,
deny network raw,
deny network packet,
file,
mount,
}
Para asegurarte de que el archivo de servicio carga tu perfil personalizado en AppArmor y le indica a Docker que lo use, ejecuta los siguientes comandos en tu instancia:
ExecStartPre=/sbin/apparmor_parser -r -W /etc/apparmor.d/no_raw_net
ExecStart=/usr/bin/docker run --security-opt apparmor=no-ping ...
Después de ejecutar los comandos, reinicia tu instancia y podrás ejecutar tu contenedor protegido por tu perfil de AppArmor personalizado.