Como verificar o certificado SSL usado por um registro Docker

DockerBeginner
Pratique Agora

Introdução

Proteger o seu ambiente Docker é crucial, e verificar o certificado SSL usado pelo seu registro Docker é um passo essencial para manter essa segurança. Este tutorial irá guiá-lo através do processo de verificação de certificados SSL para registros Docker, ajudando-o a garantir uma comunicação segura e solucionar quaisquer problemas relacionados a certificados SSL.

Ao final deste laboratório, você entenderá como o Docker usa certificados SSL, será capaz de inspecionar e verificar os certificados usados pelos registros Docker e saberá como lidar com problemas comuns de certificado.

Compreendendo os Certificados SSL para Registros Docker

Registros Docker são repositórios onde as imagens Docker são armazenadas e distribuídas. Esses registros usam certificados SSL/TLS para proteger a comunicação entre o seu cliente Docker e o servidor do registro. Vamos entender o que são esses certificados e por que eles são importantes.

O que é um Certificado SSL/TLS?

Um certificado SSL/TLS é um documento digital que:

  • Estabelece uma conexão segura entre um cliente e um servidor
  • Criptografa os dados transmitidos entre eles
  • Verifica a identidade do servidor

Quando você se conecta a um registro Docker, o seu cliente Docker verifica o certificado SSL do registro para garantir que a conexão seja segura e que você esteja se conectando ao registro legítimo.

Examinando Informações do Certificado com OpenSSL

Vamos começar explorando como verificar as informações do certificado usando o OpenSSL, uma ferramenta poderosa para trabalhar com certificados SSL.

Primeiro, vamos criar um diretório para o nosso trabalho de laboratório:

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

Agora, vamos verificar o certificado SSL para o Docker Hub, que é um registro Docker comum:

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

Este comando conecta-se ao Docker Hub e exibe informações sobre seu certificado SSL. Você deve ver muitas informações na saída, incluindo:

  • A cadeia de certificados (certificate chain)
  • Informações do emissor (issuer information)
  • Datas de validade do certificado
  • A chave pública

Vamos extrair apenas as informações do certificado em um formato mais legível:

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

Este comando mostra as primeiras 20 linhas dos detalhes do certificado, que incluem informações importantes como:

  • Versão
  • Número de Série
  • Algoritmo de Assinatura
  • Emissor (a Autoridade Certificadora)
  • Período de validade
  • Assunto (a quem o certificado pertence)

Compreender essas informações é o primeiro passo para verificar a autenticidade de um certificado.

Verificando Certificados SSL de Registro com a CLI Docker

Agora que entendemos os conceitos básicos de certificados SSL, vamos aprender como verificar certificados especificamente para registros Docker usando a CLI Docker.

Usando docker info para Verificar a Configuração do Registro

A CLI Docker fornece ferramentas para examinar as configurações do registro, incluindo suas configurações de certificado.

Vamos verificar as configurações atuais do registro que o Docker conhece:

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

Este comando gera a saída dos detalhes de configuração para todos os registros que o daemon Docker conhece, formatados em uma estrutura JSON legível. Você notará que o Docker Hub (em index.docker.io) está configurado por padrão.

Testando uma Conexão a um Registro

Vamos tentar conectar ao Docker Hub para verificar seu certificado:

docker login

Quando solicitado, você pode pressionar Ctrl+C para cancelar o login, pois estamos apenas testando a conexão, não fazendo login de fato.

O cliente Docker verifica automaticamente o certificado SSL do registro durante o processo de login. Se o certificado for válido, você verá o prompt de login. Caso contrário, o Docker exibirá uma mensagem de erro.

Criando um Arquivo para Verificar um Registro Específico

Vamos criar um script para verificar o certificado de um registro específico de forma mais completa:

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

Agora, torne o script executável:

chmod +x check_registry_cert.sh

Vamos executá-lo para verificar o certificado do Docker Hub:

./check_registry_cert.sh

Você deve ver a saída mostrando:

  • Quando o certificado foi emitido e quando expira
  • Quem emitiu o certificado
  • A quem o certificado pertence
  • Informações sobre a cadeia de certificados

Vamos também verificar o certificado de outro registro, o registro de contêineres da Microsoft:

./check_registry_cert.sh mcr.microsoft.com

Compare as saídas para ver como os certificados podem diferir entre os registros.

Solucionando Problemas de Certificados SSL

Mesmo com um processo de verificação adequado, você pode encontrar problemas com certificados SSL ao trabalhar com registros Docker. Vamos aprender como identificar e resolver os problemas mais comuns.

Problemas Comuns de Certificados SSL

Os problemas de certificado SSL mais frequentes incluem:

  1. Certificados autoassinados
  2. Certificados expirados
  3. Incompatibilidade de nome de host do certificado
  4. Autoridades de certificação não confiáveis

Vamos criar um diretório para simular e solucionar esses problemas:

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

Criando um Certificado Autoassinado de Teste

Primeiro, vamos criar um certificado autoassinado para entender como lidar com eles:

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

Este comando cria:

  • Uma chave privada (registry.key)
  • Um certificado autoassinado (registry.crt) válido por 365 dias

Vamos examinar nosso certificado autoassinado:

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

Observe que, em um certificado autoassinado, o Emissor (Issuer) e o Assunto (Subject) são os mesmos, pois o certificado se assinou.

Configurando o Docker para Confiar em um Certificado Autoassinado

Para fazer com que o Docker confie em um certificado autoassinado, você normalmente o adicionaria ao diretório de certificados do Docker. Vamos criar a estrutura de diretórios necessária:

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

Após adicionar um certificado, você normalmente reiniciaria o Docker:

