Skip to main content

Pregunta 16 | Superficie de Ataque Imagen Docker

Usar contexto: kubectl config use-context workload-prod

Hay un Deployment image-verify en el Namespace team-blue que ejecuta la imagen registry.killer.sh:5000/image-verify:v1. DevSecOps te ha pedido mejorar esta imagen:

Cambiando la imagen base a alpine:3.12

No instalando curl

Actualizando nginx para usar la restricción de versión >=1.18.0

Ejecutando el proceso principal como usuario myuser

No añadas nuevas líneas al Dockerfile, solo edita las existentes. El archivo está ubicado en /opt/course/16/image/Dockerfile.

Etiqueta tu versión como v2. Puedes construir, etiquetar y enviar usando:

cd /opt/course/16/image
podman build -t registry.killer.sh:5000/image-verify:v2 .
podman run registry.killer.sh:5000/image-verify:v2 # para probar tus cambios
podman push registry.killer.sh:5000/image-verify:v2
Haz que el Deployment use tu etiqueta de imagen actualizada v2.

Respuesta:

Primero deberíamos echar un vistazo a la Imagen Docker:

cd /opt/course/16/image
cp Dockerfile Dockerfile.bak
vim Dockerfile
# /opt/course/16/image/Dockerfile
FROM alpine:3.4
RUN apk update && apk add vim curl nginx=1.10.3-r0
RUN addgroup -S myuser && adduser -S myuser -G myuser
COPY ./run.sh run.sh
RUN ["chmod", "+x", "./run.sh"]
USER root
ENTRYPOINT ["/bin/sh", "./run.sh"]

Dockerfile muy simple que parece ejecutar un script run.sh:

# /opt/course/16/image/run.sh
while true; do date; id; echo; sleep 1; done

Así que solo genera la fecha actual y la información de credenciales en un bucle. Podemos ver esa salida en el Deployment image-verify existente:

➜ k -n team-blue logs -f -l id=image-verify
Fri Sep 25 20:59:12 UTC 2020
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)

Vemos que se está ejecutando como root.

A continuación actualizamos el Dockerfile según los requisitos:

# /opt/course/16/image/Dockerfile

# cambiar
FROM alpine:3.12

# cambiar
RUN apk update && apk add vim nginx>=1.18.0

RUN addgroup -S myuser && adduser -S myuser -G myuser
COPY ./run.sh run.sh
RUN ["chmod", "+x", "./run.sh"]

# cambiar
USER myuser

ENTRYPOINT ["/bin/sh", "./run.sh"]

Luego construimos la nueva imagen:

➜ :/opt/course/16/image$ podman build -t registry.killer.sh:5000/image-verify:v2 .
...
STEP 7/7: ENTRYPOINT ["/bin/sh", "./run.sh"]
COMMIT registry.killer.sh:5000/image-verify:v2
--> ceb8989101b
Successfully tagged registry.killer.sh:5000/image-verify:v2
ceb8989101bccd9f6b9c3b4c6c75f6c3561f19a5b784edd1f1a36fa0fb34a9df

Luego podemos probar nuestros cambios ejecutando el contenedor localmente:

➜ :/opt/course/16/image$ podman run registry.killer.sh:5000/image-verify:v2
Thu Sep 16 06:01:47 UTC 2021
uid=101(myuser) gid=102(myuser) groups=102(myuser)

Thu Sep 16 06:01:48 UTC 2021
uid=101(myuser) gid=102(myuser) groups=102(myuser)

Thu Sep 16 06:01:49 UTC 2021
uid=101(myuser) gid=102(myuser) groups=102(myuser)

Se ve bien, así que enviamos:

➜ :/opt/course/16/image$ podman push registry.killer.sh:5000/image-verify:v2
Getting image source signatures
Copying blob cd0853834d88 done
Copying blob 5298d0709c3e skipped: already exists
Copying blob e6688e911f15 done
Copying blob dbc406096645 skipped: already exists
Copying blob 98895ed393d9 done
Copying config ceb8989101 done
Writing manifest to image destination
Storing signatures

Y actualizamos el Deployment para usar la nueva imagen:

k -n team-blue edit deploy image-verify
# kubectl -n team-blue edit deploy image-verify
apiVersion: apps/v1
kind: Deployment
metadata:
...
spec:
...
template:
...
spec:
containers:
- image: registry.killer.sh:5000/image-verify:v2 # cambiar

# Y después podemos verificar nuestros cambios mirando los logs del Pod:
➜ k -n team-blue logs -f -l id=image-verify
Fri Sep 25 21:06:55 UTC 2020
uid=101(myuser) gid=102(myuser) groups=102(myuser)
#
También para verificar nuestros cambios aún más:

➜ k -n team-blue exec image-verify-55fbcd4c9b-x2flc -- curl
OCI runtime exec failed: exec failed: container_linux.go:349: starting container process caused "exec: \"curl\": executable file not found in $PATH": unknown
command terminated with exit code 126

➜ k -n team-blue exec image-verify-55fbcd4c9b-x2flc -- nginx -v
nginx version: nginx/1.18.0