Let's Encryptの証明書を自動更新してnginxに反映させる

先日、nginxで運営するWebサーバをHTTPS対応させました。

https://yuuchika.com/lets_encrypt_nginx/

この際に取得したLet's Encryptの証明書は、期限が90日と短くなっています。 手動で更新するようにしていると、いずれうっかり期限切れとなってしまいかねないので、自動化します。

環境は前回同様、次の通りです。

手動更新を試す

自動更新の設定をする前に、コマンドが正しく動作するか手動更新で試しておきたいと思います。

更新が上手くできたか確認しやすくするために、ひとまず更新前の証明書を確認しておきましょう。

下の画像は、Chromeのものですが、他のブラウザの場合も似たような手順で確認ができます。 アドレスバー付近にある南京錠のようなマークをクリックします。 (私の環境では、Chrome, firefoxはアドレスバー左側、InternetExplorerはアドレスバー右側にありました)

表示されるメニューから、証明書の表示を選びます。

更新できたか確認するためだけに、証明書の詳細を控えるの大変なので、期限くらいをメモって置けば手軽でよいでしょう。

取得方式をstandaloneからwebrootに変更する

先日は、certbotのstandaloneモードで証明書取得を行いました。 どうやらその場合は、更新処理もstandaloneモードでやらなくてはならないようです。

取得方法などの情報は、/etc/letsencrypt/renewal/example.com.conf の中に記録されているようです。 (これを手動で書き換えることはないので、開く必要はないです。興味のある方だけどうぞ)

standaloneモードで更新する場合は、その間Webサーバを止める必要があります。 すでに運用しているサーバを止めることはなるべく避けたいですよね。 そういう場合を想定して用意されているのがwebrootモードです。 webrootモードの場合、運用しているWebサーバ(今回はnginx)上で証明書更新を行うことができます。

webrootモードで更新するためには、nginxの設定が必要なのですが、前回すでにそれを埋め込んであります。

https://yuuchika.com/lets_encrypt_nginx/

webrootモードへの取得方式変更は以下のコマンドで可能です。 緑字の/path/to/doc/root/は、前回のHTTPS対応の際に/etc/nginx/conf.d/default.confに記載したものとなります。

[user@server certbot]$ /usr/local/certbot/certbot-auto certonly --webroot -w /path/to/doc/root/ -d example.com --agree-tos --force-renewal -n
Requesting to rerun /usr/local/certbot/certbot-auto with root privileges...
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for example.com
Using the webroot path /usr/share/nginx/certbot for all unmatched domains.
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.com/privkey.pem
   Your cert will expire on 2019-03-14. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot-auto
   again. To non-interactively renew *all* of your certificates, run
   "certbot-auto renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

これ以降は、/usr/local/certbot/certbot-auto renewのコマンドだけで証明書更新が行えるようになります。 (有効期限に余裕があるタイミングでこのコマンドを実行しても証明書更新がスキップされます。動作確認のために実行してみたい場合は --force-renewal を付与してください)

nginxに新しい証明書を反映

証明書を更新したあとはnginxに反映させる必要があります。

[user@server ~]$ sudo /bin/systemctl reload nginx

これで更新は完了です。

サイトの証明書を開いて、更新されているか(有効期限が、控えておいたものから発行したものに変わったか)確認をしましょう。

無事、有効期限が延長されていることが確認できました。

自動更新設定

取得方式変更を済ませてしまえば、証明書更新とnginxリロードの2コマンドだけなわけで、シェルスクリプトを書いたりする必要もなく、そのままcronに登録すれば自動化完了です。

crontabコマンドで以下を登録します。

[user@server ~]$ crontab
 0 4 1 * * /usr/local/certbot/certbot-auto renew && sudo /bin/systemctl reload nginx
 Ctrl+Dで抜ける

これで、毎月1日の午前4時に証明書更新が実行されます。