La imagen que iba bien el año pasado
Un equipo construyó una imagen de servidor web hace un año y la ha usado desde entonces. Funcionaba, así que nadie la tocó.
En ese año se encontraron tres fallos en programas que lleva dentro. El equipo nunca miró, pero un escáner los habría encontrado.
Esta lección revisa una imagen como un defensor, antes de que alguien ataque.
Al final de esta lección
Nota
Puedo revisar qué ejecuta una imagen, qué versiones contiene y si alguna está desactualizada.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Imagen | una copia empaquetada de un programa y lo que necesita, de la que arrancan los contenedores | |
| Etiqueta | el rótulo tras los dos puntos en el nombre de una imagen | 1.27.5-alpine |
| Fijar | nombrar una versión exacta para que no cambie por sorpresa | |
| Paquete | un programa o biblioteca instalado en la imagen | |
| Aviso | una nota que dice qué versión arregló un fallo conocido | |
| Escaneo | comparar lo instalado con una lista de fallos conocidos |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Una etiqueta dice qué versión ejecutas
Un contenedor arranca desde una imagen. El nombre de la imagen termina con una etiqueta, como nginx:1.27.5-alpine.
Una etiqueta latest significa lo más nuevo de hoy. Cambia bajo tus pies. Una etiqueta fijada nombra una versión exacta: sabes qué ejecutas y decides cuándo cambiar.
¿Qué imagen ejecuta el servicio web?
docker inspect web --format '{{.Config.Image}}'Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
¿Qué nginx lleva dentro?
docker exec web nginx -vSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Qué escribieron los dos Run
El primero escribió nginx:1.27.5-alpine. La etiqueta es una versión: esta imagen está fijada. El segundo escribió nginx version: nginx/1.27.5.
Las dos respuestas deben coincidir. Si la etiqueta dice una cosa y el programa otra, alguien cambió la imagen.
¿Quién ejecuta los procesos?
docker exec web ps -o user,args | head -n 3Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Root y el trabajador
El Run escribió un encabezado, luego una línea root con el proceso principal, y luego una línea nginx con un trabajador.
El principal es root para poder abrir el puerto 80. Los trabajadores, que atienden a los visitantes, corren con la cuenta simple nginx. Un fallo en un trabajador da mucho menos a un atacante. Si todo corriera como root, el mismo fallo daría todo el contenedor.
Un inventario va antes de un escaneo
Un escáner hace tres cosas. Lista los paquetes, lee una lista de fallos y sus arreglos, y compara las dos.
Puedes hacer la primera y la tercera en el laboratorio. Un escáner real saca su lista de fallos de internet, y el laboratorio no tiene salida: así que escribirás dos avisos inventados.
¿Cuántos paquetes hay instalados?
docker exec web apk info 2>/dev/null | wc -lSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Muestra las versiones de dos de ellos
docker exec web apk info -v 2>/dev/null | grep -E '^(zlib|musl)-[0-9]'Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
El inventario
Cuando se probó, el conteo fue 68, y las dos líneas fueron musl-1.2.5-r9 y zlib-1.3.1-r2. Cada línea es un nombre, una versión y un número de compilación.
Ahora un aviso inventado: «zlib se arregla en la 1.3.2-r0». Alpine sabe comparar dos versiones por ti, sin conexión.
¿El zlib es más viejo que el arreglo?
docker exec web apk version -t 1.3.1-r2 1.3.2-r0Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Compara musl con un arreglo igual
docker exec web apk version -t 1.2.5-r9 1.2.5-r9Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Qué significan los símbolos
El primer Run escribió <. La versión instalada es más vieja que el arreglo: ese paquete necesitaría una actualización. El segundo escribió =: ya está en la versión arreglada.
Un símbolo > significaría más nueva que el arreglo. Esto es todo un escaneo: un inventario, un aviso y una comparación.
Ejemplo: qué decide un escaneo
| Paquete | Instalado | Arreglado en | Resultado |
|---|---|---|---|
| zlib | 1.3.1-r2 | 1.3.2-r0 | Más viejo: actualizar |
| musl | 1.2.5-r9 | 1.2.5-r9 | Igual: arreglado |
| curl | 8.12.1-r1 | 8.12.0-r0 | Más nuevo: arreglado |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
¿Qué lleva la imagen en su entorno?
docker inspect web --format '{{json .Config.Env}}'Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Un error frecuente
Advertencia
Mucha gente escanea una vez, no ve nada y no vuelve a escanear. Cada semana se encuentran fallos nuevos: una imagen limpia el mes pasado puede no serlo hoy. Escanea según un calendario, y otra vez cada vez que cambie la imagen.
Lo que el laboratorio no puede mostrar
Un laboratorio no puede descargar, construir ni escanear imágenes: inspeccionaste el servicio en marcha, no el archivo de la imagen. En la máquina de prueba, el Run del entorno solo escribió valores que la propia imagen fija, como la versión. Eso es lo que debe contener.
Una contraseña en esa lista sería una fuga. Cualquiera que pueda inspeccionar el contenedor la puede leer.
Para ir más lejos: tras tus arreglos
Termina los arreglos del laboratorio y ejecuta docker exec web lab-check. Repite los tres Run de esta lección y escribe una frase: ¿cambió alguno?
La configuración es lo que endureciste. La imagen y sus paquetes no, porque arreglar la configuración no actualiza un paquete.