Let’s Encrypt Expiry Bot からの証明書期限切れメール
2 ヶ月ほど前に、Sakura VPS レンタルサーバーを Let’s Encrypt で SSL 対応していたら、こんなメールが来ました。
Your certificate (or certificates) for the names listed below will expire in 20 days (on 10 Apr 19 07:02 +0000). Please make sure to renew your certificate before then, or visitors to your website will encounter errors.
We recommend renewing certificates automatically when they have a third of their total lifetime left. For Let’s Encrypt’s current 90-day certificates, that means renewing 30 days before expiration. See https://letsencrypt.org/docs/integration-guide/ for details.
90 日ごとに証明書 (certificate) が期限切れになってしまうので更新しなきゃヤバイよってメールでした。 更新しないでいると、Web サイトに https でアクセスできなくなってしまいます。 見逃すところでした。
certbot コマンドによる証明書の更新
証明書の更新は、certbot
コマンドを使って簡単に実行できます。
まず、certbot
コマンドがインストールされていない場合はインストールします。
$ sudo yum install certbot
証明書を更新するには、下記のように certbot renew
を実行します。
証明書の有効期限まで 30 日以上残っている状態で更新する場合は、--force-renew
オプションを付けて実行する必要があります。
更新したら、Web サーバをリロードすれば完了です。
$ sudo certbot renew --force-renew
$ sudo systemctl reload nginx
トラブルシューティング: 404 Not Found が出る場合
certbot renew
コマンドを実行したときに、下記のようなエラーが出て失敗することがあります(下記の例では、Web サイトのドメイン名は example.com
に変えています)。
Attempting to renew cert (example.com) from /etc/letsencrypt/renewal/example.com.conf produced an unexpected error: Failed authorization procedure. example.com (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from https://example.com/.well-known/acme-challenge/Y1WeUoSwipdo5aZHsUNevZl_ppylAAWJh9bfSv1Xqu0 [225.100.100.100]: "<html>\r\n<head><title>404 Not Found</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>404 Not Found</h1></center>\r\n<hr><center>". Skipping.
...
All renewal attempts failed. The following certs could not be renewed:
/etc/letsencrypt/live/example.com/fullchain.pem (failure)
All renewal attempts failed. The following certs could not be renewed:
/etc/letsencrypt/live/example.com/fullchain.pem (failure)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1 renew failure(s), 0 parse failure(s)
このエラーが出る場合、多くの場合は nginx の Web サイトのドキュメントルートを /usr/share/nginx/html
から変更していることが原因のようです。
下記の設定ファイルの、webroot_map
のパスを、Web サイトの正しいドキュメントルートのディレクトリに変更します。
[[webroot_map]]
example.net = /usr/share/nginx/html
例えば、/home/maku/website
ディレクトリに設定しているなら、下記のように変更して保存します。
example.net = /home/maku/website
これで、certbot renew
コマンドの実行は成功するはずです。
cron で自動更新するように設定しておく
3 ヶ月おきに上記のコマンドを実行するのは面倒なので、cron で自動実行されるように設定しておきます。
設定ファイルは、/etc/crontab
をテンプレートにして、/etc/cron.d/lets_encrypt
を作成します。
$ sudo cp /etc/crontab /etc/cron.d/lets_encrypt
$ sudo vim /etc/cron.d/lets_encrypt
ファイルの中身は下記のようにして、毎週日曜日に、証明書の更新コマンドを実行するようにします。 実際には、証明書の有効期限が 30 日を切っている場合にのみ更新が行われます。
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
LANG=ja_JP.UTF-8
LC_ALL=ja_JP.UTF-8
CONTENT_TYPE=text/plain; charset=UTF-8
MAILTO="xxxxx@gmail.com"
# Let's Encrypt の証明書を更新(毎週日曜日2時30分)
30 2 * * sun root /usr/bin/certbot renew && /usr/bin/systemctl reload nginx
ここでは、MAILTO
を設定することで、cron のログをメールで送るように設定しています。
例えば、下記のようなメールが届くことになります(まだ証明書の期限は切れないから更新要求はスキップされたよ、というログですね)。
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not yet due for renewal
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The following certs are not due for renewal yet:
/etc/letsencrypt/live/example.com/fullchain.pem expires on 2019-06-19 (skipped)
No renewals were attempted.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ちなみに、cron の日時指定の方法は下記のようになっています(/etc/crontab
より抜粋)。
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
Sakura VPS レンタルサーバで Let’s Encrypt 設定した場合
Sakura のレンタルサーバの設定で Let’s Encrypt を自動設定した場合、下記のような cron 設定ファイルが自動的に生成されているかもしれません。 毎週木曜日の2時14分に証明書の更新をしようとしています。 こういったファイルが自動生成されているのであれば、それを使うのもよいでしょう。
14 2 * * 4 root /usr/local/certbot/certbot-auto renew --webroot -w /usr/share/nginx/html --post-hook 'systemctl reload nginx'
ただし、ここでも Web サイトのドキュメントルートとして /usr/share/nginx/html
が指定されているので、もしパスを変更しているのであれば、上記のファイルを修正しておく必要があります。
自分で作成した /etc/cron.d/lets_encrypt
があるのであれば、上記のファイルは処理が重複しているので削除しちゃいましょう。
関連記事
- Sakura VPS レンタルサーバーを Let's Encrypt で SSL 対応
- お名前.com の共用サーバーを Let's Encrypt で SSL 対応
- Nginx で 403 Forbidden エラーが出るときのチェック項目
- Nginx の設定: http でアクセスされた場合に https にリダイレクトする
- Nginx の設定: Nginx の設定ファイルの書き方が正しいか確認する (configtest, nginx -t)
- Nginx の設定: Nginx の設定ファイルの変更を反映する (nginx reload)
- Nginx の設定: Nginx でバーチャルホストを設定する(リバースプロキシ)