ご挨拶
皆様、証明書管理ちゃんとしてますか?
今回は、AWS Certificate Manager(ACM)で発行したワイルドカード証明書をエクスポートして、オンプレミスのnginxに設置した話です。
やりたかったこと
自前で管理しているサーバ(AlmaLinux 9.7 / nginx)で、ACMのワイルドカード証明書を使いたい。
Let's Encryptの自動更新で運用しているものの、ワイルドカード証明書で一元管理したいケースが出てきたためです。
前提知識:ACM証明書のエクスポートとは
ACMには2種類の証明書があります:
| 種別 | エクスポート可否 | 用途 |
|---|---|---|
| ACM発行(AWS管理) | 不可 | ELB、CloudFront、API Gateway等のAWSサービスにアタッチ |
| ACMインポート済み or エクスポート可能証明書 | 可 | 外部サーバへの配布が必要なケース |
ACMで「リクエスト」した通常の証明書はエクスポートできません。エクスポート可能な証明書として発行する必要があります。
今回の証明書情報
| 項目 | 値 |
|---|---|
| CN | *.lovelive-presents.com |
| Issuer | Amazon RSA 2048 M04 |
| 有効期限 | 2026-12-15 |
| エクスポート可能 | Yes |
手順
1. ACM証明書のエクスポート
AWS CLIを使用してエクスポートします。エクスポートにはパスフレーズが必要です。
aws acm export-certificate \
--certificate-arn "arn:aws:acm:us-east-1:<ACCOUNT_ID>:certificate/<CERT_ID>" \
--passphrase $(echo -n 'YOUR_PASSPHRASE' | base64) \
--region us-east-1
レスポンスとして以下が返ります:
-
Certificate: サーバ証明書(PEM) -
CertificateChain: 中間CA証明書チェーン(PEM) -
PrivateKey: 暗号化された秘密鍵(PEM、パスフレーズ付き)
2. 秘密鍵のパスフレーズ解除
nginxで使用するため、秘密鍵のパスフレーズを解除します。
openssl rsa -in encrypted_privkey.pem -out privkey.pem
パスフレーズ解除後の秘密鍵は厳重に管理してください。作業完了後、ローカルの一時ファイルは shred コマンドで安全に削除することを推奨します。
3. 証明書チェーンの結合
nginxでは ssl_certificate にサーバ証明書+中間CAを結合したfullchainを指定します。
cat certificate.pem certificate_chain.pem > fullchain.pem
4. nginxへの配置
# ディレクトリ作成
sudo mkdir -p /etc/nginx/ssl/acm/
# ファイル配置
sudo cp fullchain.pem /etc/nginx/ssl/acm/fullchain.pem
sudo cp privkey.pem /etc/nginx/ssl/acm/privkey.pem
# パーミッション設定
sudo chmod 644 /etc/nginx/ssl/acm/fullchain.pem
sudo chmod 600 /etc/nginx/ssl/acm/privkey.pem
sudo chown root:root /etc/nginx/ssl/acm/*
5. nginx設定の変更
対象のvhostのみACM証明書を参照するように切り替えます。
server {
listen 443 ssl;
server_name mail.lovelive-presents.com;
ssl_certificate /etc/nginx/ssl/acm/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/acm/privkey.pem;
# ... 他の設定
}
共用のLet's Encrypt証明書は温存しています。ワイルドカード証明書はapex(lovelive-presents.com)やmydns.jp系ドメインを保護できないため、共用LE証明書の置換は回避しました。これはOWASP A01(アクセス制御の不備)を考慮した判断です。
6. 設定確認と反映
# 設定テスト
sudo nginx -t
# リロード
sudo systemctl reload nginx
7. 検証
# 証明書のissuerを確認
echo | openssl s_client -connect mail.lovelive-presents.com:443 -servername mail.lovelive-presents.com 2>/dev/null | openssl x509 -noout -issuer
# => issuer=CN = Amazon RSA 2048 M04, ...
設計上のポイント
なぜ共用Let's Encrypt証明書を置換しなかったのか
ワイルドカード証明書(*.lovelive-presents.com)は以下をカバーできません:
- apexドメイン(
lovelive-presents.com) - 別ドメイン(
*.mydns.jp系)
既存のLet's Encrypt証明書を丸ごと置き換えてしまうと、上記ドメインでTLSエラーが発生します。
そのため、対象vhostのみACM証明書を参照する形にして、他のドメインへの影響を防いでいます。
セキュリティ上の考慮
- 秘密鍵のパスフレーズはログに記録していない
- ローカルの一時鍵ファイルは
shredで安全に削除 - 秘密鍵のパーミッションは
600(root:root) - 設定変更前のバックアップを取得(
.bak-YYYYMMDDHHMMSS)
運用上の注意点
ACMからエクスポートした証明書は、ACMの自動更新の恩恵を受けられません。有効期限前に手動でエクスポート→再配置が必要です。
| 項目 | 内容 |
|---|---|
| 今回の有効期限 | 2026-12-15 |
| 更新作業 | 有効期限前にACMから再エクスポート→nginx再配置 |
| 自動化案 | cronやSystems Managerで定期的にエクスポート→配布するパイプラインの構築を推奨 |
まとめ
ACM証明書のエクスポート機能を使えば、AWSサービス以外のサーバでもACM発行の証明書を利用できます。
ただし以下に注意してください:
- エクスポート可能な証明書として発行する必要がある
- 自動更新されないため、有効期限の管理が必要
- ワイルドカード証明書のカバー範囲を理解した上で、既存証明書との共存設計が重要
Let's Encryptの自動更新が便利な一方で、組織で統一した証明書管理をしたい場合にはACMエクスポートも選択肢の一つです。
では。