2026年5月24日
2026年5月24日
Let’s Encrypt の証明書を自動更新する設定と確認方法(certbot)
Let's Encrypt の証明書を certbot で取得した場合、自動更新の仕組みはインストール時にほぼ用意されています。やるべきことは、「更新を実行するタイマーが動いているか」「更新のテストが成功するか」「更新後にWebサーバーが新しい証明書を読み込むか」の3点を確認し、足りない部分を補うことです。この記事では、その確認手順と、更新が失敗する代表的な原因、期限を外から監視する方法を説明します。
自動更新の仕組み
certbot の更新は certbot renew というコマンドで行われます。このコマンドは、サーバーにあるすべての証明書を調べ、期限が近いもの(既定では残り30日を切ったもの)だけを更新します。期限に余裕がある証明書は何もせずに終了するため、1日に何度実行しても問題ありません。
この certbot renew を定期的に呼び出すのが、systemd のタイマーや cron です。どちらが使われるかは、certbot の入れ方によって変わります。
- snap で入れた場合(certbot の公式サイトが案内している方法):snap に含まれる systemd タイマーで実行されます
- OSのパッケージ(apt や dnf)で入れた場合:パッケージによって
certbot.timerや/etc/cron.d/certbotが用意されます。RHEL系ではタイマーを自分で有効化する必要がある場合もあります
なお Let's Encrypt の証明書の有効期間は現在90日ですが、今後さらに短くする計画が発表されています(2026年10月現在)。期間が短くなるほど、手作業ではなく自動更新が前提になります。
ステップ1:タイマーが動いているか確認する
# certbot に関係するタイマーを表示
systemctl list-timers | grep -i certbot
# cron で設定されている場合
ls /etc/cron.d/ | grep -i certbot
タイマーが表示されれば、次回の実行予定(NEXT)と前回の実行時刻(LAST)が分かります。何も表示されない場合は、certbot をどの方法で入れたかを確認してください。apt で入れた古い certbot と snap 版が混在していると、どちらが動いているのか分からなくなるため、片方に統一します。
タイマーも cron も見つからない場合は、root の crontab に1日2回程度の実行を登録します。決まった時刻に世界中から一斉に更新が集中しないよう、分の値は任意の数字にずらすのが望ましいとされています。
# sudo crontab -e で追加する例(毎日 3:17 と 15:17)
17 3,15 * * * certbot renew --quiet
ステップ2:更新のテストをする
# 取得済みの証明書と有効期限の一覧
sudo certbot certificates
# 実際には更新せず、テスト用の環境で更新手順を試す
sudo certbot renew --dry-run
--dry-run は Let's Encrypt のテスト環境(ステージング)に対して更新の手順をひととおり実行し、本物の証明書は書き換えません。ここで成功すれば、少なくとも認証の部分は自動更新でも通る見込みが高いと判断できます。失敗した場合は、出力されるエラーメッセージと /var/log/letsencrypt/letsencrypt.log を確認します。
ステップ3:更新後にWebサーバーへ反映させる
証明書のファイルが新しくなっても、Nginx や Apache が古い証明書をメモリに読み込んだままでは、ブラウザには古い証明書が届きます。「更新は成功しているのに期限切れになった」という事故の多くはこれが原因です。
証明書を取得したときの方法は、/etc/letsencrypt/renewal/ にあるドメインごとの設定ファイルに記録されています。
sudo cat /etc/letsencrypt/renewal/example.com.conf
authenticator や installer の値が nginx や apache なら、certbot のプラグインが更新後の再読み込みまで行います。一方 webroot や standalone で取得した場合は再読み込みが行われないため、デプロイフックを用意します。
# 更新に成功したときだけ実行されるスクリプトを置く
sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh > /dev/null <<'EOF'
#!/bin/sh
systemctl reload nginx
EOF
sudo chmod 755 /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
renewal-hooks/deploy/ に置いたスクリプトは、実際に証明書が更新されたときだけ実行されます。証明書をメールサーバーや別のサービスでも使っている場合は、そのサービスの再読み込みもここに書きます。なお、--dry-run のときにデプロイフックが実行されるかどうかは certbot のバージョンによって扱いが異なるため、フックの動作は本番の更新後にも確認してください。
更新が失敗する主な原因
失敗したときは、ログのエラーメッセージを見て、次の順に疑うと切り分けやすくなります。
1. 80番ポートに外から届かない
もっとも多い認証方式である HTTP-01 は、Let's Encrypt のサーバーが http://ドメイン/.well-known/acme-challenge/ に80番ポートでアクセスして確認します。初回取得のあとにファイアウォールやクラウドのセキュリティグループで80番を閉じた、という場合に更新だけが失敗します。HTTPSへのリダイレクト自体は問題ありませんが、80番は受け付けておく必要があります。
2. アクセス制限やWAFで認証用のパスが止められている
Basic認証、IPアドレス制限、国別のアクセス制限、WAFのルールが /.well-known/acme-challenge/ に掛かっていると認証に失敗します。Let's Encrypt は複数の地点から検証を行うため、特定の国からのアクセスを拒否していると失敗しやすくなります。認証用のパスだけ制限から除外する設定を検討してください。
3. standalone 方式でポートが使われている
standalone は certbot 自身が一時的にWebサーバーとして80番で待ち受ける方式なので、Nginx や Apache が動いていると更新できません。停止・起動をフックで行う方法もありますが、更新のたびにサイトが止まるため、webroot 方式や Webサーバーのプラグインに切り替えるほうが安定します。
4. DNSやドメインの設定が変わった
サーバーの移転でAレコードが別のサーバーを指している、IPv6のAAAAレコードが古いサーバーを指したまま、といった場合も認証に失敗します。Let's Encrypt はAAAAレコードがあればIPv6での接続を試みるため、IPv6側の設定も確認が必要です。
5. DNS-01 方式の認証情報が無効になった
ワイルドカード証明書で使う DNS-01 方式では、DNSサービスのAPIトークンを使ってTXTレコードを自動登録します。トークンの期限切れや権限変更で失敗することがあります。認証情報のファイルは chmod 600 にして root だけが読めるようにし、権限は必要なゾーンの編集だけに絞ります。
また、同じドメインで短時間に何度も発行・失敗を繰り返すと、Let's Encrypt の発行回数の制限に掛かります。原因が分かるまでは本番ではなく --dry-run で試すようにしてください。
期限を外から監視する
Let's Encrypt は、以前は期限が近づくとメールで知らせていましたが、この通知メールは2025年に終了しています。自動更新が止まっていても誰も気づかない、という状況を避けるため、期限を外から監視する仕組みを別に用意します。
# 配信中の証明書が14日以内に期限切れになるかを判定(14日 = 1209600秒)
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -checkend 1209600 \
&& echo "OK: 14日以上の余裕があります" \
|| echo "WARN: 14日以内に期限切れになります"
このコマンドを別のサーバーの cron で定期的に実行し、警告時にメールやチャットへ通知する、あるいは外部の監視サービスで証明書の期限チェックを有効にする方法があります。ファイルの日付ではなく「実際に配信されている証明書」を確認するのがポイントで、これによりWebサーバーの再読み込み漏れも検出できます。
まとめ
certbot renewは期限が近い証明書だけを更新するため、タイマーや cron で1日に数回実行して問題ありません- タイマーの有無を
systemctl list-timersで確かめ、certbot renew --dry-runで更新手順をテストします - webroot や standalone で取得した場合は、デプロイフックでWebサーバーの再読み込みを行います
- 更新失敗の多くは、80番ポートの閉鎖、アクセス制限、DNSの変更が原因です
- 期限通知メールは終了しているため、配信中の証明書の期限を外から監視します