インフラ・運用 2026.08.19

SSL証明書の期限切れを防ぐ!自動更新と監視の仕組み化

約12分で読めます

本番サーバーのSSL証明書をうっかり失効させてしまう前に。Let's Encryptの自動更新設定からSlack通知まで、期限切れゼロを実現する仕組みを実践的に解説します。

「サイトが突然、警告画面に…」その原因の多くはSSL証明書の期限切れ

こんな経験、ありませんか?

月曜の朝、出社直後にクライアントから「サイトが見られない、と問い合わせがきている」という連絡が入る。焦って確認すると、ブラウザには真っ赤な警告画面。原因を調べると、SSL証明書の有効期限が前日に切れていた——。

Fivenineのサポート窓口にも、こうした「証明書切れ」の緊急相談は後を絶ちません。SSL証明書が失効すると、サイト訪問者はセキュリティ警告を突き付けられ、ほとんどのユーザーはその時点で離脱します。ECサイトであれば売上への直撃、コーポレートサイトであれば信頼の毀損が避けられません。

問題は「うっかり忘れた」という人的ミスだけにあるのではなく、更新を人間の記憶や手作業に依存している構造そのものにあります。この記事では、Let's Encryptを使った自動更新の設定から、証明書の期限を定期的に監視してSlackへ通知する仕組みまで、運用を属人化させない手順を一通り解説します。


なぜ証明書の期限切れは「うっかり」起きるのか

証明書管理が後手に回る背景には、いくつかの構造的な理由があります。

まず、更新サイクルの問題です。 Let's Encryptは無料で使える反面、有効期限がわずか90日です。有料の証明書(1〜2年が一般的)と比べて更新頻度が高く、手動管理では対応しきれません。一方、有料証明書は期限が長い分「まだ大丈夫だろう」という油断を生み、気づいたら残り数日、という事態を招きます。

次に、担当者の入れ替わりです。 あるクライアントのケースでは、証明書を手動更新していた担当者が退職し、引継ぎ書にも記載がなかったために失効しました。更新手順が「特定の人の頭の中」にある状態は、そのまま組織のリスクになります。

さらに、監視が機能していない場合です。 サーバーを構築してそのまま、という環境では、証明書の残り期限をリアルタイムで把握する手段がありません。気づいたときには手遅れ、というのが典型的なパターンです。

flowchart TD
    A[SSL証明書を設置] --> B{手動管理?}
    B -->|Yes| C[担当者が期限をカレンダー管理]
    C --> D[担当者の異動・退職]
    D --> E[引き継ぎ漏れ]
    E --> F[期限切れ 🚨]
    B -->|No 自動化| G[certbot --renew を定期実行]
    G --> H[有効期限を自動チェック]
    H --> I{残り30日以内?}
    I -->|Yes| J[自動更新 → Slack通知]
    I -->|No| K[次回チェックまで待機]
    J --> L[証明書を更新完了 ✅]

サーバー・インフラでお困りですか?

障害対応・移行・パフォーマンスチューニングなど、ご相談ください

無料で相談する

仕組み化の全体像:3つのレイヤーで守る

証明書の失効リスクを排除するには、以下の3つのレイヤーで対策を重ねるのが最も堅牢です。

  1. 自動更新(certbot) — 更新作業そのものを自動化
  2. 期限監視スクリプト — 有効期限を定期的にチェックして通知
  3. 外部監視サービス — サーバー外部からSSLの状態を見張る
自動更新(certbot)の設定40%
期限監視スクリプトの設置35%
外部監視サービスの導入25%

レイヤー1:certbotによる自動更新

Let's Encryptの証明書は、certbotコマンドで取得・更新します。インストール済みの環境では、まず手動更新が正常に動くかを確認しましょう。

# ドライランで更新が成功するか確認(実際には更新しない)
sudo certbot renew --dry-run

問題がなければ、cronまたはsystemdタイマーで定期実行を登録します。Ubuntu/Debianであればcertbotのパッケージインストール時に自動でタイマーが設定されますが、念のため確認しておきましょう。

# crontabを開く
sudo crontab -e

# 毎日午前3時と午後3時に実行(証明書が30日を切っていれば更新される)
0 3,15 * * * certbot renew --quiet --deploy-hook "systemctl reload nginx"

--deploy-hook オプションが重要です。証明書の更新に成功したタイミングで自動的にNginxをリロードしないと、古い証明書をサーバーが掴み続けることがあります。更新されているのにブラウザでは警告が出る、という問題の大半はここが原因です。

レイヤー2:期限監視スクリプト+Slack通知

自動更新が動いていても、「本当に更新されているか」を確認する仕組みは別に持つべきです。以下は、証明書の残り日数をチェックしてSlackに通知するシェルスクリプトです。

#!/bin/bash
# /usr/local/bin/check-ssl-expiry.sh

DOMAIN="example.com"
WARN_DAYS=30
SLACK_WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"

