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の選び方
| 比較項目 | cron | systemd 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の導入手順
- win-acme公式サイトからZIPをダウンロード
- 展開してwacs.exeを管理者権限で実行
- 対話形式でIISサイトを選択し、証明書を取得
win-acmeはWindowsタスクスケジューラにタスクを自動登録するため、初回設定後は自動更新が有効になります。
# タスクの確認
Get-ScheduledTask | Where-Object {$_.TaskName -like "*acme*"}
証明書の短期化ロードマップ(45日・6日証明書)
Let’s Encryptは2025年12月に、証明書有効期間を段階的に短縮する計画を正式発表しました(出典: Let’s Encrypt公式ブログ)。
短縮化スケジュール
| 時期 | 対象プロファイル | 有効期間 | 影響範囲 |
|---|---|---|---|
| 2026年1月(実施済み) | shortlived | 6日(160時間) | オプトインのみ |
| 2026年5月 | tlsserver | 45日 | オプトイン |
| 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が確実に動作しているかの監視がより重要になります。
今すぐ準備すべきこと
- certbotをsnap版にアップグレードする - 自動更新とバージョン管理が確実
certbot renew --dry-runの成功を確認する - 2027年2月に64日証明書がデフォルトになる前にテスト- 更新失敗を検知する監視を設定する - 有効期間が短くなるほど更新失敗の影響が大きい
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クライアントが存在します。
| クライアント | 言語 | 特徴 |
|---|---|---|
| certbot | Python | 公式推奨、プラグインが豊富 |
| lego | Go | シングルバイナリ、DNS APIプラグイン内蔵 |
| acme.sh | Shell | 依存関係なし、軽量 |
| dehydrated | Shell | 最小限の実装 |
| Caddy | Go | Webサーバーに証明書管理が統合済み |
Caddy Webサーバーは設定ファイルにドメイン名を記述するだけでLet’s Encryptの証明書取得・更新が自動で行われるため、証明書管理の手間を最小化できます。
まとめ
Let’s Encryptの自動更新は、snap版certbotをインストールすれば最小限の手順で設定が完了します。snap版にはsystemd timerが組み込まれており、cronの設定やログ管理を手動で行う必要がありません。
設定後はcertbot renew --dry-runで動作確認を行い、ポート80の開放やWebサーバー設定に問題がないことを検証してください。
2028年にはデフォルトの証明書有効期間が45日に短縮されます。更新サイクルが現行の半分になるため、certbotのrenew処理が確実に動いているかを定期的に検証する運用体制が欠かせません。
