2026年5月29日

2026年5月29日

NginxのLet’s Encrypt証明書自動更新設定(Certbotのタイマー確認と更新失敗の対処)

Certbot で取得した Let's Encrypt の証明書は、インストール方法に応じて systemd タイマーや cron による自動更新があらかじめ組み込まれていることがほとんどです。大事なのは「自動更新が本当に動いているか」「更新後に Nginx が新しい証明書を読み込むか」の2点を確認しておくことです。この記事では、タイマーの確認、--dry-run による更新テスト、Nginx を再読み込みさせるデプロイフック、よくある更新失敗の原因と対処を順に説明します。

自動更新の仕組み

Let's Encrypt の証明書は有効期間が短く(従来は90日で、さらに短縮する方針が公表されています)、手作業で更新する前提では運用できません。Certbot は certbot renew を1日に複数回実行し、期限が近い証明書だけを更新します。期限に余裕がある証明書には何もしないので、頻繁に実行しても問題ありません。

この certbot renew を誰が定期実行するかは、インストール方法によって異なります。

  • snap 版(Certbot の公式手順で推奨されている方法):systemd タイマー snap.certbot.renew.timer が登録されます
  • Debian・Ubuntu の apt パッケージ版:certbot.timer が登録され、systemd のない環境向けに /etc/cron.d/certbot も用意されます
  • pip などで独自に入れた場合:自動更新は登録されないので、自分でタイマーか cron を設定する必要があります

1. タイマーが動いているか確認する

systemctl list-timers | grep -i certbot

次回の実行予定(NEXT)と前回の実行(LAST)が表示されれば、タイマーは有効です。何も表示されない場合は、cron 側を確認します。

ls /etc/cron.d/ | grep -i certbot
sudo crontab -l

どちらにもなければ自動更新は設定されていません。後述の方法で設定してください。逆に、過去に自分で cron を追加していてタイマーとも二重に動いている場合は、どちらか一方に整理しておくとログが読みやすくなります。

現在の証明書と有効期限の一覧は、次のコマンドで確認できます。

sudo certbot certificates

2. --dry-run で更新をテストする

実際の証明書には手を付けずに、更新処理が通るかを Let's Encrypt のステージング環境で試せます。

sudo certbot renew --dry-run

Congratulations, all simulated renewals succeeded のような成功メッセージが出れば、所有確認から証明書の取得までの流れは問題ありません。設定を変えたとき(ファイアウォール、リダイレクト、DNS、CDN の導入など)は、そのつど --dry-run を実行しておくと、期限直前に失敗に気づく事態を防げます。

失敗した場合の詳細は /var/log/letsencrypt/letsencrypt.log に記録されます。

3. 更新後に Nginx を再読み込みさせる

証明書ファイルが新しくなっても、Nginx は起動時や再読み込み時にしか証明書を読み込みません。更新後に再読み込みしないと、ディスク上は新しい証明書なのに古い証明書を配信し続け、期限切れのエラーが出ます。

certbot --nginx で取得した場合は、Nginx プラグインが更新後の再読み込みを行います。--webroot や --standalone で取得した場合は、デプロイフックを設定します。

sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh > /dev/null <<'EOF'
#!/bin/sh
nginx -t && systemctl reload nginx
EOF
sudo chmod 755 /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

renewal-hooks/deploy/ に置いた実行可能なスクリプトは、証明書が実際に更新されたときだけ実行されます。nginx -t を先に入れているのは、別の作業中の設定ミスで再読み込みが失敗し、サイトが止まるのを避けるためです。

各証明書がどの方式で取得・更新されるかは、/etc/letsencrypt/renewal/<ドメイン名>.conf の authenticator と installer の行で確認できます。

4. Nginx 側で確認しておく設定

Nginx の証明書の指定は、live ディレクトリのファイルを指すようにします。

ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

live 配下は最新の証明書へのシンボリックリンクなので、更新されても設定を書き換える必要がありません。archive 配下のファイルを直接指定していると、更新後も古い証明書を読み続けます。また、cert.pem ではなく中間証明書を含む fullchain.pem を指定しないと、一部の端末で証明書エラーになります。

webroot 方式の場合、所有確認のファイルが HTTP で取得できる必要があります。HTTPS へのリダイレクトや WordPress の書き換えルールに吸い込まれないよう、専用の location を用意しておくと安定します。

location ^~ /.well-known/acme-challenge/ {
    root /var/www/letsencrypt;
    default_type "text/plain";
}

よくある更新失敗と対処

--dry-run やログで失敗が出たときは、可能性の高い順に次を確認します。

  1. 80番ポートに届かない:ファイアウォール(ufw、firewalld、クラウドのセキュリティグループ)で 80 番を閉じていると、HTTP-01 の所有確認ができません。HTTPS のみで運用していても、更新のために 80 番は開けておきます。
  2. DNS の向き先が違う:特に AAAA レコードが古いサーバーを向いたまま残っていると、IPv6 での確認だけが失敗します。dig +short example.com AAAA で確認してください。
  3. standalone 方式で 80 番が使用中:Nginx が 80 番を使っているため、Certbot の一時サーバーが起動できません。webroot 方式か Nginx プラグインに切り替えるのが根本的な解決です。
  4. CDN やプロキシの設定:CDN 経由で確認用の URL がキャッシュされたり、別のサーバーに転送されたりしていないかを確認します。
  5. レート制限:失敗を繰り返すと、Let's Encrypt の利用制限に達することがあります。本番環境で何度も試す前に、--dry-run で原因を解消してください。
  6. CAA レコード:ドメインに CAA レコードを設定している場合、Let's Encrypt の発行が許可されているかを確認します。

期限の監視は別に用意する

Let's Encrypt は、有効期限が近いことを知らせるメールの送信を 2025 年に終了しています。自動更新が止まっていても通知は来ないため、外部の監視サービスや自前のスクリプトで、実際に配信されている証明書の期限を定期的に確認する仕組みを用意しておくと安心です。手元で確認するには次のコマンドが使えます。

echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -dates

notAfter が期限です。ディスク上の証明書ではなく、サーバーが今配信している証明書を見ている点が大事で、デプロイフックの設定漏れもこれで見つけられます。

この記事は Certbot と Let's Encrypt の現在の運用を前提にしています(2026年10月現在)。証明書の有効期間や更新タイミングの扱いは今後変わる可能性があるため、日付を計算して独自の cron を組むよりも、Certbot の renew に任せる構成をおすすめします。

まとめ

  • 自動更新はインストール方法に応じて systemd タイマーか cron で組み込まれる。systemctl list-timers で確認する
  • 設定を変えたら certbot renew --dry-run で更新が通るかを試す
  • webroot・standalone 方式では、デプロイフックで更新後に Nginx を再読み込みさせる
  • 証明書は live 配下の fullchain.pem と privkey.pem を指定する
  • 期限切れのメール通知は終了しているので、配信中の証明書の期限を外部から監視する

お気軽にご相談ください

お見積りへ お問い合わせへ
▲