## We won't actually restart Docker in this lab
echo "In a real environment, you would run: sudo systemctl restart docker"

Lidando com Certificados Expirados

Vamos simular a verificação de um certificado expirado criando um com uma data de expiração passada:

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

Agora, vamos examinar o certificado expirado:

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

Você verá que a data "Not After" está no passado, o que significa que o certificado expirou.

Configurando Registros Inseguros

Em alguns casos, você pode precisar usar registros com problemas de certificado. O Docker permite que você marque registros específicos como "inseguros":

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

echo "In a real environment, you would place this file at /etc/docker/daemon.json"
cat daemon.json

Esta configuração diz ao Docker para ignorar a verificação de certificado para esses registros, o que pode ser útil para ambientes de teste, mas deve ser evitado em produção.

Script para Verificar a Expiração do Certificado

Vamos criar um script útil para verificar se um certificado está prestes a expirar:

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

Vamos testar nosso script com ambos os certificados:

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

Você verá que o script identifica corretamente o certificado válido e o expirado.

Melhores Práticas para Certificados SSL de Registro Docker

Agora que entendemos como verificar e solucionar problemas de certificados SSL, vamos explorar as melhores práticas para gerenciar certificados com registros Docker.

Automatizando a Verificação de Certificados

É essencial verificar regularmente seus certificados para evitar falhas inesperadas. Vamos criar um script que pode ser agendado para ser executado periodicamente:

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

Vamos executar o script para ver como ele funciona:

./monitor_registry_certs.sh

Este script verifica vários registros e avisa se algum certificado está próximo da expiração, o que é crucial para evitar tempo de inatividade inesperado.

Melhores Práticas de Gerenciamento de Certificados

Vamos criar um documento descrevendo as melhores práticas para o gerenciamento de certificados de registro Docker:

cat > certificate_best_practices.md << 'EOF'
## Melhores Práticas de Gerenciamento de Certificados de Registro Docker

### Aquisição de Certificados
- Use certificados de Autoridades de Certificação (CA) confiáveis para ambientes de produção
- Use tipos de certificado apropriados (DV, OV ou EV com base nas necessidades)
- Certifique-se de que os certificados correspondam aos nomes de domínio exatos usados para acessar os registros
- Considere certificados curinga para vários subdomínios
- Use comprimentos de chave apropriados (mínimo de 2048 bits para RSA)

### Implantação de Certificados
- Armazene os certificados com segurança
- Use permissões de arquivo adequadas (legíveis apenas pelo daemon Docker)
- Faça backup de certificados e chaves privadas com segurança
- Implemente procedimentos adequados de rotação de certificados
- Mantenha os caminhos dos certificados consistentes em todos os nós de um cluster

### Monitoramento e Manutenção
- Configure alertas para certificados próximos da expiração (pelo menos 30 dias de antecedência)
- Mantenha um inventário de todos os certificados em uso
- Documente os procedimentos de renovação
- Teste as renovações de certificados em um ambiente de teste antes da produção
- Automatize a renovação de certificados sempre que possível (usando ferramentas como certbot)

### Considerações de Segurança
- Nunca use registros inseguros em ambientes de produção
- Evite usar certificados autoassinados em produção
- Implemente procedimentos adequados de revogação de certificados
- Audite regularmente o uso e as permissões dos certificados
- Mantenha o pacote CA atualizado em todos os sistemas
EOF

cat certificate_best_practices.md

Criando um Modelo de Configuração para Registros Seguros

Finalmente, vamos criar um modelo para uma configuração de registro Docker seguro:

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 configuração fornece um modelo para executar um registro Docker seguro com a configuração adequada de certificado SSL.

Resumo das Etapas de Gerenciamento de Certificados SSL

Vamos criar uma referência rápida para o gerenciamento de certificados SSL com Docker:

cat > ssl_management_summary.txt << 'EOF'
## Resumo do Gerenciamento de Certificados SSL de Registro Docker

1. VERIFIQUE o certificado de um registro:
   openssl s_client -connect registry.example.com:443 -showcerts </dev/null

2. ADICIONE um certificado personalizado para um registro:
   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 um registro inseguro (somente para desenvolvimento):
   Adicione a /etc/docker/daemon.json:
   { "insecure-registries": ["registry.example.com:5000"] }
   sudo systemctl restart docker

4. VERIFIQUE as datas de expiração regularmente:
   openssl x509 -in certificate.crt -noout -dates

5. AUTOMATIZE o monitoramento de certificados:
   Crie e agende scripts para verificar os certificados regularmente
EOF

cat ssl_management_summary.txt

Este resumo serve como uma referência rápida para as operações mais comuns relacionadas a certificados SSL de registro Docker.

Resumo

Neste laboratório, você aprendeu como verificar e gerenciar certificados SSL para registros Docker. Agora você tem o conhecimento e as ferramentas para:

  • Entender o que são certificados SSL e por que eles são essenciais para a segurança do registro Docker
  • Verificar certificados SSL usando comandos OpenSSL e Docker CLI
  • Solucionar problemas comuns de certificado, como certificados expirados e certificados autoassinados
  • Implementar as melhores práticas para o gerenciamento de certificados
  • Configurar o Docker para trabalhar com vários cenários de certificado
  • Automatizar o monitoramento de certificados para evitar falhas inesperadas

Essas habilidades são cruciais para manter ambientes Docker seguros, especialmente em configurações de produção, onde a segurança é primordial. Ao verificar regularmente e gerenciar adequadamente seus certificados SSL de registro Docker, você pode evitar vulnerabilidades de segurança e garantir operações suaves para suas aplicações em contêineres.