MeWrite Docs

SSL certificate has expired

SSL証明書の有効期限が切れた場合に発生するエラー

概要

SSL certificate has expired は、WebサイトやAPIのSSL/TLS証明書の有効期限が切れた場合に発生するエラーです。証明書を更新するか、自動更新を設定する必要があります。

エラーメッセージ

curl: (60) SSL certificate problem: certificate has expired
SSL_ERROR_EXPIRED_CERT_ALERT
NET::ERR_CERT_DATE_INVALID
SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired

原因

  1. 証明書の期限切れ: 有効期限が過ぎている
  2. 自動更新の失敗: Let’s Encrypt の更新が失敗
  3. 中間証明書の期限切れ: チェーン証明書が期限切れ
  4. システム時刻のずれ: サーバーまたはクライアントの時刻が不正
  5. 証明書の設定ミス: 古い証明書が参照されている

重要: 2026年以降の証明書有効期限の変更

CA/Browser Forumの決定により、SSL/TLS証明書の有効期限が段階的に短縮されます:

時期最大有効期限DCV再利用期間
現在398日398日
2026年3月200日200日
2027年3月100日100日
2029年3月47日10日

対応策:

  • 証明書の自動更新を必ず設定する
  • 手動更新の場合は更新頻度を上げる
  • 証明書管理の自動化ツール導入を検討

解決策

1. 証明書の有効期限を確認

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# リモートサーバーの証明書を確認
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates

# 出力例
# notBefore=Jan  1 00:00:00 2024 GMT
# notAfter=Apr  1 00:00:00 2024 GMT

# 詳細情報
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -text -noout

# curl で確認
curl -vI https://example.com 2>&1 | grep -E "expire|subject|issuer"

2. Let’s Encrypt の更新

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# certbot で証明書を更新
sudo certbot renew

# 特定のドメインを更新
sudo certbot certonly --nginx -d example.com

# 強制更新
sudo certbot renew --force-renewal

# ドライラン(テスト)
sudo certbot renew --dry-run

# 証明書の状態を確認
sudo certbot certificates

3. 自動更新の設定

1
2
3
4
5
6
7
# cron で自動更新(2回/日が推奨)
sudo crontab -e
0 0,12 * * * /usr/bin/certbot renew --quiet

# systemd timer で自動更新
sudo systemctl status certbot.timer
sudo systemctl enable certbot.timer

4. Nginx で証明書を更新

1
2
3
4
5
6
7
8
# /etc/nginx/sites-available/example.com
server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
}
1
2
3
# 証明書更新後、Nginx を再読み込み
sudo nginx -t
sudo systemctl reload nginx

5. Apache で証明書を更新

1
2
3
4
5
6
7
8
9
# /etc/apache2/sites-available/example.com.conf
<VirtualHost *:443>
    ServerName example.com

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem
</VirtualHost>
1
2
3
# Apache を再読み込み
sudo apachectl configtest
sudo systemctl reload apache2

6. 中間証明書の確認

1
2
3
4
5
6
7
8
# 証明書チェーンを確認
openssl s_client -connect example.com:443 -showcerts

# チェーンの検証
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt fullchain.pem

# 中間証明書が含まれているか確認
openssl crl2pkcs7 -nocrl -certfile fullchain.pem | openssl pkcs7 -print_certs -noout

7. システム時刻の確認

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 現在時刻を確認
date
timedatectl

# NTP で時刻を同期
sudo timedatectl set-ntp true

# ntpd を使用
sudo ntpdate pool.ntp.org

# chrony を使用
sudo systemctl restart chronyd

8. AWS Certificate Manager (ACM)

1
2
3
4
5
6
7
8
# ACM の証明書を確認
aws acm list-certificates --region us-east-1

# 証明書の詳細
aws acm describe-certificate --certificate-arn arn:aws:acm:...

# ACM の証明書は自動更新される
# 更新が失敗した場合はメール通知を確認

9. 開発環境での対処

1
2
3
4
5
6
# curl で証明書検証をスキップ(開発用)
curl -k https://example.com

# Python で証明書検証をスキップ(開発用)
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
1
2
3
# requests で証明書検証をスキップ
import requests
response = requests.get('https://example.com', verify=False)
1
2
// Node.js で証明書検証をスキップ
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

10. Docker での証明書

1
2
3
4
5
# Dockerfile
FROM nginx:alpine

COPY fullchain.pem /etc/nginx/ssl/fullchain.pem
COPY privkey.pem /etc/nginx/ssl/privkey.pem
1
2
3
4
5
6
7
# docker-compose.yml
services:
  web:
    image: nginx
    volumes:
      - ./certs:/etc/nginx/ssl:ro
      - ./nginx.conf:/etc/nginx/nginx.conf:ro

証明書の更新手順

商用証明書の場合

  1. CSR(証明書署名要求)を生成
1
openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr
  1. 認証局に CSR を提出
  2. 発行された証明書をダウンロード
  3. サーバーに設置
  4. Web サーバーを再起動

自己署名証明書(開発用)

1
2
3
4
# 自己署名証明書を生成
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
    -keyout server.key -out server.crt \
    -subj "/CN=localhost"

デバッグのコツ

証明書の詳細確認

1
2
3
4
5
# ローカルファイル
openssl x509 -in cert.pem -text -noout

# リモートサーバー
openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -text -noout

オンラインツール

関連エラー

最終更新: 2025-12-08