AppArmor es un módulo de seguridad del kernel de Linux que puedes utilizar para restringir las capacidades 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 no permite capacidades específicas como, por ejemplo, acceso a la red o permisos de ejecución/escritura/lectura de archivos.
Puedes utilizar AppArmor con los contenedores de Docker que se ejecutan en las instancias de Container-Optimized OS. Para cualquier contenedor determinado, puedes aplicar el perfil de seguridad predeterminado de AppArmor que viene con Docker, o un perfil de seguridad personalizado que proporciones.
Cómo usar el perfil de seguridad predeterminado de AppArmor de Docker
Cuando inicias un contenedor en la instancia de Container-Optimized OS, el sistema aplica de forma automática el perfil de seguridad docker-default
de AppArmor. En el siguiente comando de ejemplo, se 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
de la siguiente manera:
root@88cef496c1a5:/# cat /proc/sysrq-trigger
El resultado debería contener un error "Permiso denegado" similar al que figura a continuación:
cat: /proc/sysrq-trigger: Permission denied
Cómo aplicar un perfil de seguridad personalizado
Para aplicar un perfil de seguridad diferente, usa la opción de línea de comandos apparmor=<profile-name>
cuando ejecutes tu contenedor. En el siguiente comando de ejemplo, se 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 Crea un perfil de seguridad personalizado más adelante a fin de obtener más información para 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 ejecutará sin ningún perfil de seguridad, como en el siguiente ejemplo:
docker run --rm -it --security-opt apparmor=unconfined debian:jessie bash -i
Cómo visualizar los perfiles de seguridad activos de AppArmor
Puedes ver qué perfil de AppArmor se aplica a los procesos en tu instancia de Container-Optimized OS si inspeccionas el archivo /proc/<pid>/attr/current
, en el que <pid>
es el ID del proceso.
Supongamos que tienes los siguientes procesos en ejecución en tu instancia (que se muestran con 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 ejecutó 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 ejecutó sin ningún perfil de seguridad (es decir, con la opción apparmor=unconfined
):
# cat /proc/2001/attr/current
unconfined
Cómo crear un perfil de seguridad personalizado
Si el proceso requiere un perfil de seguridad que diferente de docker-default
, puedes escribir tu propio perfil personalizado. Para utilizar un perfil personalizado, debes crear el archivo de perfil y, a continuación, cargar el archivo en AppArmor.
Por ejemplo, supongamos que deseas un perfil de seguridad que rechace 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, puedes 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
y, además, intenta ejecutar ping
desde el contenedor. El perfil de seguridad debería rechazar el tráfico, lo que genera un error como el siguiente:
ping: Lacking privilege for raw socket.
Para garantizar que el perfil de seguridad personalizado esté presente cuando se inicie la instancia de Container-Optimized OS, y siga siendo constante en todos los reinicios, puedes usar cloud-init
para instalar el perfil en /etc/apparmor.d
. Para ello, agrega una secuencia de comandos cloud-config
a los metadatos de la instancia como valor de la clave user-data
.
La siguiente secuencia de comandos de cloud-config
agrega 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 cargue el perfil personalizado en AppArmor y le indique a Docker que lo utilice, 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 ...
Una vez que hayas ejecutado los comandos, reinicia tu instancia, y luego puedes ejecutar el contenedor restringido por el perfil personalizado de AppArmor.