Implementing Docker Containers with Non-Root User Access

Implementar contenedores Docker con acceso de usuario no-root mejora la seguridad al minimizar la superficie de ataque. Esta práctica implica configurar Dockerfiles y puntos de entrada para garantizar permisos adecuados.
Índice
Implementación de contenedores Docker con acceso de usuario no rootIntroducciónDocker es una plataforma de contenedorización que permite empaquetar aplicaciones y sus dependencias en contenedores ligeros y portátiles. Por defecto, los contenedores Docker se ejecutan como el usuario root, lo que puede suponer un riesgo de seguridad si el contenedor se ve comprometido. En este artículo, exploraremos cómo implementar contenedores Docker con acceso de usuario no root para mejorar la seguridad.¿Por qué usar un usuario no root en Docker?Ejecutar contenedores como root puede ser peligroso por varias razones:1. Si un atacante consigue acceso al contenedor, tendrá privilegios de root en el sistema host.2. Algunas aplicaciones no necesitan privilegios de root para funcionar correctamente.3. Cumplimiento de políticas de seguridad que requieren ejecutar procesos sin privilegios de administrador.Cómo implementar contenedores con usuario no root1. Crear un usuario y grupo en el Dockerfile:```dockerfileFROM ubuntu:latestRUN groupadd -r appgroup && useradd -r -g appgroup appuserUSER appuser```2. Establecer permisos adecuados en los archivos y directorios:```dockerfileFROM ubuntu:latestRUN groupadd -r appgroup && useradd -r -g appgroup appuser# Crear directorio de la aplicación y establecer permisosRUN mkdir /app && chown appuser:appgroup /appUSER appuserWORKDIR /app```3. Utilizar el comando `gosu` para cambiar de usuario:```dockerfileFROM ubuntu:latestRUN groupadd -r appgroup && useradd -r -g appgroup appuser# Instalar gosuRUN apt-get update && apt-get install -y gosuUSER rootCOPY entrypoint.sh /usr/local/bin/RUN chmod +x /usr/local/bin/entrypoint.shENTRYPOINT ["entrypoint.sh"]```entrypoint.sh:```bash#!/bin/bashset -e# Cambiar a usuario appuserexec gosu appuser "$@"```4. Utilizar Docker Compose para gestionar usuarios:docker-compose.yml:```yamlversion: '3.8'services:  app:    build: .    user: "1000:1000"    volumes:      - ./app:/app```5. Utilizar Podman como alternativa a Docker:Podman es una herramienta de contenedorización que, por defecto, ejecuta contenedores sin privilegios root. Es compatible con la CLI de Docker y puede ser una buena alternativa si se requiere ejecutar contenedores sin privilegios de administrador.ConclusiónImplementar contenedores Docker con acceso de usuario no root es una práctica recomendada para mejorar la seguridad de las aplicaciones contenerizadas. Siguiendo los pasos descritos en este artículo, puedes reducir significativamente el riesgo de seguridad asociado con la ejecución de contenedores como root. Recuerda siempre seguir las mejores prácticas de seguridad y mantener tus imágenes Docker actualizadas con los últimos parches de seguridad.

