Mantener los Secretos Fuera de las Imágenes de Contenedores

DockerBeginner
Practicar Ahora

Introducción

Un archivo eliminado de una imagen de contenedor puede seguir existiendo en una capa anterior de la imagen. Las reglas de exclusión de Git tampoco controlan lo que recibe Docker durante una construcción.

Investigarás una imagen preparada, restringirás sus entradas de construcción y verificarás cada capa de una imagen nueva. El proceso de trabajo y el flujo de Docker siguen el laboratorio anterior. Todas las credenciales son datos de prueba locales ficticios; la imagen base de la caché y las herramientas auxiliares de inspección están preparadas.

Inspeccionar las Entradas de Construcción Preparadas

En este paso separarás las reglas de exclusión del control de versiones de las entradas de construcción de Docker.

cd /home/labex/project/ticket-image
ls -a

ls -a incluye archivos cuyo nombre empieza por un punto. Este proyecto contiene el proceso de trabajo, la configuración pública, los directorios de entrada/salida, private.env y debug.txt. Los dos últimos son entradas privadas locales, no archivos de entrega.

cat .gitignore

Git ignora los dos nombres privados. Eso afecta al flujo de seguimiento de Git, no al contexto de construcción de Docker.

cat .dockerignore

El archivo está vacío actualmente. .dockerignore controla qué rutas excluye Docker cuando recibe el contexto de construcción. Un archivo puede estar ignorado por Git y aun así enviarse a una construcción de Docker.

cat Dockerfile

COPY . /app/ copia todo el contexto disponible. El posterior RUN rm ... elimina archivos privados del sistema de archivos final, pero no deshace la capa anterior de la imagen.

Encontrar la Copia Oculta en una Capa

En este paso compararás el sistema de archivos final con las capas guardadas de la imagen.

La etiqueta heredada preparada ticket-image:legacy se construyó con este Dockerfile. Ejecuta un contenedor de inspección de una sola ejecución. --rm elimina automáticamente este contenedor temporal cuando termina ls; su comando sustituye el inicio predeterminado del proceso de trabajo de la imagen:

sudo docker run --rm ticket-image:legacy ls -a /app

El directorio /app final no debería mostrar private.env ni debug.txt. Sigue conteniendo el proceso de trabajo y la configuración pública.

docker history muestra las instrucciones de construcción de la imagen. --no-trunc conserva el texto completo de las instrucciones:

sudo docker history --no-trunc ticket-image:legacy

Busca la copia amplia seguida de la eliminación. El historial explica la secuencia, pero no el contenido de cada archivo. La herramienta auxiliar preparada course-image-scan guarda esta imagen real y lee cada capa guardada y la configuración de la imagen:

sudo course-image-scan ticket-image:legacy

Espera hallazgos que nombren archivos privados en una capa anterior y una credencial de práctica objetivo con el valor oculto. El código de salida 1 significa que hay hallazgos; 2 o CHECK ERROR significa que la inspección falló. El alcance fijo de la herramienta son estos nombres privados indicados y esta credencial falsa, no el de un analizador completo de secretos de producción.

Las eliminaciones en capas posteriores no borran los bytes anteriores. Por tanto, no basta con que un ls del sistema de archivos final dé el resultado esperado.

Excluir las Entradas Privadas de Construcción

En este paso conservarás los archivos privados locales y los excluirás del contexto de Docker.

nano .dockerignore

Usa este archivo completo:

private.env
debug.txt
input/
output/

Cada línea es una ruta o un directorio que se excluirá. Estos patrones retiran la configuración privada, el material de depuración y los datos de ejecución de las entradas de construcción; el proceso de trabajo y config.public siguen disponibles.

Guarda con Ctrl+O, Enter y sal con Ctrl+X. No elimines los archivos privados locales. Ignorar una ruta debe limitar su inclusión, no destruir la configuración local.

Limitar el Alcance de Copia del Dockerfile

En este paso harás explícitas las entradas que necesita la imagen.

La instrucción de eliminación anterior ahora es innecesaria y fallaría porque los archivos excluidos no están disponibles. Abre el Dockerfile:

nano Dockerfile

