誰も語らない Docker コンテナの SSL に関する課題

Mary-Kate Olsen
リリース: 2024-10-06 18:38:03
オリジナル
732 人が閲覧しました

The Challenge About SSL in Docker Containers No One Talks About

Docker 環境での SSL のセットアップに苦労したことがあるのは、あなただけではありません。 SSL は多くの人にとって恐ろしいハードルになる可能性がありますが、アプリケーションをセキュリティで保護することは、特にアプリケーションがインターネットに公開されている場合には非常に重要です。この投稿では、Dockerized セットアップで Let's Encrypt SSL 生成用に Nginx と Certbot を追加する方法を説明します。これにより、最小限の手間で証明書を自動的に更新し、環境を安全に保つことができます。

飛び込んでみましょう!

前提条件

  • Docker と Docker Compose がマシンにインストールされています。
  • Docker Compose と Nginx の基本的な理解。
  • サーバーを指すドメイン名。

この例では、リバース プロキシとして Nginx を使用し、SSL 証明書を管理するために Certbot を使用しています。以下に、docker-compose.yml、Nginx を自動リロードするためのシェル スクリプト、およびすべてをセットアップするために必要な構成ファイルがあります。

Docker Compose 構成

まず、Nginx と Certbot をセットアップするための Docker Compose 構成を示します。


# 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


ログイン後にコピー

この Docker Compose ファイルは 2 つのサービスを定義します:

  • Nginx: リバース プロキシとして機能し、バックエンドにリクエストを処理します。
  • Certbot: Let's Encrypt を使用して SSL 証明書の生成と更新を処理します。

certbot サービスは無限ループで実行され、12 時間ごとに証明書を更新します。証明書は共有ボリューム (./nginx/certbot/conf) に保存され、Nginx が最新の証明書ファイルにアクセスできるようになります。

Nginxの構成

Nginx はリバース プロキシとして機能し、HTTP トラフィックと HTTPS トラフィックの両方を処理します。最初のリクエストの場合、Certbot はドメイン検証プロセスを完了するために HTTP (ポート 80) を必要とします。


# 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
    }
}


ログイン後にコピー

上記の設定ファイルでは、Nginx は次のことを行います:

  1. 安全な通信を確保するために、HTTP リクエストを HTTPS にリダイレクトします。
  2. SSL 終了を処理し、バックエンド サービス (例: my-app:3000) へのリクエストをプロキシします。

Nginx 構成の自動再読み込み

SSL 証明書が更新された後、Nginx をリロードして、更新された証明書を適用する必要があります。このプロセスを自動化するには、単純な自動リロード スクリプトを追加します:


# 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 &


ログイン後にコピー

このスクリプトは Nginx コンテナ内で実行され、6 時間ごと、または証明書が更新されるたびに Nginx をリロードします。

環境変数

Certbot 登録用のドメイン名と電子メール アドレスを保存する .env ファイルを作成します。


# .env file

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


ログイン後にコピー

初期SSL証明書の生成

Nginx が HTTPS トラフィックを処理できるようにするには、最初の SSL 証明書を生成する必要があります。次の bash スクリプト (init-letsencrypt.sh) を使用して 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



ログイン後にコピー

まとめ

要約すると、上記の構成は、Certbot によって自動的に管理される Let's Encrypt SSL 証明書を使用して、Docker 化アプリケーションのリバース プロキシとして Nginx を設定します。この設定により、SSL を手動で更新する手間を省いて、アプリケーションへの安全な接続が確保されます。

最後のメモ

初めて環境を立ち上げるには、以下を使用します:


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


ログイン後にコピー

次の場合は、通常の docker compose コマンドを使用して環境を起動できます。


docker-compose up -d


ログイン後にコピー

ドメインがサーバーを指しており、HTTP および HTTPS トラフィックへのアクセスを許可するためにポート 80 と 443 が開いていることを確認してください。

問題が発生した場合、または改善のための提案がある場合は、以下のコメント欄でお知らせください。特定のトピックのトラブルシューティングや拡張を喜んでお手伝いいたします。

以上が誰も語らない Docker コンテナの SSL に関する課題の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!