Prácticas recomendadas de seguridad para las tareas y contenedores de Amazon ECS - Amazon Elastic Container Service

Prácticas recomendadas de seguridad para las tareas y contenedores de Amazon ECS

Debe considerar la imagen del contenedor como su primera línea de defensa contra un ataque. Una imagen insegura y mal construida puede permitir que un atacante escape de los límites del contenedor y acceder al host. Debe hacer lo siguiente para reducir el riesgo de que esto ocurra.

Al configurar las tareas y los contenedores, recomendamos que realice las siguientes acciones.

Cree imágenes minimalistas o utilice imágenes sin distribución.

Comience por eliminar todos los archivos binarios extraños de la imagen del contenedor. Si utiliza una imagen desconocida de la galería pública de Amazon ECR, inspeccione la imagen para consultar el contenido de cada una de las capas del contenedor. Para ello, puede utilizar una aplicación como Dive.

Como alternativa, puede usar imágenes sin distribución que solo incluyan su aplicación y sus dependencias de tiempo de ejecución. Estas no contienen administradores ni intérprete de comandos de paquetes. Las imágenes sin distribución mejoran la “relación señal-ruido de los escáneres y reducen el esfuerzo de establecer la procedencia a lo que se necesita”. Para obtener más información, consulte la documentación sobre sin distribución en GitHub.

Docker cuenta con un mecanismo para crear imágenes a partir de una imagen reservada y minimalista conocida como scratch. Para obtener más información, consulte Crear una imagen principal simple mediante scratch en la documentación de Docker. Con lenguajes como Go, puede crear un binario enlazado estático y hacer referencia a él en el Dockerfile. En los siguientes ejemplos, se muestra cómo hacerlo:

############################ # STEP 1 build executable binary ############################ FROM golang:alpine AS builder # Install git. # Git is required for fetching the dependencies. RUN apk update && apk add --no-cache git WORKDIR $GOPATH/src/mypackage/myapp/ COPY . . # Fetch dependencies. # Using go get. RUN go get -d -v # Build the binary. RUN go build -o /go/bin/hello ############################ # STEP 2 build a small image ############################ FROM scratch # Copy our static executable. COPY --from=builder /go/bin/hello /go/bin/hello # Run the hello binary. ENTRYPOINT ["/go/bin/hello"] This creates a container image that consists of your application and nothing else, making it extremely secure.

El ejemplo anterior también ilustra una compilación de varias etapas. Estos tipos de compilaciones son atractivos desde el punto de vista de la seguridad porque se pueden utilizar para minimizar el tamaño de la imagen final que se envía al registro del contenedor. Las imágenes de contenedores sin herramientas de compilación ni otros binarios desconocidos mejoran la seguridad al reducir la superficie expuesta a ataques de la imagen. Para obtener más información sobre las compilaciones de varias etapas, consulte Crear compilaciones de varias etapas.

Escanear las imágenes para detectar vulnerabilidades

Al igual que las máquinas virtuales homólogas, las imágenes de contenedores pueden contener binarios y bibliotecas de aplicaciones con vulnerabilidades o, con el tiempo, pueden surgir vulnerabilidades en ellas. La mejor forma de protegerse contra las vulnerabilidades es escanear las imágenes con regularidad con un escáner de imágenes.

Las imágenes almacenadas en Amazon ECR se pueden escanear de forma automática o bajo demanda (una vez cada 24 horas). El escaneo básico de Amazon ECR utiliza Clair, una solución de escaneo de imágenes de código abierto. El escaneo mejorado de Amazon ECR utiliza Amazon Inspector. Tras escanear una imagen, los resultados se registran en la transmisión de eventos de Amazon ECR en Amazon EventBridge. También puede ver los resultados de un escaneo desde la consola de Amazon ECR o llamando a la API DescribeImageScanFindings. Las imágenes con una vulnerabilidad HIGH o CRITICAL deben eliminarse o reconstruirse. Si una imagen que se ha implementado presenta una vulnerabilidad, debe sustituirse lo antes posible.

La versión 2.3.6.0 o posterior de Docker Desktop Edge puede escanear imágenes locales. Los escaneos se basan en Snyk, un servicio de seguridad de aplicaciones. Cuando se descubren vulnerabilidades, Snyk identifica las capas y las dependencias en las que se encuentra la vulnerabilidad en el Dockerfile. También recomienda alternativas seguras, como usar una imagen base más delgada con menos vulnerabilidades o actualizar un paquete concreto a una versión más reciente. Al utilizar el escaneo de Docker, los desarrolladores pueden resolver posibles problemas de seguridad antes de enviar sus imágenes al registro.