Ejecución de contenedores Docker como usuarios no rootEn el mundo de la contenerización, Docker se ha convertido en una herramienta fundamental para el desarrollo y despliegue de aplicaciones. Sin embargo, por defecto, los contenedores Docker se ejecutan con privilegios de root, lo que puede representar un riesgo de seguridad significativo. En este artículo, exploraremos cómo ejecutar contenedores Docker como usuarios no root, mejorando así la seguridad de nuestras aplicaciones.¿Por qué es importante ejecutar contenedores como usuarios no root?Ejecutar contenedores con privilegios de root puede ser peligroso por varias razones:1. Escalada de privilegios: Si un atacante logra comprometer el contenedor, tendría acceso de root al sistema host. 2. Vulnerabilidades del kernel: Los procesos con privilegios de root pueden explotar vulnerabilidades del kernel para escapar del contenedor. 3. Cumplimiento normativo: Muchas regulaciones de seguridad requieren el principio de privilegio mínimo.Pasos para ejecutar contenedores como usuarios no root:1. Crear un usuario dentro de la imagen: En tu Dockerfile, agrega las siguientes líneas: ``` RUN useradd -m appuser USER appuser ```2. Establecer el usuario correcto en el ENTRYPOINT: ``` ENTRYPOINT ["su", "-", "appuser", "-c", "your_command"] ```3. Utilizar la opción --user al ejecutar el contenedor: ``` docker run --user 1000:1000 tu_imagen ```4. Configurar permisos adecuados en los volúmenes montados: ``` docker run -v /ruta/host:/ruta/container -u 1000:1000 tu_imagen ```5. Utilizar Docker Compose para gestionar usuarios: ``` version: '3' services: app: image: tu_imagen user: "1000:1000" ```Consideraciones adicionales:- Algunas aplicaciones pueden requerir privilegios elevados para ciertas operaciones. En estos casos, considera utilizar la opción --cap-drop y --cap-add para gestionar capacidades específicas del kernel. - Asegúrate de que el usuario creado tenga los permisos necesarios para acceder a los archivos y directorios requeridos por tu aplicación. - Si estás utilizando orquestación con Kubernetes, puedes especificar el usuario en el pod specification.Ejemplo práctico:Supongamos que tenemos una aplicación Node.js. Nuestro Dockerfile podría verse así:``` FROM node:14 RUN useradd -m appuser WORKDIR /app COPY package*.json ./ RUN npm install COPY . . USER appuser EXPOSE 3000 CMD ["npm", "start"] ```Luego, para ejecutar el contenedor:``` docker build -t mi-app . docker run -p 3000:3000 --user 1000:1000 mi-app ```Conclusión:Ejecutar contenedores Docker como usuarios no root es una práctica recomendada de seguridad que reduce significativamente los riesgos asociados con los privilegios de root. Al seguir los pasos y consideraciones mencionados en este artículo, puedes mejorar la postura de seguridad de tus aplicaciones contenerizadas y cumplir con las mejores prácticas de la industria.Recuerda que la seguridad es un proceso continuo, y siempre es recomendable mantenerse actualizado con las últimas prácticas y vulnerabilidades en el ecosistema Docker.

Docker has revolutionized the way we build, manage, and deploy applications. However, running containers as the root user can pose significant security risks. In this article, we’ll explore the importance of running Docker containers as non-root users, the steps required to set it up, and some best practices to ensure your applications are secure.

Understanding Docker and User Permissions

Docker es una plataforma de código abierto que permite a los desarrolladores crear, implementar y ejecutar aplicaciones en contenedores. Los contenedores son entornos aislados que contienen todo lo necesario para que una aplicación se ejecute, incluyendo el código, las bibliotecas del sistema, las herramientas y las dependencias. Esto significa que las aplicaciones pueden ejecutarse de manera consistente en cualquier entorno, ya sea en un servidor local, en la nube o en un dispositivo móvil.Docker utiliza la tecnología de contenedores de Linux, que permite que múltiples contenedores se ejecuten en una sola máquina host. Cada contenedor comparte el kernel del sistema operativo host, pero tiene su propio espacio de usuario y sistema de archivos. Esto hace que los contenedores sean mucho más ligeros y rápidos que las máquinas virtuales tradicionales, que requieren un sistema operativo completo para cada instancia.Docker también proporciona una serie de herramientas y servicios para facilitar el desarrollo y la implementación de aplicaciones en contenedores. Estos incluyen:- Docker Hub: Un repositorio de imágenes de contenedores que los desarrolladores pueden usar como base para sus propias aplicaciones.- Docker Compose: Una herramienta para definir y ejecutar aplicaciones de múltiples contenedores.- Docker Swarm: Un orquestador de contenedores que permite a los desarrolladores administrar y escalar aplicaciones en contenedores en múltiples hosts.- Docker Machine: Una herramienta para crear y administrar máquinas host de Docker en diferentes plataformas.En resumen, Docker es una plataforma de contenedores que permite a los desarrolladores crear, implementar y ejecutar aplicaciones de manera consistente en cualquier entorno. Proporciona una serie de herramientas y servicios para facilitar el desarrollo y la implementación de aplicaciones en contenedores, lo que lo convierte en una opción popular para el desarrollo de aplicaciones modernas.

Docker es una plataforma de código abierto que automatiza el despliegue de aplicaciones dentro de contenedores ligeros. Estos contenedores encapsulan todo lo necesario para ejecutar la aplicación, incluyendo el código, el entorno de ejecución, las herramientas del sistema, las librerías y la configuración.

Why Use Non-Root Users?

When a Docker container runs as the root user, it possesses the same permissions and privileges as the root user on the host machine. If a vulnerability is exploited within the container, an attacker could gain root access to the host system, leading to severe security implications. By running containers as non-root users, we limit the scope of potential damage, making it harder for attackers to compromise the host system.

Setting Up a Non-Root User in Docker Containers

Paso 1: Crear un usuario no root en el Dockerfile

