本日も乙

ただの自己満足な備忘録。

GCP HTTPS ロードバランサ用のセルフマネージド SSL 証明書の更新方法

本記事は Google Cloud Platform Advent Calendar 2020 の 12日目です。

GCP にはマネージドの SSL 証明書が HTTPS ロードバランサでサポートされています。

blog.jicoman.info

マネージドであれば SSL 証明書の管理や更新を GCP でやってくれるので大変便利ですが、要件によってはセルフマネージド(自分で SSL 証明書を購入して更新する)が必要になる場合があります。例えば以下の場合です。

  • 内部 HTTPS ロードバランサで SSL 証明書を使いたい場合
  • ワイルドカード SSL 証明書を使いたい場合
  • 組織認証(OV)、拡張認証(EV)証明書を使いたい場合

GCP でセルフマネージド SSL 証明書を更新するのが意外と手間だったのでその手順についてまとめました。今回はワイルドカード SSL 証明書を発行して、外部 HTTPS ロードバランサと内部 HTTPS ロードバランサに設定します。

SSL 証明書の発行

SSL 証明書を購入するところによって発行手順が異なるので省略します。今回は以下のファイル名を前提としてすすめます。

ファイル名 説明
wildcard.example.com.crt SSL 証明書
wildcard.example.com.key 秘密鍵
ca-bundle.ca 中間証明書

GCP は中間証明書の設定項目がないため、SSL 証明書と合わせて1つのファイルにします。これを certificate.pem とします。

$ awk 1 wildcard.example.com.crt ca-bundle.ca > certificate.pem

SSL 証明書の設定

外部 HTTPS ロードバランサの場合はブラウザ(マネジメントコンソール)からでも設定できますが、今回は gcloud コマンドで設定します。なお、内部 HTTPS ロードバランサはマネジメントコンソールに対応していないため gcloud コマンドからでしか設定できません。

外部 HTTPS ロードバランサ

$ gcloud compute ssl-certificates create wildcard-example-com-$(date "+%Y/%m/%d") \
    --certificate=certificate.pem \
    --private-key=wildcard.example.com.key \
    --project $PROJECT_ID \
    --global

Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/sslCertificates/wildcard-example-com-20200825].
NAME                           TYPE          CREATION_TIMESTAMP             EXPIRE_TIME                    MANAGED_STATUS
wildcard-example-com-20200825  SELF_MANAGED  2020-08-25T22:25:25.072-07:00  2021-09-03T07:59:59.000-07:00

# 確認コマンド
$ gcloud compute ssl-certificates list \
    --global \
    --project $PROJECT_ID

内部 HTTPS ロードバランサ

先ほどの外部 HTTPS ロードバランサのオプション(--global)が --region になっただけです。

# 例
$ gcloud compute ssl-certificates create internal-wildcard-example-com-$(date "+%Y/%m/%d") \
    --certificate=certificate.pem \
    --private-key=wildcard.example.com.key \
    --project $PROJECT_ID \
    --region=asia-northeast1

Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/regions/asia-northeast1/sslCertificates/internal-wildcard-example-com-20200825].
NAME                                    TYPE          CREATION_TIMESTAMP             EXPIRE_TIME                    MANAGED_STATUS
internal-wildcard-example-com-20200825  SELF_MANAGED  2020-08-25T22:29:28.649-07:00  2021-09-03T07:59:59.000-07:00

# 確認コマンド
$ gcloud compute ssl-certificates list \
   --filter="region:asia-northeast1" \
   --project $PROJECT_ID

SSL 証明書の切り替え

GCP における SSL 証明書の切り替えはロードバランサ一つずつに対して行います。マネジメントコンソールでできますが、ドキュメントには gcloud コマンドによる方法が載っていたので今回はその方法でやります。

外部 HTTPS ロードバランサ

Target Proxies を更新します。ダウンタイムを避けるために --ssl-certificates は新しい証明を最初にして、既存の証明書を後ろにします。この順番が重要です。

$ gcloud compute target-https-proxies update example-com-target-proxy \
    --global \
    --ssl-certificates=wildcard-example-com-20200825,wildcard-example-com-20190824 \
    --global-ssl-certificates \
    --project $PROJECT_ID

# 確認
$ gcloud beta compute target-https-proxies list --global --project $PROJECT_ID

このときに、SSL エラーが出ていないかを確認します。IP_ADDRESS は外部 HTTPS ロードバランサのグローバル IP アドレスです。

# 検証
$ echo | openssl s_client -showcerts -connect IP_ADDRESS:443 -verify 99 -verify_return_error

# 有効期限の確認
$ openssl s_client -connect IP_ADDRESS:443 < /dev/null 2> /dev/null | openssl x509 -text | grep Not

15分ほど待ったら古い方の SSL 証明書を削除すれば完了です。

$ gcloud compute target-https-proxies update example-com-target-proxy \
    --global \
    --ssl-certificates=wildcard-example-com-20200825 \
    --global-ssl-certificates \
    --project $PROJECT_ID

内部 HTTPS ロードバランサ

先ほどの外部 HTTPS ロードバランサのオプション(--global)が --region になっただけです。外部 HTTPS ロードバランサと異なり、マネジメントコンソールに表示されないため、gcloud コマンドで設定や確認をする必要があります。

$ gcloud compute target-https-proxies update example-com-target-proxy \
    --region asia-northeast1 \
    --ssl-certificates=internal-wildcard-example-com-20200825,internal-wildcard-example-com-20190824 \
    --global-ssl-certificates \
    --project $PROJECT_ID

# 確認
$ gcloud beta compute target-https-proxies list \
     --region asia-northeast1 --project $PROJECT_ID

このときに、SSL エラーが出ていないかを確認します。IP_ADDRESS は内部 HTTPS ロードバランサのプライベート IP アドレスです。

# 検証
$ echo | openssl s_client -showcerts -connect IP_ADDRESS:443 -verify 99 -verify_return_error

# 有効期限の確認
$ openssl s_client -connect IP_ADDRESS:443 < /dev/null 2> /dev/null | openssl x509 -text | grep Not

15分ほど待ったら古い方の SSL 証明書を削除すれば完了です。

$ gcloud compute target-https-proxies update example-com-target-proxy \
    --region asia-northeast1 \
    --ssl-certificates=internal-wildcard-example-com-20200825 \
    --global-ssl-certificates \
    --project $PROJECT_ID

参考 URL