¿Cómo verificar el certificado SSL utilizado por un registro Docker?

DockerBeginner
Practicar Ahora

Introducción

Asegurar su entorno Docker es crucial, y verificar el certificado SSL utilizado por su registro Docker es un paso esencial para mantener esta seguridad. Este tutorial le guiará a través del proceso de verificación de certificados SSL para registros Docker, ayudándole a garantizar una comunicación segura y a solucionar cualquier problema relacionado con los certificados SSL.

Al final de este laboratorio, comprenderá cómo Docker utiliza los certificados SSL, podrá inspeccionar y verificar los certificados utilizados por los registros Docker, y sabrá cómo manejar los problemas comunes de los certificados.

Comprensión de los Certificados SSL de Registro Docker

Los registros Docker son repositorios donde se almacenan y distribuyen las imágenes Docker. Estos registros utilizan certificados SSL/TLS para asegurar la comunicación entre su cliente Docker y el servidor del registro. Entendamos qué son estos certificados y por qué son importantes.

¿Qué es un Certificado SSL/TLS?

Un certificado SSL/TLS es un documento digital que:

  • Establece una conexión segura entre un cliente y un servidor
  • Cifra los datos transmitidos entre ellos
  • Verifica la identidad del servidor

Cuando se conecta a un registro Docker, su cliente Docker comprueba el certificado SSL del registro para asegurar que la conexión es segura y que se está conectando al registro legítimo.

Examinando la Información del Certificado con OpenSSL

Comencemos explorando cómo verificar la información del certificado utilizando OpenSSL, una herramienta poderosa para trabajar con certificados SSL.

Primero, creemos un directorio para nuestro trabajo de laboratorio:

mkdir -p ~/project/ssl-lab
cd ~/project/ssl-lab

Ahora, verifiquemos el certificado SSL para Docker Hub, que es un registro Docker común:

openssl s_client -connect hub.docker.com:443 -showcerts < /dev/null

Este comando se conecta a Docker Hub y muestra información sobre su certificado SSL. Debería ver mucha información en la salida, incluyendo:

  • La cadena de certificados (certificate chain)
  • Información del emisor (Issuer information)
  • Fechas de validez del certificado
  • La clave pública

Extraigamos solo la información del certificado en un formato más legible:

echo | openssl s_client -connect hub.docker.com:443 2> /dev/null | openssl x509 -text -noout | head -20

Este comando muestra las primeras 20 líneas de los detalles del certificado, que incluyen información importante como:

  • Versión
  • Número de serie (Serial Number)
  • Algoritmo de firma (Signature Algorithm)
  • Emisor (la Autoridad de Certificación - Certificate Authority)
  • Período de validez
  • Sujeto (a quién pertenece el certificado)

Comprender esta información es el primer paso para verificar la autenticidad de un certificado.

Verificación de Certificados SSL de Registro con la CLI de Docker

Ahora que entendemos los conceptos básicos de los certificados SSL, aprendamos a verificar los certificados específicamente para los registros Docker utilizando la CLI de Docker.

Uso de docker info para Verificar la Configuración del Registro

La CLI de Docker proporciona herramientas para examinar las configuraciones del registro, incluyendo sus ajustes de certificado.

Verifiquemos las configuraciones actuales del registro que Docker conoce:

docker info --format '{{json .RegistryConfig.IndexConfigs}}' | python3 -m json.tool

Este comando muestra los detalles de configuración para todos los registros que el demonio Docker conoce, formateados en una estructura JSON legible. Notará que Docker Hub (en index.docker.io) está configurado por defecto.

Probando una Conexión a un Registro

Intentemos conectarnos a Docker Hub para verificar su certificado:

docker login

Cuando se le solicite, puede presionar Ctrl+C para cancelar el inicio de sesión, ya que solo estamos probando la conexión, no iniciando sesión realmente.

El cliente Docker verifica automáticamente el certificado SSL del registro durante el proceso de inicio de sesión. Si el certificado es válido, verá el indicador de inicio de sesión. Si no, Docker mostrará un mensaje de error.

Creación de un Archivo para Verificar un Registro Específico

Creemos un script para verificar el certificado de un registro específico de manera más exhaustiva:

cat > check_registry_cert.sh << 'EOF'
#!/bin/bash

