DockerコンテナでCertbotを使ってHTTP-01 チャレンジする方法(無停止更新の準備)

この記事は約7分で読めます。

スポンサーリンク

はじめに

Dockerのコンテナにて、リバースプロキシを構築しましたが、次に
Let’s Encryptを利用し、外部・リバースプロキシ間をSSL化します。

Dockerで最小構成なリバースプロキシを作成した。《備忘録》
はじめに 本内容は、今後作成する構成のチュートリアルです。 私はDockerの初学者で、学習の一環で記しているため、不十分な内容の場合があります。 環境 ホスト:Ubuntu 24.04 構成 同一ネットワークでリバースプロキシ、Webのコ...

 

Let’s Encryptにて証明書の発行、更新できるように構築にはいくつかの方式があります。そのうち一番シンプルなのがStandalone方式と呼ばれる一時的に停止が発生してしまう方式です。これはCertbotが一時的に独自のWebサーバを立ち上げてACMEチャレンジを行う方法で、80、443ポートを使用してポート競合を起こすため停止が必要となります。

無停止で更新するチャレンジ方法は、HTTP-01、DNS-01チャレンジなどいくつかありますが、今回は一般的なHTTP-01チャレンジ(Webroot方式)を行います。

CertbotがACMEチャレンジ用のファイルをWebrootディレクトリに配置後、CertbotからのリクエストによりLet’s Encryptサーバがhttp://<YOUR_DOMAIN>/.well-known/acme-challenge/<TOKEN>を取得します。
この検証により、正当なレスポンスがあれば証明書の発行されます。

https://letsencrypt.org/ja/docs/challenge-types/

本記事の注意事項

エディタの都合上、以下文字列に続くパスを全角スラッシュにしてあります。
コピーして使用される際は半角スラッシュに変更してご使用ください。
/etc

スポンサーリンク

Certbotを使ってHTTP-01 チャレンジする

今回は、初回証明書発行のところまで記します。
構成は以下の画像の通りです。


簡略化していますが、docker-composeでreverse-proxy.ymlとwebapp01.ymlを作成し、それぞれコンテナを稼働させます。外部からの80/443リクエストはreverse-proxyで受け特定ドメインのリクエストのときにwebapp01のwebサービスに転送します。

SSLの範囲は、外部とreverse-proxy間のみです。
ボリュームにおいては、ACMEチャレンジディレクトリや証明書及びシンボリックリンク元ディレクトリをバインドマウントしています。

それでは、認証までの方法を順に記します。

Certbotのインストール

CertbotとはSSL証明書を取得するための機能をもつソフトで、
Let’sEncryptにも対応をしています。

今回は、Certbotを使用しますので、まずはCertbotのパッケージをインストールを行います。

sudo apt install certbot

今回は、Webrootを使用した証明書の取得・更新を行うためWebソフト(Apache、Nginx等)の追加プラグインは不要です。
例:sudo apt install python3-certbot-nginx

認証のためにdocker-compose.ymlへ記述

まず、ACMEチャレンジを行うためのディレクトリを作成します。

今回は/home/dockerをプロジェクトフォルダとして、
それぞれcomposeごとにディレクトリを作成します。

SSL化するのは、リバースプロキシサーバのためリバースプロキシを構成している
コンテナに記述していきます。

・/home/docker/reverse-proxy/docker-compose.yml

services:
 reverse-proxy:
  image: nginx:alpine
  ports:
   - "80:80"
  volumes:
   - ./conf.d:/etc/nginx/conf.d
   - ./certbot/www:/var/www/certbot
   - ./certbot/conf:/etc/letsencrypt
   - ./certbot/conf/archive:/etc/letsencrypt/archive

ネットワークや一部設定は省いていますが、上記の通りです。

volumesについては、バインドマウントしており、それぞれ
・ホストの/home/docker/reverse-proxy/conf.dをコンテナ内の/etc/nginx/conf.dに配置=>nginxの設定ファイルを読み込んでいます。

・ホストの/home/docker/reverse-proxy/certbot/wwwをコンテナ内で/var/www/certbotに配置=>ACMEディレクトリを配置します。

・ホストの/home/docker/reverse-proxy/certbot/confをコンテナ内の/etc/letsencryptに配置=>証明書のシンボリックリンクを配置しています。

・ホストの/certbot/conf/archiveをコンテナ内で/etc/letsencrypt/archiveに配置=>証明書が保管されます。

ACMEチャレンジ用のディレクトリを作成

次に、ACMEチャレンジ用のディレクトリを作成します。
/home/docker/reverse-proxy/certbot/www.well-known/acme-challenge/を作成します。

confファイルへパスの記述をする

既にある、もしくは新規作成するreverse-proxy(任意).confを/home/docker/reverse-proxy/conf.dに配置し以下を追記します。これによりexample/.well-known/acme-challengeのリクエストは、/var/www/certbotに関連付けることができます。

server {
 listen 80;
 server_name example(domain);
 location /.well-known/acme-challenge/ {
   root /var/www/certbot;
 }
 location / {
   省略....
 }
}

–dry-runオプションを使用して検証

証明書を発行、更新を行うコマンドは、Let’sEncryptにリクエストを行いますが、一定時間リクエストリミットがあります。

そのため、検証段階では、dry-runオプションを付与すると、証明書の発行や更新のシミュレーションを行うことができます。(リミットなし)

sudo certbot certonly --webroot -w /home/docker/reverse-proxy/certbot/www -d example(domain) --dry-run

証明書を発行する

以下は、Webroot方式で、証明書の発行のみ行うコマンドです。対象ドメインをexampleとしています。

Webrootディレクトリ指定は、/home/docker/reverse-proxy/certbot/www/です。
このときは、ホストのパスを指定します。ここで誤ると404エラーで取得できません。

検証で問題なければ、dry-runを外して証明書を発行します。

sudo certbot certonly --webroot -w /home/docker/reverse-proxy/certbot/www/ -d example(domain)

エラーが発報されず、指定した場所に証明書が発行されていれば成功です。

おわりに

私は、本工程を完了するのに時間がかかりました。
証明書発行のコマンドを実行すると404でエラーが発報され、原因の切り分けをしたわけですが、/.well-known/acme-challenge/にテストファイルを(.html)を入れると問題なく表示されたのにエラーは継続し、あまりcertbotの挙動を把握していなかったこともあり、autoindex on;default_type text/plain;、権限周りを重点的に探っていました。

結論、certbotのコマンドでコンテナ側のディレクトリを指定していたことが原因でした。
certbotはホストで実行するので、ホストのディレクトリを指定するんですね。

参考文献

関連記事

https://it.hasethblog.com/archives/286

さくらVPSで独自ドメインをSSL化と更新の自動化をした。docker-composeのリバースプロキシにて。
さくらVPS上で、DockerComposeにてリバースプロキシを立ち上げ、独自ドメインをSSL化および、自動更新されるように設定をしていきます。 本記事は、以下記事の摘要及び続きの自動化の部分を記します。 前回までの記事 ①独自ドメインの...

コメント

スポンサーリンク
スポンサーリンク
タイトルとURLをコピーしました