Maison >interface Web >js tutoriel >Le défi du SSL dans les conteneurs Docker dont personne ne parle

Le défi du SSL dans les conteneurs Docker dont personne ne parle

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-10-06 18:38:03859parcourir

The Challenge About SSL in Docker Containers No One Talks About

Si vous avez déjà eu du mal à configurer SSL dans un environnement Docker, vous n'êtes pas seul. SSL peut être un obstacle intimidant pour beaucoup, mais il est crucial de sécuriser votre application, en particulier lorsqu'elle est exposée à Internet. Dans cet article, je vais vous guider dans l'ajout de Nginx et Certbot pour la génération SSL Let's Encrypt dans une configuration Dockerisée. Cela vous permet de renouveler automatiquement les certificats et de sécuriser votre environnement avec un minimum de tracas.

Plongeons-nous !

Conditions préalables

  • Docker et Docker Compose installés sur votre machine.
  • Compréhension de base de Docker Compose et Nginx.
  • Un nom de domaine pointant vers votre serveur.

Dans cet exemple, nous utilisons Nginx comme proxy inverse et Certbot pour gérer les certificats SSL. Ci-dessous, vous trouverez le docker-compose.yml, le script shell pour le rechargement automatique de Nginx et les fichiers de configuration nécessaires pour tout configurer.

Configuration de la composition Docker

Tout d'abord, laissez-moi vous montrer la configuration Docker Compose pour configurer Nginx et Certbot.


# docker-compose.yml

services:
  nginx:
    container_name: nginx
    image: nginx:latest
    restart: unless-stopped
    env_file: .env
    networks:
      - your-app-network # Update this with your application service network
    ports:
      - 80:80
      - 443:443
    depends_on:
      - your-app # Your application service
    volumes:
      - ./nginx/secure/:/etc/nginx/templates/
      - /etc/localtime:/etc/localtime:ro
      - ./nginx/certbot/conf:/etc/letsencrypt
      - ./nginx/certbot/www:/var/www/certbot
      - ./nginx/99-autoreload.sh:/docker-entrypoint.d/99-autoreload.sh  # Script to autoreload Nginx when certs are renewed

  certbot:
    image: certbot/certbot
    volumes:
      - ./nginx/certbot/conf:/etc/letsencrypt
      - ./nginx/certbot/www:/var/www/certbot
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"  # Renew certificates every 12 hours


Ce fichier Docker Compose définit deux services :

  • Nginx : agit comme un proxy inverse et envoie des requêtes à votre backend.
  • Certbot : S'occupe de générer et de renouveler les certificats SSL à l'aide de Let's Encrypt.

Le service certbot fonctionne en boucle infinie, renouvelant les certificats toutes les 12 heures. Les certificats sont stockés dans un volume partagé (./nginx/certbot/conf), permettant à Nginx d'accéder aux derniers fichiers de certificat.

Configuration Nginx

Nginx sert de proxy inverse, gérant à la fois le trafic HTTP et HTTPS. Pour la demande initiale, Certbot a besoin de HTTP (port 80) pour terminer le processus de vérification du domaine.


# default.conf.template

server {
    listen 80;
    server_name ${APP_DOMAIN};

    location / {
        return 301 https://$host$request_uri;
    }

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
}

server {
    listen 443 ssl;
    server_name ${APP_DOMAIN};
    server_tokens off;
    client_max_body_size 20M;

    ssl_certificate /etc/letsencrypt/live/${APP_DOMAIN}/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/${APP_DOMAIN}/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Url-Scheme $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://my-app:3000; // Your app service name
    }
}


Dans le fichier de configuration ci-dessus, Nginx fait ce qui suit :

  1. Redirige les requêtes HTTP vers HTTPS pour garantir une communication sécurisée.
  2. Gère la résiliation SSL et les demandes de proxy vers votre service backend (par exemple, my-app:3000).

Configuration Nginx à rechargement automatique

Une fois les certificats SSL renouvelés, Nginx doit être rechargé pour appliquer les certificats mis à jour. Pour automatiser ce processus, ajoutez un simple script de rechargement automatique :


# 99-autoreload.sh

#!/bin/sh
while :; do
    # Optional: Instead of sleep, detect config changes and only reload if necessary.
    sleep 6h
    nginx -t && nginx -s reload
done &


Ce script s'exécute dans le conteneur Nginx et recharge Nginx toutes les 6 heures, ou à chaque fois que le certificat est renouvelé.

Variables d'environnement