REGISTRY=${1:-"hub.docker.com"}
PORT=${2:-"443"}

echo "Checking certificate for $REGISTRY:$PORT..."
echo | openssl s_client -connect $REGISTRY:$PORT 2>/dev/null | openssl x509 -noout -dates -issuer -subject

echo -e "\nVerifying certificate chain..."
openssl s_client -connect $REGISTRY:$PORT -showcerts </dev/null 2>/dev/null | grep -A 1 "Certificate chain"
EOF

Ahora, hagamos que el script sea ejecutable:

chmod +x check_registry_cert.sh

Ejecutémoslo para verificar el certificado de Docker Hub:

./check_registry_cert.sh

Debería ver una salida que muestra:

  • Cuándo se emitió el certificado y cuándo expira
  • Quién emitió el certificado
  • A quién pertenece el certificado
  • Información sobre la cadena de certificados

Verifiquemos también el certificado para otro registro, el registro de contenedores de Microsoft:

./check_registry_cert.sh mcr.microsoft.com

Compare las salidas para ver cómo los certificados pueden diferir entre los registros.

Solución de Problemas de Certificados SSL

Incluso con un proceso de verificación adecuado, puede encontrar problemas con los certificados SSL al trabajar con registros Docker. Aprendamos a identificar y resolver los problemas más comunes.

Problemas Comunes de Certificados SSL

Los problemas de certificados SSL más frecuentes incluyen:

  1. Certificados autofirmados (self-signed certificates)
  2. Certificados caducados (expired certificates)
  3. Desajustes de nombre de host (hostname mismatches) en el certificado
  4. Autoridades de certificación (certificate authorities) no confiables

Creemos un directorio para simular y solucionar estos problemas:

mkdir -p ~/project/ssl-lab/troubleshooting
cd ~/project/ssl-lab/troubleshooting

Creación de un Certificado Autofirmado de Prueba

Primero, creemos un certificado autofirmado para entender cómo manejarlos:

openssl req -newkey rsa:2048 -nodes -keyout registry.key -x509 -days 365 -out registry.crt -subj "/CN=registry.example.com"

Este comando crea:

  • Una clave privada (registry.key)
  • Un certificado autofirmado (registry.crt) válido por 365 días

Examinemos nuestro certificado autofirmado:

openssl x509 -in registry.crt -text -noout | grep -E "Issuer|Subject|Not"

Observe que en un certificado autofirmado, el Emisor (Issuer) y el Sujeto (Subject) son iguales, ya que el certificado se firmó a sí mismo.

Configuración de Docker para Confiar en un Certificado Autofirmado

Para que Docker confíe en un certificado autofirmado, normalmente lo agregaría al directorio de certificados de Docker. Creemos la estructura de directorio necesaria:

sudo mkdir -p /etc/docker/certs.d/registry.example.com:5000
sudo cp registry.crt /etc/docker/certs.d/registry.example.com:5000/ca.crt

Después de agregar un certificado, normalmente reiniciaría Docker:

## No reiniciaremos Docker en este laboratorio
echo "En un entorno real, ejecutaría: sudo systemctl restart docker"

Manejo de Certificados Caducados

Simulemos la verificación de un certificado caducado creando uno con una fecha de caducidad pasada:

openssl req -newkey rsa:2048 -nodes -keyout expired.key -x509 -days -30 -out expired.crt -subj "/CN=expired.example.com"

Ahora examinemos el certificado caducado:

openssl x509 -in expired.crt -text -noout | grep -E "Issuer|Subject|Not"

Verá que la fecha "Not After" está en el pasado, lo que significa que el certificado ha caducado.

Configuración de Registros Inseguros

En algunos casos, es posible que deba usar registros con problemas de certificado. Docker le permite marcar registros específicos como "inseguros":

cat > daemon.json << 'EOF'
{
  "insecure-registries": [
    "registry.example.com:5000",
    "expired.example.com:5000"
  ]
}
EOF

echo "En un entorno real, colocaría este archivo en /etc/docker/daemon.json"
cat daemon.json

Esta configuración le dice a Docker que omita la verificación del certificado para estos registros, lo que puede ser útil para entornos de prueba, pero debe evitarse en producción.

Script para Verificar la Caducidad del Certificado