Eliminar los permisos especiales de sus imágenes

Los marcadores de derechos de acceso setuid y setgid permiten ejecutar un ejecutable con los permisos del propietario o del grupo del ejecutable. Elimine todos los binarios con estos derechos de acceso de la imagen, ya que estos binarios se pueden usar para aumentar los privilegios. Considere la posibilidad de eliminar todos los intérpretes de comandos y utilidades similares a nc y curl que puedan usarse con fines malintencionados. Puede encontrar los archivos con derechos de acceso setuid y setgid con el siguiente comando.

find / -perm /6000 -type f -exec ls -ld {} \;

Para eliminar los permisos especiales de estos archivos, agregue la siguiente directiva a la imagen del contenedor.

RUN find / -xdev -perm /6000 -type f -exec chmod a-s {} \; || true

Crear un conjunto de imágenes mantenidas

En lugar de permitir que los desarrolladores creen sus propias imágenes, cree un conjunto de imágenes revisadas para las diferentes pilas de aplicaciones de la organización. De este modo, los desarrolladores pueden prescindir de aprender cómo componer Dockerfiles y concentrarse en escribir código. A medida que los cambios se van integrando en el código base, una canalización de CI/CD puede compilar automáticamente el activo y, a continuación, almacenarlo en un repositorio de artefactos. Y, por último, copie el artefacto en la imagen correspondiente antes de subirlo a un registro de Docker, como Amazon ECR. Como mínimo, debe crear un conjunto de imágenes base a partir de las cuales los desarrolladores puedan crear sus propios Dockerfiles. Debe evitar extraer imágenes de Docker Hub. No siempre se sabe lo que hay en la imagen y aproximadamente una quinta parte de las 1000 imágenes principales tienen vulnerabilidades. Puede encontrar una lista de esas imágenes y sus vulnerabilidades en https://vulnerablecontainers.org/.

Escanear los paquetes y las bibliotecas de aplicaciones para detectar vulnerabilidades

El uso de bibliotecas de código abierto ahora es común. Al igual que ocurre con los sistemas operativos y los paquetes de sistemas operativos, estas bibliotecas pueden tener vulnerabilidades. Como parte del ciclo de vida del desarrollo, estas bibliotecas deben escanearse y actualizarse cuando se encuentren vulnerabilidades críticas.

Docker Desktop realiza escaneos locales con Snyk. También se puede utilizar para encontrar vulnerabilidades y posibles problemas de licencia en bibliotecas de código abierto. Se puede integrar directamente en los flujos de trabajo de los desarrolladores, lo que permite mitigar los riesgos que plantean las bibliotecas de código abierto. Para obtener más información, consulte los temas siguientes:

Realizar un análisis de código estático

Debe realizar un análisis de código estático antes de crear una imagen de contenedor. Se realiza en función del código fuente y se utiliza para identificar errores de codificación y códigos que un agente malintencionado podría aprovechar, como las inserciones de errores. Puede usar Amazon Inspector. Para obtener más información, consulte Escaneo de imágenes de contenedor de Amazon ECR con Amazon Inspector en la Guía del usuario de Amazon Inspector.

Ejecutar contenedores como usuario no raíz

Debe ejecutar contenedores como usuario no raíz. De forma predeterminada, los contenedores se ejecutan como usuario root, a menos que la directiva USER esté incluida en el Dockerfile. Las capacidades predeterminadas de Linux asignadas por Docker restringen las acciones que se pueden ejecutar como root, pero solo de manera marginal. Por ejemplo, un contenedor que se ejecuta como root aún no puede acceder a los dispositivos.

Como parte de su canalización de CI/CD, debe utilizar Dockerfiles para buscar la directiva USER y fallar en la compilación si no existe. Para obtener más información, consulte los temas siguientes:

  • Dockerfile-lint es herramienta de código abierto de RedHat que se puede utilizar para comprobar si el archivo se ajusta a las prácticas recomendadas.

  • Hadolint es otra herramienta para crear imágenes de Docker que se ajusten a las prácticas recomendadas.

Utilizar un sistema de archivos raíz de solo lectura

Debe utilizar un sistema de archivos raíz de solo lectura. De forma predeterminada, se puede escribir en el sistema de archivos raíz de un contenedor. Cuando configuras un contenedor con un sistema de archivos raíz RO (de solo lectura), se obliga a definir explícitamente dónde se pueden persistir los datos. Esto reduce la superficie expuesta a ataques, ya que no se puede escribir en el sistema de archivos del contenedor a menos que se concedan permisos específicos.

