1 分で読了 #devops
このページの目次

証明書操作マニュアル

openssl

# リモートサーバーの証明書を表示
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -text -noout
# -servername: SNI を指定(同一 IP で複数の証明書がある場合に必須)
# </dev/null: 接続を即座に閉じる
# 出力に含まれるもの: Subject, Issuer, Validity, SAN, Public Key, Signature

# ローカルの証明書ファイルを表示
openssl x509 -text -noout -in cert.pem
openssl x509 -text -noout -in cert.pem | grep -E 'Not Before|Not After|DNS:'

# 証明書の期限切れをチェック
openssl x509 -checkend 86400 -noout -in cert.pem && echo "OK" || echo "EXPIRED"

# 秘密鍵の生成 (ECDSA P-256、現代的な推奨)
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out key.pem
# または RSA 2048(旧システムとの互換性用)
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out key.pem

# CSR(証明書署名要求)の生成、CA への提出用
openssl req -new -key key.pem -out csr.pem -subj "/CN=example.com"
# SAN 付きの CSR(現代的な必須要件、Chrome は CN を無視):
cat > san.cnf <<EOF
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
[req_distinguished_name]
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = example.com
DNS.2 = *.example.com
EOF
openssl req -new -key key.pem -out csr.pem -config san.cnf

# 自己署名証明書(テスト用、信頼されない)
openssl req -new -x509 -days 365 -key key.pem -out cert.pem -subj "/CN=localhost"

# 証明書チェーンの検証
openssl verify -CAfile ca-bundle.crt cert.pem

# 証明書フィンガープリントの表示(既知の証明書と照合用)
openssl x509 -fingerprint -sha256 -noout -in cert.pem

acme.sh

# DNS-01 による発行(アリババクラウド DNS)— ワイルドカード *.example.com も発行可能
export Ali_Key="xxx" Ali_Secret="yyy"
acme.sh --issue --dns dns_ali -d example.com -d '*.example.com'
# → ~/.acme.sh/example.com_ecc/ ディレクトリに証明書が生成される

# 証明書をターゲット場所にインストール + リロードフック
acme.sh --install-cert -d example.com \
  --cert-file /etc/caddy/certs/example.crt \
  --key-file /etc/caddy/certs/example.key \
  --fullchain-file /etc/caddy/certs/example-fullchain.crt \
  --reloadcmd "systemctl reload caddy"

# 手動での更新
acme.sh --renew -d example.com --force

# 自動更新(cron)
acme.sh --cron
# → すべての証明書を確認、有効期限の 30 日前に自動更新、更新成功 → reloadcmd を実行

# 発行済みの確認
acme.sh --list

certbot

# DNS-01 による発行(騰訊クラウド DNSPod)
certbot certonly --dns-tencentcloud \
  --dns-tencentcloud-credentials /etc/letsencrypt/tencentcloud.ini \
  --dns-tencentcloud-propagation-seconds 30 \
  -d example.com

# 更新(ドライラン)
certbot renew --dry-run

# 発行済みの確認
certbot certificates

トラブルシューティング

# 証明書の期限切れ
openssl x509 -text -noout -in cert.pem | grep "Not After"

# 証明書チェーンの不備(curl で SSL エラーが発生)
openssl verify -CAfile ca-bundle.crt cert.pem
# → 中間 CA が欠落 → fullchain.pem(cert + intermediates)が必要

# Let's Encrypt のレートリミット
# → 検証失敗制限: 1 時間あたりホスト名ごとにアカウントあたり 5 回まで失敗
# → --dry-run または staging 環境でテスト: --server https://acme-staging-v02.api.letsencrypt.org/directory

# acme.sh の自動更新が実行されていない
# → crontab を確認: crontab -l | grep acme.sh
# → または手動: acme.sh --cron --force