El primer paso para ejecutar tu contenedor como un usuario no root es crear un usuario en tu Dockerfile. A continuación se muestra un ejemplo de cómo hacerlo al construir una aplicación simple de Node.js.

# Comienza con una imagen base
FROM node:14

# Crea un usuario no root
RUN groupadd -g 1001 appuser && 
    useradd -u 1001 -g appuser -m appuser

# Establece el directorio de trabajo
WORKDIR /home/appuser/app

# Copia package.json e instala las dependencias
COPY package.json ./
RUN npm install

# Copia el resto del código de tu aplicación
COPY . .

# Cambia al usuario no root
USER appuser

# Inicia la aplicación
CMD ["node", "app.js"]

En el Dockerfile anterior:

  • We create a non-root user appuser and a group appuser con IDs específicos.
  • We set the working directory to a path within the appuser’directorio personal.
  • Finalmente, cambiamos a la appuser antes de ejecutar la aplicación.

Paso 2: Construyendo la imagen de Docker

Después de crear tu Dockerfile, puedes construir tu imagen utilizando la CLI de Docker:

docker build -t my-node-app .

Paso 3: Ejecutar el contenedor de Docker

Once the image is built, you can run it, and it will execute as the non-root user specified in the Dockerfile.

docker run -d my-node-app

Verifying Non-Root Execution

To verify that your container is running as a non-root user, you can execute a command inside the container:

docker exec -it  whoami

The output should return appuser, confirmando que la aplicación se está ejecutando como un usuario no root.

Prácticas recomendadas para ejecutar contenedores Docker como usuarios no rootEn el mundo de la contenerización, la seguridad es una preocupación primordial. Una de las mejores prácticas para mejorar la seguridad de tus contenedores Docker es ejecutarlos como usuarios no root. Esto reduce significativamente el riesgo de que un atacante obtenga acceso privilegiado a tu sistema si logra comprometer el contenedor.En este artículo, exploraremos las mejores prácticas para ejecutar contenedores Docker como usuarios no root, incluyendo cómo crear y gestionar usuarios dentro de los contenedores, cómo configurar permisos de archivos y cómo utilizar herramientas como Podman para una mayor seguridad.1. Crear un usuario no root en tu DockerfileLa forma más sencilla de ejecutar un contenedor como un usuario no root es crear un usuario dentro del contenedor y cambiar a ese usuario antes de ejecutar la aplicación. Aquí tienes un ejemplo de cómo hacerlo en tu Dockerfile:```dockerfile FROM ubuntu:latest# Crear un nuevo usuario y grupo RUN groupadd -r appgroup && useradd -r -g appgroup appuser# Cambiar al nuevo usuario USER appuser# Tu aplicación y configuración COPY . /app WORKDIR /app CMD ["python", "app.py"] ```En este ejemplo, creamos un nuevo grupo llamado "appgroup" y un nuevo usuario llamado "appuser" que pertenece a ese grupo. Luego, usamos la instrucción USER para cambiar al usuario "appuser" antes de ejecutar la aplicación.2. Configurar permisos de archivosEs importante asegurarse de que los archivos y directorios dentro del contenedor tengan los permisos correctos para el usuario no root. Puedes hacer esto en tu Dockerfile utilizando los comandos chown y chmod:```dockerfile FROM ubuntu:latest# Crear un nuevo usuario y grupo RUN groupadd -r appgroup && useradd -r -g appgroup appuser# Cambiar la propiedad de los archivos a appuser RUN chown -R appuser:appgroup /app# Cambiar los permisos de los archivos RUN chmod 755 /app# Cambiar al nuevo usuario USER appuser# Tu aplicación y configuración COPY . /app WORKDIR /app CMD ["python", "app.py"] ```En este ejemplo, cambiamos la propiedad de todos los archivos en el directorio /app al usuario "appuser" y al grupo "appgroup" utilizando el comando chown. Luego, cambiamos los permisos de los archivos en el directorio /app para que sean legibles y ejecutables por el propietario y el grupo, pero no por otros usuarios, utilizando el comando chmod.3. Utilizar Podman para una mayor seguridadPodman es una herramienta alternativa a Docker que proporciona una mayor seguridad al ejecutar contenedores como usuarios no root de forma predeterminada. A diferencia de Docker, que requiere privilegios de root para ejecutar contenedores, Podman puede ejecutar contenedores sin privilegios de root.Para utilizar Podman, primero debes instalarlo en tu sistema. Luego, puedes construir y ejecutar tus contenedores utilizando los comandos de Podman en lugar de los comandos de Docker. Por ejemplo:```bash # Construir la imagen podman build -t myapp .# Ejecutar el contenedor podman run -d --name myapp myapp ```Al utilizar Podman, tus contenedores se ejecutarán automáticamente como usuarios no root, lo que proporciona una capa adicional de seguridad.4. Utilizar volúmenes con el usuario correctoCuando utilizas volúmenes para compartir archivos entre el host y el contenedor, es importante asegurarse de que los archivos tengan los permisos correctos para el usuario no root dentro del contenedor. Puedes hacer esto utilizando la opción -u de docker run para especificar el usuario y el grupo:```bash docker run -d --name myapp -v /host/path:/container/path -u appuser:appgroup myapp ```En este ejemplo, especificamos el usuario "appuser" y el grupo "appgroup" utilizando la opción -u. Esto asegura que los archivos en el volumen sean accesibles para el usuario no root dentro del contenedor.5. Utilizar herramientas de seguridad adicionalesAdemás de ejecutar contenedores como usuarios no root, hay otras herramientas y prácticas que puedes utilizar para mejorar la seguridad de tus contenedores Docker:- Escaneo de vulnerabilidades: Utiliza herramientas como Clair o Trivy para escanear tus imágenes de contenedor en busca de vulnerabilidades conocidas. - Redes de contenedores: Utiliza redes de contenedores para aislar tus contenedores y limitar la comunicación entre ellos. - Políticas de seguridad: Utiliza herramientas como SELinux o AppArmor para aplicar políticas de seguridad adicionales a tus contenedores.ConclusiónEjecutar contenedores Docker como usuarios no root es una práctica recomendada importante para mejorar la seguridad de tus aplicaciones contenerizadas. Al crear usuarios no root dentro de tus contenedores, configurar los permisos de archivos correctamente y utilizar herramientas como Podman, puedes reducir significativamente el riesgo de que un atacante obtenga acceso privilegiado a tu sistema.Recuerda siempre seguir las mejores prácticas de seguridad y mantener tus contenedores actualizados con las últimas actualizaciones de seguridad. Con estas medidas, puedes asegurarte de que tus contenedores Docker sean lo más seguros posible.

