TLS / 証明書の期限切れ
症状
'certificate has expired'、'SSL handshake failed'、クライアントが突然接続できなくなる (コード変更なし)。
1. どこで壊れているか: サーバー、クライアント、CA のどれか
期限切れになったのはサーバー証明書か、クライアント証明書か、チェーン内の CA か。症状は通常「昨日は動いていたが今日は動かない、コードは変更していない」である。
2. 有効期限を確認する
証明書の有効期限をサーバーから直接読み取る (データベースに依存しない迅速な方法)。
PostgreSQL
openssl s_client -connect host:5432 -starttls postgres </dev/null 2>/dev/null | openssl x509 -noout -datesMongoDB
openssl s_client -connect host:27017 </dev/null 2>/dev/null | openssl x509 -noout -enddateRedis
openssl s_client -connect host:6379 </dev/null 2>/dev/null | openssl x509 -noout -enddate3. 新しい証明書をインストールしてロードする
証明書を置き換え、ほとんどの場合は再起動せずにサービスをリロードする。
PostgreSQL
-- Renew ssl_cert_file/ssl_key_file, then:
SELECT pg_reload_conf();MySQL
ALTER INSTANCE RELOAD TLS;SQL Server
-- SQL Server Configuration Manager > Certificate; a service restart is requiredMongoDB
// Renew the net.tls.certificateKeyFile file (at the same path), then load it without a restart (5.0+):
db.adminCommand({rotateCertificates: 1})Redis
CONFIG SET tls-cert-file /path/new.crt
CONFIG SET tls-key-file /path/new.keyElasticsearch
# ES watches the certificate/key files (PEM, PKCS#12) defined under xpack.security.*.ssl and
# reloads them automatically when the file at the SAME path changes (no restart needed).
# If the path, file name or keystore password changes, a rolling restart is required.
# Note: POST _nodes/reload_secure_settings is only for reloadable keystore settings, not for TLS certificates.
# Verify: check the new expiry date with openssl s_client and look in the ES logs for
# an entry showing the certificate was reloaded.4. 検証する
上記の openssl コマンドで、新しい証明書で TLS ハンドシェイクが成功し、有効期限が延長されたことを確認する。クライアントでエンドツーエンドに接続する。
5. 恒久対策: 二度と起こさない
証明書の有効期限の 30 日前にアラートを設定する。自動更新 (ACME/Let's Encrypt、HashiCorp Vault、cert-manager) を使う。更新後のリロードを自動化する。