Créez un fichier .env pour stocker votre nom de domaine et votre adresse e-mail pour l'enregistrement Certbot :


# .env file

APP_DOMAIN=your-domain.com
SSL_EMAIL=contact@your-domain.com


Génération initiale du certificat SSL

Avant que Nginx puisse servir le trafic HTTPS, vous devez générer le certificat SSL initial. Utilisez le script bash suivant (init-letsencrypt.sh) pour générer le certificat SSL :


#!/bin/bash

# Source the .env file
if [ -f .env ]; then
  export $(grep -v '^#' .env | xargs)
fi

if ! [ -x "$(command -v docker compose)" ]; then
    echo 'Error: docker compose is not installed.' >&2
    exit 1
fi

domains=(${APP_DOMAIN:-example.com})
rsa_key_size=4096
data_path="./nginx/certbot"
email="${SSL_EMAIL:-hello@example.com}" # Adding a valid address is strongly recommended
staging=0 # Set to 1 if you're testing your setup to avoid hitting request limits

if [ -d "$data_path" ]; then
    read -p "Existing data found for $domains. Continue and replace existing certificate? (y/N) " decision
    if [ "$decision" != "Y" ] && [ "$decision" != "y" ]; then
        exit
    fi
fi

if [ ! -e "$data_path/conf/options-ssl-nginx.conf" ] || [ ! -e "$data_path/conf/ssl-dhparams.pem" ]; then
    echo "### Downloading recommended TLS parameters ..."
    mkdir -p "$data_path/conf"
    curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf >"$data_path/conf/options-ssl-nginx.conf"
    curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem >"$data_path/conf/ssl-dhparams.pem"
    echo
fi

echo "### Creating dummy certificate for $domains ..."
path="/etc/letsencrypt/live/$domains"
mkdir -p "$data_path/conf/live/$domains"
docker compose -f "docker-compose.yml" run --rm --entrypoint "\
  openssl req -x509 -nodes -newkey rsa:$rsa_key_size -days 1\
    -keyout '$path/privkey.pem' \
    -out '$path/fullchain.pem' \
    -subj '/CN=localhost'" certbot
echo

echo "### Starting nginx ..."
docker compose  -f "docker-compose.yml" up --force-recreate -d nginx
echo

echo "### Deleting dummy certificate for $domains ..."
docker compose  -f "docker-compose.yml" run --rm --entrypoint "\
  rm -Rf /etc/letsencrypt/live/$domains && \
  rm -Rf /etc/letsencrypt/archive/$domains && \
  rm -Rf /etc/letsencrypt/renewal/$domains.conf" certbot
echo

echo "### Requesting Let's Encrypt certificate for $domains ..."
#Join $domains to -d args
domain_args=""
for domain in "${domains[@]}"; do
    domain_args="$domain_args -d $domain"
done

# Select appropriate email arg
case "$email" in
"") email_arg="--register-unsafely-without-email" ;;
*) email_arg="--email $email" ;;
esac

# Enable staging mode if needed
if [ $staging != "0" ]; then staging_arg="--staging"; fi

docker compose -f "docker-compose.yml" run --rm --entrypoint "\
  certbot certonly --webroot -w /var/www/certbot \
    $staging_arg \
    $email_arg \
    $domain_args \
    --rsa-key-size $rsa_key_size \
    --agree-tos \
    --force-renewal" certbot
echo

#echo "### Reloading nginx ..."
docker compose -f "docker-compose.yml" exec nginx nginx -s reload



Résumé

En résumé, la configuration fournie ci-dessus configure Nginx comme proxy inverse pour votre application Dockerisée, avec les certificats SSL Let's Encrypt automatiquement gérés par Certbot. Cette configuration garantit une connexion sécurisée à votre application sans le casse-tête des renouvellements SSL manuels.

Notes finales

Pour afficher votre environnement la première fois, utilisez :


chmod a+x init-letsencrypt.sh
./init-letsencrypt.sh


Les fois suivantes, vous pouvez afficher votre environnement avec la commande docker compose habituelle :


docker-compose up -d


Assurez-vous que votre domaine pointe vers votre serveur et que les ports 80 et 443 sont ouverts pour permettre l'accès au trafic HTTP et HTTPS.

Si vous rencontrez des problèmes ou avez des suggestions d'améliorations, faites-le-moi savoir dans les commentaires ci-dessous ! Je me ferai un plaisir de vous aider à résoudre des problèmes ou à développer des sujets spécifiques.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn