Let’s Encryptの証明書は有効期間が90日と短く、手動更新を続けると更新漏れによるサイトダウンのリスクがあります。certbotとsystemd timer(またはcron)を組み合わせれば、更新処理を完全に自動化でき、運用負荷をほぼゼロにできます。

さらに、2028年にはデフォルトの有効期間が45日へ短縮される計画が公式発表されており、自動更新の仕組みは今後ますます重要になります。

Let’s Encryptの証明書が90日間の理由

Let’s Encryptが有効期間を90日に設定しているのは、セキュリティ上の理由です。有効期間が短ければ、万が一秘密鍵が漏えいしても被害の影響範囲を限定できます。

商用のSSL証明書(DV/OV/EV)は1年〜2年の有効期間が一般的ですが、Let’s Encryptは「自動更新を前提とした短期証明書」というポリシーを採用しています。

Let’s Encryptの主な仕様:

項目内容
有効期間90日間(2026年2月時点のデフォルト)
推奨更新タイミング有効期限の30日前(残り1/3の時点)
費用無料
認証方式DV(ドメイン認証)のみ
ルート証明書ISRG Root X1(2030年まで有効)
プロトコルACMEv2(RFC 8555)
世界シェア約63.7%(出典: W3Techs

Let’s Encryptは2025年9月末に1日あたりの証明書発行数が1,000万件を突破し、SSL証明書市場で最大のシェアを持つ認証局です(出典: Let’s Encrypt公式ブログ)。

certbotのインストール手順(OS別)

Let’s Encrypt証明書の取得・更新にはACMEクライアントが必要です。公式が推奨するACMEクライアントはcertbotで、snap経由のインストールが最も推奨されています(出典: Certbot公式ドキュメント)。

Ubuntu / Debian

# snapdの確認とcertbotインストール
sudo snap install core && sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

AlmaLinux / Rocky Linux / CentOS Stream

# EPELからsnapdをインストール
sudo dnf install epel-release
sudo dnf install snapd
sudo systemctl enable --now snapd.socket
sudo ln -s /var/lib/snapd/snap /snap

# certbotインストール
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

旧バージョンのcertbotが入っている場合

パッケージマネージャー経由で古いcertbotが入っていると競合するため、先に削除します。

# Ubuntu/Debian
sudo apt remove certbot

# RHEL系
sudo dnf remove certbot

pip経由のインストール(非推奨だが必要な場合)

snapが使えない環境では、Python仮想環境内にpipでインストールできます。

sudo python3 -m venv /opt/certbot/
sudo /opt/certbot/bin/pip install --upgrade pip
sudo /opt/certbot/bin/pip install certbot certbot-nginx
sudo ln -s /opt/certbot/bin/certbot /usr/bin/certbot

pip版はsystemd timerが自動設定されないため、cronまたはsystemd timerを手動で設定する必要があります。

SSL証明書の初回取得

certbotインストール後、SSL証明書を取得します。使用しているWebサーバーに合わせてコマンドを選択してください。

Nginx環境

sudo certbot --nginx -d example.com -d www.example.com

certbotがNginxの設定ファイルを自動で書き換え、HTTPS化まで完了します。

Apache環境

sudo certbot --apache -d example.com -d www.example.com

Webサーバーを停止せずに取得(webroot方式)

既存のWebサーバーを停止したくない場合は、webroot方式を使用します。

sudo certbot certonly --webroot -w /var/www/html -d example.com

この方式では、certbotが/.well-known/acme-challenge/配下に認証用トークンを生成します。Let’s EncryptのサーバーがそのトークンへHTTPリクエストを送り、レスポンスの内容でドメインの管理権を確認する仕組みです。

DNS認証方式(ワイルドカード証明書)

*.example.comのようなワイルドカード証明書が必要な場合は、DNS-01チャレンジを使用します。

sudo certbot certonly --manual --preferred-challenges dns -d "*.example.com" -d example.com

指定されたTXTレコードをDNSに追加する必要があるため、手動更新向きです。DNS APIプラグインを使えば自動化も可能です。

# Route 53プラグインの場合
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-route53
sudo certbot certonly --dns-route53 -d "*.example.com" -d example.com

自動更新の設定方法

snap版certbotの場合(自動設定済み)

snap経由でcertbotをインストールした場合、systemd timerが自動的に設定されるため追加の設定は不要です。

確認方法:

# timerの動作状況を確認
sudo systemctl status snap.certbot.renew.timer

# 次回の実行予定を確認
sudo systemctl list-timers snap.certbot.renew.timer

snap版certbotのsystemd timerは以下のように動作します。

  • インストール時にランダムに決定された1日2回の固定時刻で実行される
  • 時刻はインストールごとに異なり、Let’s Encryptサーバーへの負荷が自然に分散される
  • Persistent=trueが設定されているため、サーバー停止中にスケジュールを逃しても起動時に自動実行される

cronで自動更新を設定する場合

pip版やパッケージマネージャー版のcertbotを使っている場合は、手動でcronを設定します。

sudo crontab -e

以下の行を追加します。

0 3 * * * /usr/bin/certbot renew --quiet --deploy-hook "systemctl reload nginx"

各オプションの意味:

オプション役割
--quietエラー時以外の出力を抑制する
--deploy-hook証明書が実際に更新された場合のみ指定コマンドを実行する

--deploy-hookはcertbotが証明書の更新に成功した場合だけ実行されます。有効期限まで30日以上ある場合はcertbot renew自体がスキップされるため、Webサーバーの不要な再起動は発生しません。

Apache環境の場合:

0 3 * * * /usr/bin/certbot renew --quiet --deploy-hook "systemctl reload httpd"

systemd timerを手動で設定する場合

snap版を使わずにsystemd timerを設定したい場合は、serviceファイルとtimerファイルの2つを作成します。

/etc/systemd/system/certbot-renew.service:

[Unit]
Description=Certbot Renewal

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet --deploy-hook "systemctl reload nginx"

/etc/systemd/system/certbot-renew.timer:

[Unit]
Description=Run certbot twice daily

[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=3600
Persistent=true

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now certbot-renew.timer

cronとsystemd timerの選び方

比較項目cronsystemd timer
多重起動の防止なし(同時実行のリスクあり)あり(1インスタンス保証)
停止中のスケジュール補完なしPersistent=trueで起動時に実行
ランダム遅延標準機能なしRandomizedDelaySecで設定可能
ログ管理独自実装が必要journalctl -u certbot-renewで確認可能
設定の簡便さ1行で完結2ファイル必要
BSD等への対応対応systemd必須のため非対応

systemdベースのLinuxサーバー(Ubuntu 16.04以降、CentOS 7以降、AlmaLinux等)ではsystemd timerが推奨です。証明書更新はサーバーの安定運用に直結するため、ログ管理や多重起動防止があるsystemd timerの方が運用上安全です。

設定後の動作確認

自動更新を設定したら、必ず--dry-runオプションで事前検証を行います。

sudo certbot renew --dry-run

このコマンドはLet’s Encryptのステージングサーバーに対して更新処理をシミュレーションします。実際の証明書は更新されないため、レート制限にも影響しません。

確認すべき出力:

Congratulations, all simulated renewals succeeded:
  /etc/letsencrypt/live/example.com/fullchain.pem (success)

successが表示されれば、自動更新は正常に動作します。

現在の証明書情報を確認する

sudo certbot certificates

有効期限、証明書パス、使用しているドメインの一覧が表示されます。

証明書の有効期限をOpenSSLで確認する

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

自動更新が失敗する主な原因と対処法

Let’s Encryptの自動更新が失敗するケースにはいくつかの共通パターンがあります。

ポート80がブロックされている

Let’s EncryptのHTTP-01チャレンジはポート80でトークンファイルへのアクセスを検証します。ファイアウォールやセキュリティグループでポート80を閉じていると更新が失敗します。

# iptablesで確認
sudo iptables -L -n | grep 80

# firewalldで確認(RHEL系)
sudo firewall-cmd --list-ports

海外からのアクセス制限にも注意が必要です。 Let’s Encryptは複数の地理的に分散した拠点から検証リクエストを送信します(Multi-Perspective Validation)。日本国内のIPのみに制限している場合、海外拠点からの検証が失敗するケースがあります。

Webサーバーの設定ミス

/.well-known/acme-challenge/へのアクセスがリダイレクトやBasic認証によってブロックされている場合があります。

Nginx設定の確認:

server {
    listen 80;
    server_name example.com;

    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

HTTPSへのリダイレクトよりも前に/.well-known/acme-challenge/のlocationブロックを配置する必要があります。

certbotのバージョンが古い

パッケージマネージャー経由でインストールしたcertbotはバージョンが古く、ACMEv2に対応していない場合があります。

certbot --version

最新バージョンは5.3.1(2026年2月時点)です。snap版であれば自動的にアップデートされます。

レート制限に達している

Let’s Encryptには発行レート制限があります。同一ドメインに対して1週間に50件までの証明書発行が上限です。テスト時はステージング環境(--dry-run)を使用してください。

DNS設定の変更

ドメインのDNSレコードを変更した際、Aレコードが旧サーバーのIPアドレスのままだと、Let’s Encryptの検証が旧サーバーに到達して失敗します。DNS変更後は、TTLの経過を待ってから更新を実行してください。

hookオプションで更新前後にスクリプトを実行する

certbotのrenewコマンドには、更新プロセスの各段階でカスタムスクリプトを実行するhookオプションが用意されています。

hookオプション実行タイミング
--pre-hook更新処理の開始前に実行
--post-hook更新処理の完了後に実行(成功・失敗問わず)
--deploy-hook証明書の更新が成功した場合のみ実行

設定ファイルへの永続化:

hookは/etc/letsencrypt/renewal/example.com.confに記述することで、certbot renew実行時に自動適用されます。

[renewalparams]
pre_hook = systemctl stop nginx
post_hook = systemctl start nginx
deploy_hook = /usr/local/bin/notify-slack.sh

hookの活用例:

  • Webサーバーを一時停止してstandalone方式で更新する
  • 更新完了をSlackやメールで通知する
  • 更新後にCDNの証明書キャッシュをパージする
  • ロードバランサーに新しい証明書を配布する

Windows Server(IIS)での自動更新

Windows環境ではcertbotのサポートが限定的なため、win-acmeというACMEクライアントが広く使われています。

win-acmeの導入手順

  1. win-acme公式サイトからZIPをダウンロード
  2. 展開してwacs.exeを管理者権限で実行
  3. 対話形式でIISサイトを選択し、証明書を取得

win-acmeはWindowsタスクスケジューラにタスクを自動登録するため、初回設定後は自動更新が有効になります。

# タスクの確認
Get-ScheduledTask | Where-Object {$_.TaskName -like "*acme*"}

証明書の短期化ロードマップ(45日・6日証明書)

Let’s Encryptは2025年12月に、証明書有効期間を段階的に短縮する計画を正式発表しました(出典: Let’s Encrypt公式ブログ)。

短縮化スケジュール

時期対象プロファイル有効期間影響範囲
2026年1月(実施済み)shortlived6日(160時間)オプトインのみ
2026年5月tlsserver45日オプトイン
2027年2月classic(デフォルト)64日全ユーザー
2028年2月classic(デフォルト)45日全ユーザー

6日証明書(shortlivedプロファイル)

2026年1月15日に一般提供が開始された6日証明書は、有効期間が160時間です。OCSPやCRLのURLを含まないため、失効チェックのオーバーヘッドが不要になるという利点があります(出典: Let’s Encrypt公式ブログ)。

Certbot 4.0以降であれば以下のように取得できます。

sudo certbot certonly --nginx --preferred-profile shortlived -d example.com

6日証明書を使用する場合、systemd timerやcronが確実に動作しているかの監視がより重要になります。

今すぐ準備すべきこと

  1. certbotをsnap版にアップグレードする - 自動更新とバージョン管理が確実
  2. certbot renew --dry-runの成功を確認する - 2027年2月に64日証明書がデフォルトになる前にテスト
  3. 更新失敗を検知する監視を設定する - 有効期間が短くなるほど更新失敗の影響が大きい

ACME Renewal Information(ARI)による更新タイミングの最適化

2025年6月にIETFで標準化されたARI(RFC 9773)は、ACMEプロトコルの拡張機能です(出典: IETF RFC 9773)。

従来のcertbotは「有効期限の残り1/3になったら更新」という固定ルールで動作していました。ARIでは、Let’s Encrypt側が各証明書に対して最適な更新タイミングを提案します。

ARIのメリット:

  • Let’s Encrypt側のサーバー負荷を分散して、更新処理の成功率が向上する
  • 秘密鍵の漏えい等が発覚した場合、Let’s Encryptが通常より早い更新タイミングを提案できる
  • Certbot 4.1以降で自動的にARIを利用する

複数ドメイン・複数サーバーでの運用

1台のサーバーで複数ドメインの証明書を管理する場合

certbot renew/etc/letsencrypt/renewal/配下の全証明書をまとめて処理するため、ドメインごとの個別設定は必要ありません。

# 管理中の証明書を一覧表示
sudo certbot certificates

複数サーバーで同一ドメインの証明書を使う場合

ロードバランサー配下に複数のWebサーバーがある構成では、証明書の更新をどのサーバーで実行するかを決める必要があります。

方法1: 代表サーバーで更新し、他サーバーへ配布する

deploy-hookでrsyncやscpを使い、更新された証明書を他サーバーにコピーします。

certbot renew --deploy-hook "/usr/local/bin/distribute-certs.sh"

方法2: DNS-01チャレンジで全サーバーが個別に更新する

DNS認証であればポート80へのアクセスが不要なため、各サーバーが独立して証明書を更新できます。DNS APIプラグインを使えば完全自動化が可能です。

よくある質問

自動更新は何日前に実行されますか?

Certbotは標準設定の場合、証明書の残り有効日数が30日を下回ったタイミングで更新処理を開始します(90日間の約1/3に相当)。Certbot 4.1以降はARIにより、Let’s Encrypt側から推奨される更新タイミングが動的に調整されます。

更新中にサイトがダウンしますか?

Nginx/Apacheプラグインやwebroot方式であれば、Webサーバーを停止せずに更新できるためダウンタイムは発生しません。standalone方式を使用する場合のみ、ポート80を一時的に占有するためWebサーバーの停止が必要です。

さくらのレンタルサーバーでは自動更新されますか?

さくらのレンタルサーバーの無料SSL(Let’s Encrypt)は、有効期間満了前にさくらインターネット側で自動更新が行われます。ユーザー側の操作は不要です(出典: さくらインターネット サポート)。

Certbotを使わずに自動更新はできますか?

Certbot以外にも複数のACMEクライアントが存在します。

クライアント言語特徴
certbotPython公式推奨、プラグインが豊富
legoGoシングルバイナリ、DNS APIプラグイン内蔵
acme.shShell依存関係なし、軽量
dehydratedShell最小限の実装
CaddyGoWebサーバーに証明書管理が統合済み

Caddy Webサーバーは設定ファイルにドメイン名を記述するだけでLet’s Encryptの証明書取得・更新が自動で行われるため、証明書管理の手間を最小化できます。

まとめ

Let’s Encryptの自動更新は、snap版certbotをインストールすれば最小限の手順で設定が完了します。snap版にはsystemd timerが組み込まれており、cronの設定やログ管理を手動で行う必要がありません。

設定後はcertbot renew --dry-runで動作確認を行い、ポート80の開放やWebサーバー設定に問題がないことを検証してください。

2028年にはデフォルトの証明書有効期間が45日に短縮されます。更新サイクルが現行の半分になるため、certbotのrenew処理が確実に動いているかを定期的に検証する運用体制が欠かせません。