Creemos un script útil para verificar si un certificado está a punto de caducar:

cat > check_expiration.sh << 'EOF'
#!/bin/bash

CERT_FILE=$1
DAYS_WARNING=${2:-30}

if [ ! -f "$CERT_FILE" ]; then
    echo "Certificate file not found: $CERT_FILE"
    exit 1
fi

## Get expiration date in seconds since epoch
EXPIRY=$(openssl x509 -in "$CERT_FILE" -noout -enddate | cut -d= -f2)
EXPIRY_SECONDS=$(date -d "$EXPIRY" +%s)
NOW_SECONDS=$(date +%s)
SECONDS_LEFT=$((EXPIRY_SECONDS - NOW_SECONDS))
DAYS_LEFT=$((SECONDS_LEFT / 86400))

echo "Certificate: $CERT_FILE"
echo "Expires on: $EXPIRY"
echo "Days remaining: $DAYS_LEFT"

if [ $DAYS_LEFT -lt 0 ]; then
    echo "CRITICAL: Certificate has EXPIRED!"
    exit 2
elif [ $DAYS_LEFT -lt $DAYS_WARNING ]; then
    echo "WARNING: Certificate will expire in less than $DAYS_WARNING days!"
    exit 1
else
    echo "OK: Certificate is valid for more than $DAYS_WARNING days."
    exit 0
fi
EOF

chmod +x check_expiration.sh

Probemos nuestro script con ambos certificados:

./check_expiration.sh registry.crt
./check_expiration.sh expired.crt

Verá que el script identifica correctamente el certificado válido y el caducado.

Mejores Prácticas para Certificados SSL de Registro Docker

Ahora que entendemos cómo verificar y solucionar problemas de certificados SSL, exploremos las mejores prácticas para administrar certificados con registros Docker.

Automatización de la Verificación de Certificados

Es esencial verificar regularmente sus certificados para evitar fallos inesperados. Creemos un script que se pueda programar para ejecutarse periódicamente:

cd ~/project/ssl-lab
cat > monitor_registry_certs.sh << 'EOF'
#!/bin/bash

## List of registries to check
REGISTRIES=(
  "hub.docker.com"
  "mcr.microsoft.com"
  "registry.k8s.io"
  "quay.io"
)

echo "========================================"
echo "Docker Registry Certificate Monitor"
echo "========================================"
echo "Date: $(date)"
echo ""

for registry in "${REGISTRIES[@]}"; do
  echo "Checking $registry..."
  CERT_INFO=$(echo | openssl s_client -connect $registry:443 2>/dev/null | openssl x509 -noout -dates -issuer -subject 2>/dev/null)
  
  if [ -z "$CERT_INFO" ]; then
    echo "ERROR: Could not retrieve certificate for $registry"
  else
    echo "$CERT_INFO"
    
    ## Extract expiry date
    EXPIRY=$(echo "$CERT_INFO" | grep "notAfter" | cut -d= -f2)
    EXPIRY_SECONDS=$(date -d "$EXPIRY" +%s)
    NOW_SECONDS=$(date +%s)
    DAYS_LEFT=$(( (EXPIRY_SECONDS - NOW_SECONDS) / 86400 ))
    
    echo "Days until expiry: $DAYS_LEFT"
    
    if [ $DAYS_LEFT -lt 30 ]; then
      echo "WARNING: Certificate will expire in less than 30 days!"
    fi
  fi
  echo "----------------------------------------"
done
EOF

chmod +x monitor_registry_certs.sh

Ejecutemos el script para ver cómo funciona:

./monitor_registry_certs.sh

Este script verifica múltiples registros y le advierte si algún certificado está a punto de caducar, lo cual es crucial para prevenir el tiempo de inactividad inesperado.

Mejores Prácticas de Gestión de Certificados

Creemos un documento que describa las mejores prácticas para la gestión de certificados de registro Docker:

cat > certificate_best_practices.md << 'EOF'
## Docker Registry Certificate Management Best Practices

### Certificate Procurement
- Use certificates from trusted Certificate Authorities for production environments
- Use appropriate certificate types (DV, OV, or EV based on needs)
- Ensure certificates match the exact domain names used to access registries
- Consider wildcard certificates for multiple subdomains
- Use appropriate key lengths (minimum 2048 bits for RSA)

