Veamos cómo endurecer y asegurar Docker para el entorno de producción.
Aunque Docker ha hecho posible que los desarrolladores de software y los ingenieros DevOps construyan y desplieguen aplicaciones rápidamente, también viene con una gran superficie de ataque que los piratas cibernéticos pueden aprovechar.
Vamos a ver cómo asegurar un Docker en una plataforma Linux a partir de lo siguiente.
- Defectos de configuración
- Ejecución remota de código
- Desbordamientos de búfer
- Falsificación de imágenes, etc.
Haremos uso de las siguientes herramientas, como el servidor notarial de Docker para firmar imágenes y el banco de seguridad de Docker para comprobar el host, la configuración del demonio, etc.
Antes de proceder a la seguridad, vamos a tocar los fundamentos.
¿Qué es una tecnología de contenedores?
La tecnología de contenedores permite a los desarrolladores o ingenieros DevOps empaquetar una aplicación para que pueda ejecutarse con dependencias aisladas de otros procesos.
Existen varias tecnologías de contenedores en el mercado, como Apache Mesos, lxc y Docker. Aunque entran dentro de la categoría de tecnología de contenedores, funcionan de forma diferente.
Diferencia entre VM y VE
Un host de máquina virtual es totalmente diferente de un host de entorno virtual. En las máquinas virtuales, cada aplicación en contenedor viene con su propio conjunto de bibliotecas y sistema operativo mientras que las aplicaciones, por defecto, en un host de entorno virtual como lxc, y docker comparten el núcleo Linux.
¿Qué es Docker?
Docker es una tecnología de contenedores utilizada por millones para crear una aplicación web y desplegarla desde un entorno de pruebas a uno de producción.
Motor Docker
El motor Docker está formado por tres componentes.
- Un Servidor: Este componente es un proceso de larga duración o demonio responsable de la gestión de imágenes y contenedores.
- UNA API REST: Esta interfaz hace posible la comunicación entre el demonio Docker y la herramienta cliente Docker.
- Herramienta cliente Docker: La herramienta cliente Docker hace uso del componente API REST para informar al demonio Docker del funcionamiento de una aplicación en contenedores.
Registro de confianza Docker
Docker Trusted Registry es una solución de almacenamiento de imágenes de Docker para el negocio de plataformas empresariales. Es diferente del docker hub. Mientras que el docker hub se aloja en la nube, el registro de confianza de Docker es una solución de almacenamiento local para la edición empresarial de Docker.
Docker Content Trust
Docker Content Trust ofrece la posibilidad de utilizar firmas de datos para las imágenes enviadas y recibidas desde y hacia registros remotos de Docker, como el docker hub.
Espacios de nombres Linux
Los espacios de nombres Linux son una característica del núcleo Linux que aísla una aplicación o proceso en contenedor que se ejecuta en un host de entorno virtual de otros procesos.
Grupos de Control Linux(Cgroups)
Los grupos de control Linux son una característica del núcleo Linux que le permite asignar recursos como tiempo de CPU, ancho de banda de red, memoria del sistema, etc. a los procesos activos en un host.
Capacidades
En Linux, existe una característica de seguridad en el subsistema del núcleo que puede configurarse o aplicarse para limitar el proceso privilegiado como un proceso ejecutado por un usuario con UID 1. Aunque los procesos o usuarios privilegiados pueden saltarse los permisos discrecionales de control de acceso, no pueden saltarse las reglas de capacidades.
Centrémonos ahora en la seguridad.
Seguridad del host Docker
En esta sección, veremos cómo asegurar el host donde reside Docker.
Escaneando el kernel Linux
Antes de alojar un Docker en una plataforma Linux, primero debe inspeccionar el kernel. Existen varias herramientas de código abierto como Lynis y OpenVAS que puede utilizar para escanear el kernel de Linux.
Copie o clone el proyecto Lynis desde Github utilizando el comando git
clone.
git clone https://github.com/CISOfy/lynis.git
A continuación, utilice el siguiente comando para navegar hasta el directorio lynis
y auditar el sistema Linux.
cd lynis; ./lynis auditar sistema
Endurezca el kernel de Linux
Después de haber escaneado el núcleo Linux en busca de vulnerabilidades basadas en el sistema, puede añadir otra capa extra de protección al núcleo mediante grsecurity. Proporciona características de seguridad como las siguientes
- Prevención de la explotación del desbordamiento del búfer
- prevención de vulnerabilidades de carrera en /tmp
- restricciones de /proc que no filtran información sobre los propietarios de los procesos.
- Prevención de la ejecución de código arbitrario en el núcleo, etc.
Inicialmente, puede descargar parches de forma gratuita desde grsecurity y aplicarlos a su núcleo actual. Pero ya no permite parches gratuitos.
Instale Docker en una VM
En lugar de instalar Docker directamente en un host Linux, puede añadir una capa extra de protección instalándolo dentro de una máquina virtual. Al hacerlo, incluso si hay un problema de vulnerabilidad con el kernel del host, no afectará a los contenedores Docker.
Proteger los privilegios de root
Por defecto, Docker requiere privilegios de root para crear y gestionar contenedores. El script malicioso puede aprovechar esta superficie de ataque para escalar a un superusuario en un host Linux y eventualmente acceder a archivos/carpetas sensibles, imágenes, certificados, etc.
Para evitarlo, podemos hacer uso del siguiente comando. Podemos decidir abandonar capacidades como setgid
y setuid
para evitar que otros programas o procesos cambien su GID por otro GID
que pueda resultar en una escalada de privilegios. También puede consultar aquí la lista de definición de capacidades de Linux.
El comando que se muestra a continuación ejecuta el contenedor apache webserver y elimina las capacidades setgid
y setuid
mediante --cap-drop
para evitar que el contenedor apache cambie su GID y UID por otro UID y GID.
GID y UID en este contexto se refieren a ID de grupo
e ID de usuario
respectivamente.
docker run -d --cap-drop SETGID --cap-drop SETUID apache
Usuario Docker
Aparte de evitar otros programas o procesos, también puede crear un usuario para gestionar operaciones docker como docker run
en lugar de gestionarlo a través de un superusuario.
Puede añadir o crear un usuario docker mediante lo siguiente:
sudo groupadd docker
El comando anterior crea un grupo llamado docker
A continuación, cree un usuario mediante el siguiente comando:
sudo useradd mike
Por último, utilice el siguiente comando para añadir un usuario mike
al grupo docker
para administrar las operaciones de docker.
sudo usermod -aG docker mike
Administración de contenedores con Cgroups
En un entorno de producción, es posible que tenga más de un contenedor.
Si no tiene instalado cgroups
en su host, puede utilizar el siguiente comando para instalarlo y luego consultar aquí (para Ubuntu) cómo configurarlo.
sudo apt-get install cgroup-bin cgroup-lite cgroup-tools cgroupfs-mount libcgroup1
Podemos asignar los contenedores a recursos de CPU limitados mediante --cpu-shares
y --cpuset-cpus
El siguiente ejemplo de comando muestra que el proceso contenedor prodnginx
se ejecuta sólo en el primer núcleo mediante --cpuset-cpus
y se le asignan 20 CPU mediante --cpu-shares
mientras que el proceso contenedor proxnginx
se ejecuta en los dos primeros núcleos de CPU y también se le asignan 20 CPU.
docker run -d --name prodnginx --cpuset-cpus=0 --cpu-shares=20 nginx
docker run -d --name testnginx --cpuset-cpus=2 --cpu-shares=20 nginx
A continuación, escriba el comando docker stats
para ver el uso de la CPU por los contenedores prodnginx
y testnginx
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O
845bea7263fb prodnginx 57.69% 1.258MiB / 985.2MiB 0.13% 578B / 0B 1.33MB / 0B
189ba15e8258 testnginx 55.85% 1.25MiB / 985.2MiB 0.13% 578b / 0B 1.33MB / 0B
Es una buena idea definir CPU-shares para un host docker cuando tiene más de un contenedor ejecutándose en él.
Gestión de contenedores con espacios de nombres
Un espacio de nombres puede evitar que los contenedores se ejecuten como usuarios con privilegios, lo que puede ayudar a evitar ataques de escalada de privilegios.
Podemos habilitar el espacio de nombres en docker haciendo uso de los archivos /etc/subuid
y /etc/subgid
como se muestra a continuación.
- cree un usuario utilizando el comando
adduser
sudo adduser dockremap
- Configure un subuid para el usuario
dockremap
sudo sh -c 'echo dockremap:400000:65536 > /etc/subuid'
- A continuación, configure un subgid para el usuario
dockremap
sudo sh -c 'echo dockremap:400000:65536 > /etc/subgid'
- Abra el archivo
daemon.json
y rellénelo con el siguiente contenido para asociar el atributouserns-remap
al usuariodockremap
vi /etc/docker/daemon.json
{
"userns-remap": "dockremap"
}
- Pulse
:wq
para guardar y cerrar el archivodaemon.json
y, por último, reinicie docker para habilitar los espacios de nombres en un host docker
sudo /etc/init.d/docker restart
Asegurar el demonio Docker
También es necesario configurar el demonio Docker para garantizar una comunicación segura entre el cliente Docker y el demonio Docker a través de TLS.
Utilice el siguiente comando para abrir el archivo daemon.j
son y copie y pegue el siguiente contenido (sustituya la IP por la suya actual) como se muestra a continuación
vi daemon.json
{
"debug": false
"tls": true
"tlscert": "/var/docker/server.pem",
"tlskey": "/var/docker/serverkey.pem",
"hosts": ["tcp://192.168.16.5:2376"]
}
Asegurar los componentes de Docker
Veamos cómo hacer uso de herramientas como CodeNotary y el servidor notarial para firmar imágenes con el fin de evitar la falsificación de imágenes. Además, también es necesario escanear las imágenes para asegurarse de que no están repletas de vulnerabilidades
Haremos uso del servidor notarial de Docker para firmar y verificar imágenes y utilizaremos Anchor Engine para escanear imágenes en busca de vulnerabilidades.
Verificar imágenes con el servidor notario
Antes de que podamos hacer uso del servidor Notary para firmar imágenes, necesitamos descargar e instalar docker-compose. Utilizaremos Docker Compose para configurar un servidor notario.
- Ejecute el siguiente comando para descargar la última versión de Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
- Aplique permisos de ejecución a docker-compose como se muestra a continuación
sudo chmod 700 /usr/local/bin/docker-compose
- Puede comprobar si ha instalado correctamente docker-compose mediante el siguiente comando
docker-compose --version
- Ahora podemos instalar el servidor notario a través de docker-compose
git clone https://github.com/theupdateframework/notary.git
- El comando anterior clona o copia el servidor notarial del repositorio notarial
- Inicie el servidor notarial y el firmante mediante los siguientes comandos
docker-compose build
docker-compose up -d
- A continuación, copie la configuración y los certificados de prueba en su directorio local del notario mediante el siguiente comando
mkdir -p ~/.notary && cp cmd/notary/config.json cmd/notary/root-ca.crt ~/.notary
- Ahora ejecute el siguiente comando para conectar el servidor notary al cliente docker
export DOCKER_CONTENT_TRUST=1
export DOCKER_CONTENT_TRUST_SERVER=https://notaryserver:4443
- Genere un par de claves de delegación mediante el siguiente comando
docker trust key generate mike --dir ~./docker/trust
- Ahora vamos a crear un objetivo nuevas claves en caso de que el repositorio no existe
docker trust signer add --key ~/.docker/trust/mike.pub mike mikedem0/whalesay
- A continuación, puede firmar su imagen docker utilizando el comando
docker trust sign
. Necesita extraer la imagen docker del docker hub y re-etiquetarla utilizando el comandodocker pull
ydocker tag
respectivamente.
docker trust sign mikedem0/nginx:latest
También puede escanear las imágenes docker en busca de vulnerabilidades y fallos de configuración. Puede consultar aquí cómo utilizar Anchor Engine para escanear en busca de vulnerabilidades y Docker Bench Security para buscar fallos de configuración.
Espero que lo anterior le dé una idea sobre la seguridad Docker para el entorno de producción. Es posible que también desee echar un vistazo a este curso Udemy sobre la piratería y la seguridad de los contenedores Docker.