Usa este archivo completo:

FROM desklite-base:1.37.0
WORKDIR /app
COPY worker.sh config.public /app/
USER nobody
CMD ["sh", "/app/worker.sh"]

COPY worker.sh config.public /app/ enumera solo los dos archivos de negocio necesarios. Conserva USER nobody y el comando de inicio original del laboratorio anterior. Guarda con Ctrl+O, Enter, Ctrl+X.

Los dos controles trabajan juntos: .dockerignore restringe las entradas de construcción disponibles y el COPY explícito restringe lo que incluye esta imagen. Ninguno depende de eliminar un secreto después de que haya entrado en una capa.

Construir e Inspeccionar el Nuevo Artefacto

En este paso inspeccionarás una imagen de entrega recién construida en lugar de cambiar el significado de las pruebas anteriores.

sudo docker build -t ticket-image:delivery .

Espera una construcción local correcta. La nueva etiqueta es distinta de ticket-image:legacy.

sudo course-image-scan ticket-image:delivery

Espera un PASS para cada capa guardada y la configuración de la imagen. Este resultado específico del objetivo no afirma haber detectado todos los secretos o vulnerabilidades posibles.

Ahora comprueba el contexto de forma independiente:

sudo course-context-check .

Esta herramienta auxiliar preparada construye una imagen temporal con una prueba fija de COPY ., aplica la misma inspección real de capas y después elimina esa imagen temporal. Espera PASS. Esto demuestra que los archivos privados se excluyeron del contexto, en lugar de simplemente omitirse mediante el COPY de entrega más limitado.

La imagen heredada puede seguir conteniendo el hallazgo original. Reconstruir un artefacto de entrega limpio no reescribe imágenes distribuidas anteriormente ni revoca credenciales filtradas. Las exposiciones reales requieren el proceso de reemplazo de credenciales aprendido anteriormente y la limpieza adecuada de copias antiguas. Aquí, el token objetivo es deliberadamente falso y la aceptación se refiere a la nueva imagen de entrega.

Ejecutar el Informe Original desde la Nueva Imagen

En este paso demostrarás que eliminar las entradas privadas de construcción conservó los archivos y el comportamiento necesarios del proceso de trabajo.

El directorio de salida ya pertenece al UID 65534 con acceso privado de escritura. Reutiliza el proceso de trabajo distinto de root y el flujo de montajes de enlace del laboratorio anterior:

sudo docker run -d --name ticket-image-worker --network none --mount type=bind,src=/home/labex/project/ticket-image/input,dst=/data/input,readonly --mount type=bind,src=/home/labex/project/ticket-image/output,dst=/data/output ticket-image:delivery
sudo docker exec ticket-image-worker id -u

Espera 65534.

sudo docker logs ticket-image-worker

Espera mode=report y tickets=2. La primera línea procede de la configuración pública necesaria; la segunda procede de leer la entrada original y escribir el informe real.

sudo docker exec ticket-image-worker cat /data/output/report.txt

Espera tickets=2. El proceso de trabajo sigue teniendo entrada de solo lectura y salida con escritura, sin necesitar configuración privada dentro de la imagen.

Confirmar las Fuentes Locales y las Pruebas de Entrega

En este paso terminarás con las entradas privadas locales y el artefacto de entrega seguro intactos.

Enumera los archivos fuente privados sin imprimir su contenido:

ls -l private.env debug.txt

Ambos deben seguir existiendo localmente. Eliminarlos eludiría el ejercicio previsto del límite de construcción.

sudo course-image-scan ticket-image:delivery
sudo docker ps

El análisis de entrega debería pasar y ticket-image-worker debería estar en ejecución. La comprobación del curso también prueba el contexto real de construcción, comprueba el ID de la imagen en ejecución y verifica el informe original. No hay ningún archivo de investigación escrito adicional que entregar.

Resumen

Restringiste las entradas reales de construcción de Docker, copiaste solo los archivos de negocio necesarios, inspeccionaste todas las capas guardadas y la configuración de la imagen, y conservaste el proceso de trabajo original que se ejecuta sin root. Un sistema de archivos final limpio por sí solo no habría demostrado este límite.