### Certificate Deployment
- Store certificates securely
- Use proper file permissions (readable only by the Docker daemon)
- Back up certificates and private keys securely
- Implement proper certificate rotation procedures
- Keep certificate paths consistent across all nodes in a cluster

### Monitoring and Maintenance
- Set up alerts for certificates nearing expiration (at least 30 days in advance)
- Maintain an inventory of all certificates in use
- Document renewal procedures
- Test certificate renewals in a staging environment before production
- Automate certificate renewal where possible (using tools like certbot)

### Security Considerations
- Never use insecure registries in production environments
- Avoid using self-signed certificates in production
- Implement proper certificate revocation procedures
- Regularly audit certificate usage and permissions
- Keep the CA bundle updated on all systems
EOF

cat certificate_best_practices.md

Creación de una Plantilla de Configuración para Registros Seguros

Finalmente, creemos una plantilla para una configuración de registro Docker segura:

cat > secure_registry_config.yml << 'EOF'
version: '3'

services:
  registry:
    image: registry:2
    ports:
      - 5000:5000
    environment:
      REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt
      REGISTRY_HTTP_TLS_KEY: /certs/domain.key
      ## Additional security settings
      REGISTRY_STORAGE_DELETE_ENABLED: "true"
      REGISTRY_HTTP_HEADERS_X_CONTENT_TYPE_OPTIONS: nosniff
      REGISTRY_HTTP_HEADERS_X_FRAME_OPTIONS: DENY
    volumes:
      - ./certs:/certs
      - ./data:/var/lib/registry
    restart: always
    
  ## Optional: Add a UI for your registry
  registry-ui:
    image: joxit/docker-registry-ui:latest
    ports:
      - 8080:80
    environment:
      - REGISTRY_URL=https://registry:5000
      - REGISTRY_TITLE=Secure Docker Registry
      - SINGLE_REGISTRY=true
    depends_on:
      - registry
EOF

cat secure_registry_config.yml

Esta configuración proporciona una plantilla para ejecutar un registro Docker seguro con la configuración adecuada del certificado SSL.

Resumen de los Pasos de Gestión de Certificados SSL

Creemos una referencia rápida para la gestión de certificados SSL con Docker:

cat > ssl_management_summary.txt << 'EOF'
## Docker Registry SSL Certificate Management Summary

1. VERIFY a registry's certificate:
   openssl s_client -connect registry.example.com:443 -showcerts </dev/null

2. ADD a custom certificate for a registry:
   sudo mkdir -p /etc/docker/certs.d/registry.example.com:5000
   sudo cp registry.crt /etc/docker/certs.d/registry.example.com:5000/ca.crt
   sudo systemctl restart docker

3. CONFIGURE an insecure registry (development only):
   Add to /etc/docker/daemon.json:
   { "insecure-registries": ["registry.example.com:5000"] }
   sudo systemctl restart docker

4. CHECK expiration dates regularly:
   openssl x509 -in certificate.crt -noout -dates

5. AUTOMATE certificate monitoring:
   Create and schedule scripts to check certificates regularly
EOF

cat ssl_management_summary.txt

Este resumen sirve como una referencia rápida para las operaciones más comunes relacionadas con los certificados SSL de registro Docker.

Resumen

En este laboratorio, aprendió a verificar y administrar certificados SSL para registros Docker. Ahora tiene el conocimiento y las herramientas para:

  • Comprender qué son los certificados SSL y por qué son esenciales para la seguridad del registro Docker
  • Verificar los certificados SSL utilizando comandos OpenSSL y Docker CLI
  • Solucionar problemas comunes de certificados como certificados caducados y certificados autofirmados (self-signed certificates)
  • Implementar las mejores prácticas para la gestión de certificados
  • Configurar Docker para que funcione con varios escenarios de certificados
  • Automatizar la supervisión de certificados para evitar fallos inesperados

Estas habilidades son cruciales para mantener entornos Docker seguros, especialmente en entornos de producción donde la seguridad es primordial. Al verificar y administrar adecuadamente sus certificados SSL de registro Docker de forma regular, puede prevenir vulnerabilidades de seguridad y garantizar operaciones fluidas para sus aplicaciones en contenedores.