nota

Tener un sistema de archivos raíz de solo lectura puede provocar problemas con algunos paquetes del sistema operativo que esperan poder escribir en el sistema de archivos. Si planea utilizar sistemas de archivos raíz de solo lectura, pruébelos minuciosamente de antemano.

Configurar tareas con límites de CPU y memoria (Amazon EC2)

Debe configurar las tareas con límites de CPU y memoria para minimizar los siguientes riesgos. Los límites de recursos de una tarea establecen un límite superior para la cantidad de CPU y memoria que pueden reservar todos los contenedores de una tarea. Si no se establece ningún límite, las tareas tienen acceso a la CPU y la memoria del host. Esto puede provocar problemas en los que las tareas implementadas en un host compartido pueden privar a otras tareas de recursos del sistema.

nota

En cuanto a las tareas de AWS Fargate, Amazon ECS requiere que especifique los límites de CPU y memoria, ya que utiliza estos valores a efectos de facturación. Una tarea que acapara todos los recursos del sistema no es un problema para Amazon ECS Fargate, ya que cada tarea se ejecuta en su propia instancia dedicada. Si no especifica un límite de memoria, Amazon ECS asigna un mínimo de 4 MB a cada contenedor. Del mismo modo, si no se establece ningún límite de CPU para la tarea, el agente de contenedor de Amazon ECS le asigna un mínimo de 2 CPU.

Utilizar etiquetas inmutables con Amazon ECR

Con Amazon ECR, puede y debe utilizar imágenes configuradas con etiquetas inmutables. Esto evita que se envíe una versión alterada o actualizada de una imagen a su repositorio de imágenes con una etiqueta idéntica. De este modo, se evita que un atacante coloque una versión comprometida de una imagen sobre la suya con la misma etiqueta. Al usar etiquetas inmutables, se obliga de forma efectiva a colocar una nueva imagen con una etiqueta diferente en cada cambio.

Evitar ejecutar contenedores con privilegios (Amazon EC2)

Debe evitar ejecutar contenedores con privilegios. En segundo plano, los contenedores ejecutados como privileged se ejecutan con privilegios ampliados en el host. Esto significa que el contenedor hereda todas las capacidades de Linux asignadas root en el host. Su uso debe estar estrictamente restringido o prohibido. Recomendamos configurar la variable de entorno del agente de contenedores de Amazon ECS en ECS_DISABLE_PRIVILEGED a true para evitar que los contenedores se ejecuten como privileged en determinados hosts si privileged no es necesario. Como alternativa, puede utilizar AWS Lambda para escanear las definiciones de las tareas para utilizar el parámetro privileged.

nota

Ejecutar un contenedor como privileged no es compatible con Amazon ECS en AWS Fargate.

Eliminar del contenedor las capacidades innecesarias de Linux

A continuación, se presenta una lista de las capacidades de Linux predeterminadas asignadas a los contenedores de Docker. Para obtener más información sobre cada capacidad, consulte Descripción general de las capacidades de Linux.

CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_FSETID, CAP_KILL, CAP_SETGID, CAP_SETUID, CAP_SETPCAP, CAP_NET_BIND_SERVICE, CAP_NET_RAW, CAP_SYS_CHROOT, CAP_MKNOD, CAP_AUDIT_WRITE, CAP_SETFCAP

Si un contenedor no requiere todas las capacidades del kernel de Docker enumeradas anteriormente, considere eliminarlas del contenedor. Para obtener más información sobre cada capacidad del kernel de Docker, consulte KernelCapabilities. Puede saber qué capacidades se están utilizando siguiendo los siguientes pasos:

  • Instale el paquete de sistema operativo libcap-ng y ejecute la utilidad pscap para enumerar las capacidades que utiliza cada proceso.

  • También puede utilizar capsh para descifrar qué capacidades utiliza un proceso.

Utilizar una clave administrada por el cliente (CMK) para cifrar imágenes enviadas a Amazon ECR

Debe utilizar una clave administrada por el cliente (CMK) para cifrar imágenes enviadas a Amazon ECR. Las imágenes que se envían a Amazon ECR se cifran automáticamente en reposo con una clave administrada AWS Key Management Service (AWS KMS). Si prefiere usar su propia clave, Amazon ECR ahora admite el cifrado AWS KMS con claves administradas por el cliente (CMK). Antes de habilitar el cifrado del lado del servidor con una CMK, consulte las consideraciones que se indican en la documentación sobre el cifrado en reposo.