1. Especificar los IDs de usuario y grupo

Al crear un usuario no root, siempre especifique tanto el ID de usuario como el ID de grupo. Esta práctica ayuda a evitar conflictos con usuarios y grupos existentes en el sistema host. El uso de 1001 como se mostró en el ejemplo anterior es común, pero asegúrate de verificar los IDs existentes que puedan causar solapamientos.

2. Use Read-Only Filesystems

Ejecutar contenedores con sistemas de archivos de solo lectura mejora la seguridad. Puedes lograrlo al especificar el read-only opción al ejecutar tu contenedor.

docker run --solo-lectura -d my-node-app

This restricts writes to specific directories if needed (like /tmp o volúmenes montados).

3. Limit Container Capabilities

By default, containers run with a set of capabilities that can be excessive for many applications. You can drop unnecessary capabilities to further minimize security risks.

docker run --cap-drop ALL -d my-node-app

Luego, añade explícitamente cualquier capacidad que necesite tu aplicación, como NET_BIND_SERVICE for binding to lower ports.

4. Use Docker’s User Namespace

Docker ofrece una función llamada espacios de nombres de usuario que permite reasignar los ID de usuario y grupo en el contenedor a diferentes en el host. Esto añade otra capa de seguridad al garantizar que incluso si un atacante obtiene acceso al contenedor, sigue estando limitado por los ID reasignados.

Para habilitar los espacios de nombres de usuario, es necesario modificar la configuración del demonio de Docker. En Linux, esto se hace típicamente en /etc/docker/daemon.json. Añada la siguiente configuración:

{
  "userns-remap": "predeterminado"
}

5. Regularly Update Images

Keeping your base images updated is crucial for security. Make it a habit to regularly pull the latest versions of your base images and rebuild your containers.

docker pull node:14
docker build -t mi-app-node .

6. Usar Docker Compose para el desarrollo

El uso de Docker Compose puede simplificar la gestión de múltiples servicios. Puedes definir la configuración del usuario en tu docker-compose.yml archivo para asegurarte de que tus contenedores se ejecuten como usuarios no root:

versión: '3'
servicios:
  app:
    build: .
    usuario: appuser
    read_only: true

7. Monitor and Audit Containers

Implementing monitoring and auditing solutions can help in detecting issues in your containers. Tools such as Prometheus, Grafana, or more specialized container security tools can assist in monitoring resource usage, log management, and compliance checks.

Desafíos al ejecutar contenedores como usuarios no root

