Let's Encrypt で webroot を利用した際、証明書の更新(renew)が上手くいかないケースに遭遇したのですが、ググっても日本語の情報が皆無でしたので、久しぶりの投稿です。
webroot を利用した証明書の発行
もはや何番煎じか分かりませんが、古い情報が錯綜している感じがするので、念の為書いておきます。
#-- certbot-auto最新版のインストール
$ cd /usr/bin/
$ wget https://dl.eff.org/certbot-auto
$ chmod 700 ./certbot-auto
#-- certbot-autoのバージョン(2019年4月1日時点:0.32.0)
#-- certbot-autoを動作させるのに必要なPython等がインストールされていなかった場合、
#-- このタイミングで自動的にインストールされるようになっています。
$ certbot-auto --version
#-- 証明書の発行
$ certbot-auto certonly \
--agree-tos \
--webroot \
-w /path/to/document/root \
-d example.com \
-d www.example.com \
-m info@example.com --no-eff-email
#-- 発行した証明書を削除して綺麗にしたい時は
# $ certbot-auto delete -d example.com
#-- .pemファイルができている事を確認
$ ll /etc/letsencrypt/live/example.com/
各ファイルの意味は…
- cert.pem:証明書
- chain.pem:中間証明書
- fullchain.pem:上記 1 と 2 とを連結したファイル
- privkey.pem:秘密鍵
です。
Apache の VirtualHost 設定
せっかくですので、こちらもついでに書いておきます。
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /path/to/document/root
#-- HTTPSへの自動リダイレクト(NE = No Escape)
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^.*$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
</VirtualHost>
<Virtualhost *:443>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /path/to/document/root
SSLEngine On
#-- Apache2.4.8以降は、fullchain.pemを指定すれば2行で書けます
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
</VirtualHost>
証明書が更新(renew)できるか試してみる(dry run)
Let's Encrypt の証明書の有効期間は 90 日(3 ヶ月) なので、cron を利用して自動更新させるのが楽です。
webroot を利用している場合、certbot-auto renew
とするだけの簡単作業…の筈なのですが…
#-- とりあえず dry run してみる
$ certbot-auto renew --dry-run
更新(renew)でエラーが発生した時の対処方法
dry run がすんなり通れば問題ないのですが、私の環境では、以下のようなエラーが発生する場合がありました。やっとこの記事の本題です。
※Google 等から検索してくる人のために、エラー文を長めにコピペしておきます。
Attempting to renew cert (example.com) from /etc/letsencrypt/renewal/example.com.conf produced an unexpected error: Missing command line flag or config entry for this setting:
Select the webroot for example.com:
Choices: ['Enter a new webroot', '/path/to/document/root']
(You can set this with the --webroot-path flag). Skipping.
All renewal attempts failed. The following certs could not be renewed:
あるいは
Attempting to renew cert (example.com) from /etc/letsencrypt/renewal/example.com.conf produced an unexpected error: Missing command line flag or config entry for this setting:
Input the webroot for example.com:. Skipping.
All renewal attempts failed. The following certs could not be renewed:
このエラーには再現性がなく、全く同じ環境なのにドメインによってエラーが出なかったり、同じドメインなのに delete してから再発行するとエラーが出るようになったり…といった状況でした。
エラー内容に従い、renew 時に読まれる設定ファイル /etc/letsencrypt/renewal/example.com.conf
の中身を確認してみると、エラーが発生する際はなぜか…
[[webroot_map]]
…と、[[webroot_map]]
エントリーが空になっていたり、あるいは…
[[webroot_map]]
example.com = /path/to/document/root
…と、「www付き」の方の設定が欠けていました。この場合…
[[webroot_map]]
example.com = /path/to/document/root
www.example.com = /path/to/document/root
…のように修正してやれば、正常に動作するようになります。
原因は不明
上記のような作業をしなくとも、[[webroot_map]]
エントリーが正しく記述される場合もあります。なぜ空になる事があるのか、原因は不明です。
もし原因をご存知の方がいらっしゃいましたら、コメントで教えて頂ければ幸いです。
証明書の自動更新を設定する
dry run が上手くいけば
certbot-auto renew --post-hook "Apache を再起動させるコマンド"
を cron で定期的に実行するよう設定してやれば OK です。