Docker手習中です。
Webサーバーの証明書をLet's Encryptで取得しようと調べてたら、今時はcertbotよりもlegoというツールが多機能で便利らしいと知り使ってみました。
certbotだとWebサーバーのルートディレクトリに.well-knownというフォルダを掘って認証ファイルを配置し、Let's Encrypt側からそれを参照することで認証を行います(http-01チャレンジ)。これをDocker環境でやろうとすると、Webサーバー(php-apache)コンテナとcertbotコンテナ間で同じフォルダをマウントする手間が生じますが、legoはDNSサーバーにレコードを作って認証するdns-01チャレンジ)にも対応しており連携が最低限で済みます(とはいえ書き出した証明書はサーバーコンテナにもってく必要はありますが)。
legoは多くのDNSサービスに対応しており、レコードの生成も含めてほぼ1行コマンドで証明書を取得してくれました。
当記事はCloudFlareのDNSサービスを利用した環境で実施したメモになります。
CloudFlareでAPIトークンを作成する
DNS設定は済んでるものとして、こちらからトークンを作成できます。
https://dash.cloudflare.com/profile/api-tokens
「トークンを作成する」ボタンから「カスタムトークンを作成する」の「始める」で開始。
適当な名前をつけ、「アクセス許可」の部分を以下のように設定します。
[ゾーン][ゾーン][読み取り]
[ゾーン][DNS][編集]
「ゾーンリソース」は操作を許可したいドメインを選択。今回は
[包含][すべてのゾーン]
としました。生成すると英数字の文字列が出てくるので紛失しないようコピーしてどこかに保存しておきます。
後ほどコマンドラインではCLOUDFLARE_DNS_API_TOKEN環境変数に入れた状態でDockerコマンドを叩きます。
フォルダ配置について
生成されたファイルが永続化されるよう、ホストのDockerファイルがあるフォルダにletsencryptフォルダを作成し、dockerコマンドの-vオプションでコンテナの/etc/letsencryptにマウントします。
-v ./letsencrypt:/etc/letsencrypt
生成実行
Dockerファイルがあるフォルダにcdして、
を実行。--accept-tosは利用許諾に「はい」してくれるオプションです。
認証に成功すると、letsencryptフォルダの下に.lego/certificatesフォルダが作成され、
- (ドメイン名).crt
- (ドメイン名).key
- (ドメイン名).issuer.crt
- (ドメイン名).json
の4つのファイルが保存されるはずです。crtとkeyファイルをWebサーバーのssl.confなどで指定すればOK。issuer.crtは中間CAの指定で必要かと思ったんですが使わなくても使えています。jsonは管理用のメタデータっぽいので直接使用しません。
更新
後日、時がきたら追記します。今回は初期認証まででつまづきまくって疲れたのでここまで。たぶん後ろの方のrunのかわりにrenewを使うとかだと思ってます。
docker-compose.ymlやDockerfileを駆使すれば自動更新もできるかもですが、まだちょっとこういうコマンド一発系のDockerコンテナをどう扱っていくのが良いのかもわかってないので保留。ホスト側で定期実行してくのか、とか。
自宅サーバーなので最悪90日毎に手動更新でもいいかなと日和かけてますw。