Aunque ejecutar contenedores Docker como usuarios no root mejora la seguridad, pueden surgir desafíos:1. **Permisos de archivo**: Los archivos creados dentro del contenedor pueden tener permisos que impidan el acceso desde el host o viceversa. Para solucionarlo, asegúrate de que el usuario dentro del contenedor tenga los permisos adecuados para los archivos y directorios necesarios.2. **Montaje de volúmenes**: Al montar volúmenes, los permisos del host pueden entrar en conflicto con los del contenedor. Utiliza la opción `:Z` o `:z` en el comando `docker run` para etiquetar el volumen con el contexto de seguridad adecuado.3. **Redes y puertos**: Algunas aplicaciones requieren privilegios elevados para enlazar a puertos privilegiados (por debajo del 1024). Considera utilizar puertos no privilegiados o configurar el sistema para permitir que el usuario no root enlace a estos puertos.4. **Dependencias del sistema**: Algunas herramientas o bibliotecas pueden requerir privilegios de root para instalarse o ejecutarse. Investiga alternativas que no requieran privilegios elevados o considera utilizar imágenes base que ya incluyan las dependencias necesarias.5. **Gestión de procesos**: Algunas operaciones de gestión de procesos, como cambiar la prioridad de un proceso o enviar señales, pueden requerir privilegios de root. Asegúrate de que el usuario no root tenga los permisos necesarios para realizar estas operaciones.6. **Configuración del sistema**: Algunas configuraciones del sistema, como ajustar los límites de recursos o modificar la configuración de red, pueden requerir privilegios de root. Considera utilizar herramientas o scripts que permitan realizar estas configuraciones sin privilegios elevados.7. **Integración con el host**: Algunas aplicaciones pueden necesitar interactuar con el sistema host de maneras que requieren privilegios de root. Investiga alternativas que permitan la integración sin necesidad de privilegios elevados o considera utilizar herramientas de virtualización que proporcionen un entorno aislado.8. **Depuración y diagnóstico**: Algunas herramientas de depuración y diagnóstico pueden requerir privilegios de root para acceder a información del sistema. Utiliza herramientas alternativas que no requieran privilegios elevados o considera ejecutar el contenedor con privilegios elevados solo cuando sea necesario para la depuración.9. **Actualizaciones y parches**: Algunas actualizaciones o parches pueden requerir privilegios de root para instalarse. Considera utilizar herramientas de gestión de paquetes que permitan la instalación sin privilegios elevados o automatizar el proceso de actualización.10. **Seguridad y cumplimiento**: Asegúrate de que la ejecución de contenedores como usuarios no root cumpla con las políticas de seguridad y cumplimiento de tu organización. Documenta y justifica las excepciones a la regla de no privilegios elevados cuando sea necesario.Al abordar estos desafíos, puedes mejorar la seguridad de tus contenedores Docker mientras mantienes la funcionalidad necesaria para tus aplicaciones.

1. Problemas de permisos

Si su aplicación intenta escribir en directorios o archivos para los que el usuario no root no tiene permisos, encontrará errores de permisos.

Para resolver esto, asegúrese de que los directorios a los que su aplicación necesita escribir tengan los permisos correctos establecidos en el Dockerfile o en tiempo de ejecución.

2. Compatibilidad con Aplicaciones Existente

Algunas aplicaciones pueden no estar diseñadas teniendo en cuenta la ejecución sin privilegios de root. Es posible que necesite reestructurar ciertos aspectos de sus aplicaciones para que funcionen correctamente con un usuario no root.

3. Capacidades Limitadas

Running as a non-root user limits certain operations, such as binding to privileged ports (ports below 1024). You may need to adjust your application or use a reverse proxy to route traffic appropriately.

Conclusión

Ejecutar contenedores Docker con usuarios no root es una práctica fundamental que mejora la seguridad de tus despliegues de aplicaciones. Al crear un usuario dedicado en tu Dockerfile, aprovechando mejores prácticas como el uso de sistemas de archivos de solo lectura, la limitación de capacidades y el empleo de espacios de nombres de usuario, puedes reducir significativamente la superficie de ataque de tus contenedores.

Aunque pueda haber desafíos al migrar aplicaciones existentes para que se ejecuten como usuarios no-root, los beneficios superan con creces los riesgos asociados a ejecutar contenedores como root. Al implementar las estrategias mencionadas en este artículo, estás adoptando un enfoque proactivo para proteger tus aplicaciones dockerizadas.

Additional Resources

Al comprender y aplicar estos principios, puedes garantizar que tus contenedores Docker operen de forma segura y eficiente mientras se minimizan los riesgos.