Introducción
Los secretos de compilación pueden filtrarse a las imágenes cuando un Dockerfile copia demasiado contexto de compilación. El error común es COPY . /app/: es conveniente, pero puede incluir tokens, credenciales, notas locales y archivos temporales en la imagen final. Una vez que un secreto está dentro de una capa de imagen, los controles en tiempo de ejecución no pueden eliminar de manera fiable este error en la cadena de suministro.
En este laboratorio, creará una imagen local deliberadamente vulnerable, demostrará que un token de compilación está presente en ella, luego corregirá la compilación limitando el alcance de la instrucción COPY en el Dockerfile y añadiendo un archivo .dockerignore. Finalmente, desplegará la imagen limpia y verificará que el contenedor en tiempo de ejecución ya no contenga el secreto de compilación.
Inspeccionar el contexto de compilación inseguro
En este paso, inspeccionará el contexto de compilación y el Dockerfile inseguro. El contexto de compilación es el directorio enviado al constructor de imágenes. Si el Dockerfile copia todo el contexto, cada archivo en ese directorio puede convertirse en parte de la imagen final.
Comience en el espacio de trabajo del laboratorio:
cd /home/labex/project/build-secret-image
Lea las notas:
sed -n '1,120p' BUILD_SECRET_NOTES.md
Enumere los archivos que existen actualmente en el contexto de compilación:
find . -maxdepth 1 -type f -printf '%f\n' | sort | tee evidence/initial-context-files.txt
Revise el Dockerfile inseguro:
sed -n '1,120p' Dockerfile.insecure | tee evidence/insecure-dockerfile-review.txt
La línea de riesgo es COPY . /app/. Copia app.sh, pero también copia build-token.txt. En el siguiente paso, creará esta imagen y demostrará la fuga desde dentro del tiempo de ejecución de la imagen.
Crear la imagen con fugas y demostrar que el secreto está presente
En este paso, creará la imagen insegura dentro del perfil de minikube labex-v134. Construir dentro del perfil hace que la imagen sea visible para el tiempo de ejecución del nodo de Kubernetes.
Copie el Dockerfile inseguro al nombre de Dockerfile activo y cree la imagen con fugas:
cp Dockerfile.insecure Dockerfile
minikube -p labex-v134 image build -t labex/leaky-build:1.0 .
Ejecute la imagen dentro del tiempo de ejecución de Docker de minikube y busque el archivo del token:
minikube -p labex-v134 ssh -- 'docker run --rm --entrypoint /bin/sh labex/leaky-build:1.0 -c "ls -l /app && cat /app/build-token.txt"' | tee evidence/leaky-image-contents.txt
Debería ver build-token=labex-temporary-secret. Esa es la fuga. La imagen se ejecuta, pero contiene un archivo que debería haber permanecido fuera de la imagen final en tiempo de ejecución.
Crear una imagen limpia con un límite de copia restringido
En este paso, corregirá la compilación de la imagen. Dos cambios son importantes: .dockerignore mantiene el token fuera del contexto de compilación enviado al constructor, y el Dockerfile copia solo app.sh en lugar de copiar todo el directorio.
Cree .dockerignore:
cat > .dockerignore <<'EOF'
build-token.txt
evidence/
*.txt
EOF
Cree el Dockerfile limpio:
cat > Dockerfile <<'EOF'
FROM busybox:1.36
WORKDIR /app
COPY app.sh /app/app.sh
RUN chmod 0555 /app/app.sh
USER 65534:65534
ENTRYPOINT ["/app/app.sh"]
EOF
Cree la imagen limpia:
minikube -p labex-v134 image build -t labex/clean-build:1.0 .
Inspeccione la imagen limpia desde dentro del tiempo de ejecución de Docker de minikube:
minikube -p labex-v134 ssh -- 'docker run --rm --entrypoint /bin/sh labex/clean-build:1.0 -c "ls -l /app; if [ -f /app/build-token.txt ]; then echo BUILD_SECRET_PRESENT; else echo NO_BUILD_SECRET; fi; id -u"' | tee evidence/clean-image-contents.txt
La salida debería mostrar NO_BUILD_SECRET y el UID 65534.
Desplegar la imagen limpia
En este paso, desplegará la imagen limpia y verificará que el contenedor en ejecución informe que no hay ningún secreto de compilación presente. Esto mantiene la prueba final cerca de Kubernetes, donde la imagen se ejecutará realmente.
Cree y aplique el manifiesto del Pod:
cat > clean-build-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: clean-build-app
namespace: cks-prep-build-secret
labels:
app: clean-build-app
spec:
restartPolicy: Never
containers:
- name: app
image: labex/clean-build:1.0
imagePullPolicy: Never
securityContext:
runAsNonRoot: true
runAsUser: 65534
runAsGroup: 65534
allowPrivilegeEscalation: false
EOF
kubectl apply -f clean-build-pod.yaml
Espere a que el Pod esté listo y lea sus registros:
kubectl -n cks-prep-build-secret wait --for=condition=Ready pod/clean-build-app --timeout=120s
kubectl -n cks-prep-build-secret logs clean-build-app | tee evidence/clean-pod-logs.txt
Los registros deberían incluir:
clean build image ready
NO_BUILD_SECRET
Resumen
Inspeccionó un contexto de compilación de imagen inseguro, creó una imagen con fugas, demostró que el token de compilación estaba presente y luego corrigió la compilación con .dockerignore y una instrucción COPY de Dockerfile más específica. Creó y desplegó una imagen limpia que se ejecuta como un usuario no root e informa NO_BUILD_SECRET. Esto completa la etapa de la cadena de suministro al conectar la higiene en la compilación de imágenes con la verificación en tiempo de ejecución de Kubernetes.



