「証明書の期限が切れています」その時、現場は凍りつく。
こんにちは!「LINUX工房」管理人の「リナックス先生」です。
前回は、中間証明書のトラブルシューティングについて解説し、「繋がらない」問題を解決しました。
しかし、Webサーバー運用において、もっと恐ろしいトラブルがあります。
ある日突然、Webサイトにアクセスできなくなり、画面にデカデカと「この接続は安全ではありません(有効期限切れ)」と表示される事故です。
先生、それニュースで見たことあります!
有名なサービスでもたまにやらかしてますよね。
でも、Let’s Encryptなら自動更新されるし、有料の証明書ならメールが来るから忘れないんじゃないですか?
甘いわね、コウ君。
「自動更新プロセスがエラーで止まっていた」「担当者が辞めてメールアドレスが不通だった」「カレンダーに入れ忘れていた」…
現場では、そんな些細な理由でサイトが全停止するの。
今回は、人間の記憶力に頼らず、システムが自律的に期限を監視してアラートを鳴らす仕組みを作りましょう!
本記事では、OpenSSLコマンドを使って証明書の残り日数を計算するシェルスクリプトの作成から、Certbotの更新時にSlackへ通知を送るフック機能の実装、そしてApacheを停止させずに設定を反映する安全なリロード手法まで、プロの運用テクニックを網羅します。
🔒 Apache SSL/TLS 完全攻略講座(バックナンバー)
現在地:【第7回】運用を楽にする!証明書期限監視と更新プロセスの自動化
- 【第1回】Webサーバーの常時SSL化!TLSの仕組みと自己署名証明書の作成
- 【第2回】無料証明書のスタンダード!Let’s Encrypt (Certbot) の導入と自動更新
- 【第3回】企業サイトならこれ!有料証明書(JPRS/GlobalSign)のCSR生成とインストール
- 【第4回】セキュリティ強度を上げる!プロトコル(TLS1.3)と暗号スイートの最適化
- 【第5回】1つのIPで複数ドメイン!バーチャルホストでのSSL設定とSNIの仕組み
- 【第6回】「繋がらない」を解決!中間証明書チェーンとトラブルシューティング
- 【第7回】運用を楽にする!証明書期限監視と更新プロセスの自動化
- 【第8回】大規模構成!ロードバランサ連携とHTTP/2・HTTP/3 (QUIC) 対応
第1章:コマンドラインで「残り日数」を知る技術
まずは、Webブラウザを開かずに、サーバー内部からコマンドだけで「証明書の有効期限」を確認する方法をマスターしましょう。
これが自動化スクリプトの基礎になります。
1. ローカルファイルを確認する場合
サーバー内にある証明書ファイル(.crt / .pem)を直接チェックします。
openssl x509 -noout -enddate -in /etc/pki/tls/certs/server.crt
出力例:notAfter=Jan 15 12:00:00 2026 GMT
これで「いつ切れるか(notAfter)」の日付が分かります。
2. 稼働中のWebサーバーを確認する場合(推奨)
ファイルを見るよりも、実際にApacheが提示している証明書を確認する方が確実です。
(「ファイルを更新したのにApacheを再起動し忘れていて、古い証明書が使われていた」というミスを防げるため)
echo | openssl s_client -connect localhost:443 -servername www.example.com 2>/dev/null | openssl x509 -noout -enddate
このコマンドを使えば、外部のサーバーの期限もチェックできます。
第2章:【実践】期限監視&通知スクリプトの作成
毎回コマンドを打つのは面倒なので、「残り日数が30日を切ったらメール(またはSlack)で警告するスクリプト」を作成し、cronで毎日実行させましょう。
1. スクリプトの作成
/usr/local/bin/check_ssl_expiry.sh というファイルを作成します。
sudo nano /usr/local/bin/check_ssl_expiry.sh
スクリプトの内容(コピペOK):
#!/bin/bash
# 監視対象ドメイン
DOMAIN="www.example.com"
# 警告を開始する残り日数
WARNING_DAYS=30
# 通知先メールアドレス
EMAIL="admin@example.com"
# 期限日を取得(秒単位のUNIXタイムスタンプ)
END_DATE_STR=$(echo | openssl s_client -connect ${DOMAIN}:443 -servername ${DOMAIN} 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
END_DATE_EPOCH=$(date -d "${END_DATE_STR}" +%s)
# 現在日時を取得
NOW_EPOCH=$(date +%s)
# 残り秒数を計算
SECONDS_LEFT=$((END_DATE_EPOCH - NOW_EPOCH))
# 残り日数を計算
DAYS_LEFT=$((SECONDS_LEFT / 86400))
echo "Domain: ${DOMAIN}"
echo "Expires on: ${END_DATE_STR}"
echo "Days left: ${DAYS_LEFT}"
# 判定
if [ "${DAYS_LEFT}" -lt "${WARNING_DAYS}" ]; then
echo "WARNING: Certificate for ${DOMAIN} expires in ${DAYS_LEFT} days!" | mail -s "SSL Expiry Warning: ${DOMAIN}" ${EMAIL}
else
echo "Certificate is valid."
fi
2. 実行権限の付与とテスト
sudo chmod +x /usr/local/bin/check_ssl_expiry.sh # テスト実行 /usr/local/bin/check_ssl_expiry.sh
残り日数が表示されれば成功です。
テストのために WARNING_DAYS を大きめの数字(3650など)にして、メールが届くか確認してください。
3. cronへの登録
毎日朝9時にチェックするように設定します。
sudo crontab -e
0 9 * * * /usr/local/bin/check_ssl_expiry.sh
これで、有料証明書の更新忘れを未然に防ぐことができます。
第3章:Certbot (Let’s Encrypt) の更新フック活用術
Let’s Encryptを使っている場合、certbot renew が自動で更新してくれますが、「更新されたことに気づかない」というのも不安です。
また、更新後にApacheをリロードしないと、新しい証明書が反映されません。
Certbotには、更新処理のタイミングで特定のコマンドを実行する「フック(Hooks)」という機能があります。
主なフックの種類
- –pre-hook: 証明書更新の「直前」に実行(例:一時的に80番ポートを空けるためにApacheを止めるなど)。
- –post-hook: 証明書更新の「直後」に実行(例:Apacheを開始する)。
- –deploy-hook: 証明書の更新が「成功した時だけ」実行(例:Apacheのリロード、Slack通知)。
最もよく使うのは --deploy-hook です。
更新時にApacheをリロードさせる設定
/etc/letsencrypt/renewal-hooks/deploy/ ディレクトリにスクリプトを置くと、更新成功時に自動実行されます。
sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload_apache.sh
内容:
#!/bin/bash systemctl reload httpd echo "Apache reloaded for certificate renewal."
実行権限を与えます。
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload_apache.sh
これで、証明書が更新されるたびに勝手にApacheがリロードされ、常に最新の証明書が使われるようになります。
第4章:更新成功をSlackに通知する
「更新されたよ!」という通知がSlackに来れば、安心感は倍増します。
SlackのWebhook URLを取得している前提で、通知スクリプトを作成します。
Slack通知スクリプトの作成
sudo nano /etc/letsencrypt/renewal-hooks/deploy/notify_slack.sh
内容:
#!/bin/bash
# Slack Webhook URL (あなたのURLに書き換えてください)
WEBHOOK_URL="https://hooks.slack.com/services/XXXX/YYYY/ZZZZ"
# Certbotから渡される環境変数を利用
DOMAIN_LIST="${RENEWED_DOMAINS}"
LINEAGE="${RENEWED_LINEAGE}"
MESSAGE="Successfully renewed certificate for: ${DOMAIN_LIST}\nPath: ${LINEAGE}"
curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"${MESSAGE}\"}" ${WEBHOOK_URL}
実行権限を与えます。
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/notify_slack.sh
テスト実行(Dry Run)
スクリプトが動くかテストします。
sudo certbot renew --dry-run
--dry-run(リハーサル)では通常フックは実行されませんが、Certbotのバージョンによっては実行されるか、または手動でスクリプト単体を叩いてSlackに通知が来るか確認してください。
第5章:Apacheの「Graceful Restart」とは?
証明書を更新した後は、Apacheに設定を読み直させる必要があります。
この時、restart を使う人が多いですが、本番環境では reload (Graceful Restart) を使うべきです。
restart vs reload
| コマンド | 動作 | 影響 |
|---|---|---|
systemctl restart httpd |
プロセスを強制終了してから、再起動する。 | 処理中の通信(ダウンロードなど)が切断される。一瞬サイトに繋がらなくなる。 |
systemctl reload httpd(apachectl graceful) |
親プロセスだけが設定を読み直し、子プロセスは処理が終わってから入れ替わる。 | 処理中の通信は維持される。ユーザーへの影響はゼロ。 |
証明書の更新程度であれば、プロセスを殺す必要はありません。
自動化スクリプトの中では必ず reload を使いましょう。
⚠️ 注意:設定ファイルミスのリスク
自動で reload する際に、もし ssl.conf などに構文エラーがあると、リロードに失敗します(Apacheは古い設定のまま動き続けます)。
さらに悪いことに、restart をしてしまうと、エラーで起動できずにWebサーバーがダウンします。
自動化スクリプトには apachectl configtest のチェックを入れるのが安全です。
安全なリロードスクリプト例
#!/bin/bash
# 設定ファイルの構文チェック
if apachectl configtest; then
# OKならリロード
systemctl reload httpd
else
# NGならエラーを通知(Slackなど)
echo "Apache configtest failed! Renewal aborted." | mail -s "Apache Error" admin@example.com
fi
第6章:トラブルシューティング「自動更新が失敗していた!」
「自動化していたはずなのに、期限切れでサイトが落ちた!」
よくある原因と対策です。
Case 1: 80番ポートを閉じていた
原因: Let’s Encryptの更新にはHTTP(80)ポートが必要です。「HTTPS化したから80番はもうイラネ」とファイアウォールで閉じてしまうと、更新時の認証に失敗します。
対策: 常に80番は開放しておくか、--pre-hook で更新時だけ開けるスクリプトを組みます。
Case 2: Basic認証をかけていた
原因: 開発環境などでサイト全体にBasic認証をかけていると、Let’s Encryptのサーバーからのアクセスも弾かれてしまい、認証に失敗します。
対策: Apacheの設定で、.well-known/acme-challenge/ ディレクトリだけBasic認証を除外する設定を入れます。
<LocationMatch "^/.well-known/acme-challenge/">
Require all granted
Satisfy Any
</LocationMatch>
Case 3: ディスク容量がいっぱい
原因: ログファイルが溜まりすぎてディスクが満杯になり、新しい証明書ファイルが書き込めない。
対策: サーバー監視(ディスク容量監視)も別途行いましょう。
まとめ:人間は忘れる。システムに覚えさせよう。
お疲れ様でした!
これで、あなたのWebサーバーは「勝手に証明書を更新し、勝手にApacheに反映し、結果をSlackに報告してくれる」賢いサーバーになりました。
今回の重要ポイント:
opensslコマンドで期限を数値化し、スクリプトで監視する。- Certbotの
--deploy-hookを使えば、更新後の処理を自動化できる。 - Apacheの反映は
restartではなくreload(Graceful) で行う。 - 80番ポートやBasic認証など、更新を阻害する要因に注意する。
ここまでで、SSL/TLSの導入から運用までは完璧です。
しかし、Webサイトの規模が大きくなり、アクセスが増えてくると、1台のサーバーでは処理しきれなくなります。
そこで必要になるのが「ロードバランサ」と、最新の高速プロトコル「HTTP/2」「HTTP/3」です。
次回、いよいよ最終回。
「大規模構成!ロードバランサ連携とHTTP/2・HTTP/3 (QUIC) 対応」です。
SSL終端(SSL Offloading)の考え方や、Googleも推進する爆速プロトコル「HTTP/3」をApacheで有効化する最先端の技術を解説します。
最後まで走り抜けましょう!
▼ エンジニアとしてのキャリアを加速させる ▼
監視システムを作る
「VPS」で自分専用環境
サーバー知識を年収に
「ITエンジニア転職」

コメント