# 証明書の有効期限を取得
EXPIRY=$(echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN:443" 2>/dev/null \
  | openssl x509 -noout -enddate 2>/dev/null \
  | sed 's/notAfter=//')

if [ -z "$EXPIRY" ]; then
  MESSAGE=":rotating_light: *[$DOMAIN]* SSL証明書の期限取得に失敗しました。サーバーを確認してください。"
  curl -s -X POST -H 'Content-type: application/json' \
    --data "{\"text\": \"$MESSAGE\"}" \
    "$SLACK_WEBHOOK_URL"
  exit 1
fi

# 残り日数を計算
EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s 2>/dev/null || date -j -f "%b %d %T %Y %Z" "$EXPIRY" +%s)
NOW_EPOCH=$(date +%s)
REMAIN_DAYS=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))

if [ "$REMAIN_DAYS" -le "$WARN_DAYS" ]; then
  MESSAGE=":warning: *[$DOMAIN]* SSL証明書の残り有効期限が *${REMAIN_DAYS}日* です。自動更新が機能しているか確認してください。"
  curl -s -X POST -H 'Content-type: application/json' \
    --data "{\"text\": \"$MESSAGE\"}" \
    "$SLACK_WEBHOOK_URL"
else
  echo "[OK] $DOMAIN: 残り${REMAIN_DAYS}日"
fi

このスクリプトをcronに登録して毎朝実行します。

# 毎朝9時にSSL期限チェック
0 9 * * * /usr/local/bin/check-ssl-expiry.sh >> /var/log/ssl-check.log 2>&1

残り30日を切るとSlackに警告が届くため、「気づかなかった」という状況が発生しません。あるクライアントの案件でこの仕組みを導入してから、担当者が「証明書のことを考えたのは通知が来た1回だけ」と話していました。それが理想の運用状態です。

レイヤー3:外部監視サービスで二重チェック

サーバー内部のスクリプトが何らかの理由で動かなかった場合に備え、外部から定期的にSSL状態をチェックするサービスも併用します。

サービス名無料プランチェック間隔Slack通知おすすめ度
UptimeRobot5分★★★
Checkly10分★★★
StatusCake30分★★☆
Site24x71分★★☆

無料プランで十分な場合がほとんどです。特にUptimeRobotはSSL証明書の期限監視に専用の機能があり、設定が直感的なため導入ハードルが低くお勧めです。


よくある失敗パターンと対処法

仕組みを整えても、落とし穴にはまるケースが繰り返し見られます。代表的なパターンを整理しておきます。

certbotは証明書ファイルを更新しますが、Nginxが新しいファイルを読み込むにはリロードが必要です。`--deploy-hook "systemctl reload nginx"` を必ずcronに付けてください。Apache環境なら `systemctl reload apache2` です。
ワイルドカード証明書はDNS-01チャレンジが必要なため、DNSプロバイダーのAPIキーが別途必要です。Route53やCloudflareならcertbotのプラグインが整備されていますが、設定が複雑なため初回は手順を丁寧に追いましょう。
管理しているドメインが10本以上になると、スクリプトのDOMAIN変数を1つひとつ書くのは現実的ではありません。ドメインリストをファイルで管理してループ処理に変更するか、監視サービスに一括登録する方法が現実的です。
certbotはデフォルトでメール通知を送りますが、メールが迷惑フォルダに入ったり、担当者が多忙で見逃したりすることがあります。Slack通知との組み合わせが最も見落としを防げます。

サーバー・インフラでお困りですか?

障害対応・移行・パフォーマンスチューニングなど、ご相談ください

無料で相談する

サーバー管理、丸ごとお任せください

サーバー保守・運用

監視・障害対応・パフォーマンス改善まで、安定稼働をサポートします

200件以上の制作実績 顧客満足度97% 初回相談無料

※ 通常1営業日以内にご返信します

まとめと次のステップ

SSL証明書の期限切れは、技術的な難易度は低いにもかかわらず、対応が遅れると信頼とビジネス機会を大きく損なうリスクがあります。個人の記憶や手作業に頼らず、仕組みとして自動化・監視することが根本的な解決策です。

「どの環境から始めればいいかわからない」「サーバーの構成が複雑で手を付けにくい」という場合は、まず現状の証明書の期限確認だけでも着手してみてください。下記のコマンド一つで現在の残り日数が分かります。

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

結果を見て「思ったより残り日数が少ない」と感じた方は、今すぐ設定を見直すタイミングです。

Fivenineでは、既存サーバーのSSL設定見直しから監視スクリプトの導入・テストまで、一括でご対応しています。「自社の環境に合った方法を知りたい」という段階からでも、お気軽にご相談ください。


この記事をシェア

サーバー・インフラの課題を解決します

構築・移行・監視・障害対応まで、安定した運用環境をご提供します。 初回相談は無料です。

※ 1営業日以内にご返信いたします

この技術でお困りなら

無料でプロに相談できます

相談する
AIに無料相談