【Azure】Key VaultにSSLサーバ証明書をインポートして利用してApp Serviceで利用する(Azure CLI編):Tech TIPS
App ServiceによるWebサイト/APIに対して、Azure外で発行したSSLサーバ証明書を割り当てることもあるだろう。この際、App Serviceに直接インポートすると更新時の手間が増えてしまう。機密情報を安全に取り扱える「Azure Key Vault」をAzure CLIで操作することで、効率良く証明書を更新できるようにする。
対象:Azure Key Vault(キーコンテナー)、Azure App Service、Azure CLI
Azure App ServiceでWebサイトやAPIを構築する際、Azure外で発行されたSSLサーバ証明書を割り当てなければならない場合もあるだろう(つまりApp Serviceマネージド証明書は使えない状況)。
App Serviceには、拡張子「.pfx」の証明書を直接インポートして割り当てる機能がある。これを使えばAzure外で発行されたSSLサーバ証明書の割り当ても可能だ。しかし、この方法だと、証明書の更新のたびに、そのインポートとカスタムドメインへの割り当てという作業が強いられてしまう。もし負荷分散や耐障害性のために、同じWebサイトを複数リージョンに展開している場合、その手間はサイト数に比例して増えることになる。
そこで本Tech TIPでは、この更新の手間を省く証明書のインポート方法を紹介する。証明書の保存には、同じAzureの「Key Vault(キーコンテナー)」というサービスを利用する。Key Vaultには、証明書やシークレット(パスワードなどの秘密情報)を安全かつ効率良く扱うための機能が備わっている。
このKey Vaultを利用して、「.pfx」ファイルからの証明書のインポートや、App Serviceへのインポート、カスタムドメインへの割り当てといった一通りの手順を説明したい。
Azureのリソースの操作には「Azure CLI」を用いる。Azure PowerShellでの操作方法については、「【Azure】Key VaultにSSLサーバ証明書をインポートしてApp Serviceで利用する(PowerShell編)」を参照していただきたい。
Key Vault自体の作成については、Microsoft Learnの解説記事を参考にしていただきたい。またKey Vaultの種類のうち、HSM(ハードウェアによる保護)は対象外としている。
■執筆時の各種ツール/APIのバージョン
- Azure CLI: Ver. 2.76.0
Key VaultにSSLサーバ証明書をインポート(保存)する
ここからAzure CLIでAzureのリソースを操作していく。あらかじめコマンドプロンプトでAzureへのログイン(「az login」コマンド)とサブスクリプションの選択(「az account set -s」コマンド)をしておくこと。
ローカルにある「.pfx」ファイルからKey Vaultへ証明書をインポート(保存)するには、以下のように「az keyvault certificate import」コマンドを実行する。これはインポートのたびに実行する必要がある。
az keyvault certificate import --vault-name <Key Vault名> -f <「.pfx」ファイル名> --password <「.pfx」パスワード> -n <Key Vault内での証明書名>
※Microsoftのレファレンス: az keyvault certificate import
「-n(--name)」オプションで指定する<Key Vault証明書名>は、他の証明書と区別できる一意な名称を指定する。筆者は以下の例のように、「cert-<FQDNの「.」を「-」に差し替えた文字列>-<必要なら付ける接尾辞>」としている。
- cert-www-example-jp
- cert-wildcard-example-com (「*.example.com」というワイルドカード証明書の場合)
- cert-www-example-jp-private
管理しやすくするために、この名称に証明書の有効期限など日付を表す文字列を加えたくなるかもしれない(「.pfx」ファイル名ではそのようにしている人も多いのではないだろうか)。しかし、それは止めておいた方がよい。Key Vaultの場合、同じ名称を維持したまま、新しい証明書へ更新していくことで、App Serviceの設定を変えることなく自動的に証明書を更新できるからだ。
Key VaultからApp Serviceへ証明書をインポートすることを許可する
Key VaultからApp Serviceへ証明書をインポートするには、App ServiceにKey Vaultへのアクセス許可を明示的に与える必要がある。許可していないと、インポート時に以下のようなエラーが発生する。
Unable to verify Key Vault permissions.
You may need to grant Microsoft.Azure.WebSites service principal the Certificate:Get permission
アクセス許可を与えるには、Key Vaultの「アクセスポリシー」を設定する。それには、以下のように「az keyvault set-policy」コマンドを実行する。
az keyvault set-policy -n <Key Vault名> -g <Key Vaultリソースグループ名> --secret-permissions Get --certificate-permissions get --spn abfa0a7c-a6b6-4736-8310-5855508787cd
※Microsoftのレファレンス: az keyvault set-policy
「--certificate-permissions」オプションの後には、Key Vault内の証明書に対して許可したい操作を下表から選んで「,」(半角コンマ)で区切って列挙する。
パラメーターに指定する単語 | 許可される操作の内容 |
---|---|
All | Purge(消去)以外の全て |
Get | 取得 |
List | 一覧を取得 |
Set | 設定 |
Delete | 削除 |
Recover | 回復 |
Backup | バックアップ |
Restore | 復元 |
Purge | 消去 |
az keyvault set-policyコマンドの「--certificate-permissions」オプションに指定できる単語 複数の単語を指定する場合は、「,」(半角コンマ)で区切って列挙すること。 |
上記リストでは、「Get(取得)」のみを許可している。
また「--spn」オプションの後には、許可を与える先のリソースのサービスプリンシパルのオブジェクトIDを指定する。上記で指定している「abfa0a7c-a6b6-4736-8310-5855508787cd」は、App ServiceのサービスプリンシパルのオブジェクトIDだ。これは一意に決まっていて、通常は他のサブスクリプションでも共通である。
ただAzure Governmentなど別の環境ではサービスプリンシパル名が異なることもある。そのような場合は、以下のように「az ad sp list」コマンドを実行してみよう。
az ad sp list --filter "DisplayName eq 'Microsoft.Azure.WebSites' " --query "[].servicePrincipalNames"
※Microsoftのレファレンス: az ad sp list
表示されたサービスプリンシパル名の中に、GUID形式のオブジェクトIDが含まれているはずだ。
Key VaultからApp ServiceへSSLサーバ証明書をインポートする
Key Vaultに保存した証明書をApp Serviceで利用するには、まずそれをApp Serviceにインポートする必要がある。それには以下のように「az webapp config ssl import」コマンドを実行する。これは原則として、証明書ごとに1回だけ実行すればよい(更新された証明書を手動で即座にApp Serviceへ反映したいなら、再度実行する必要がある)。
az webapp config ssl import -n <App Service名> -g <App Serviceリソースグループ名> --key-vault <Key Vault名> --key-vault-certificate-name <Key Vault内での証明書名> --certificate-name <App Service内での証明書名>
※Microsoftのレファレンス: az webapp config ssl import
「-g」オプションで指定するのは、App Serviceの方のリソースグループであり、Key Vaultの方ではないので気を付けよう。また、App Serviceにインポートされた証明書のリソースは、ここで指定したリソースグループ内に作られる。
リソースの名称についてはKey VaultとApp Service双方を指定しなければいけないので、オプションを混同しないように注意すること。証明書名についても同様に注意したい。
<App Service内での証明書名>については、筆者の場合、どのApp Serviceにひも付けているか一目で分かるように「<Key Vault内での証明書名>-<App Service名>」と命名している。
App ServiceのカスタムドメインにSSLサーバ証明書を割り当てる
最後に、上記の手順でインポートしたSSLサーバ証明書を、App Serviceのカスタムドメインに割り当てる(ひも付ける)。それには以下のように「az webapp config ssl bind」コマンドを実行する。
az webapp config ssl bind -n <App Service名> -g <App Serviceリソースグループ名> --certificate-thumbprint <母印> --hostname <FQDN> --ssl-type SNI
※Microsoftのレファレンス: az webapp config ssl bind
「--ssl-type」オプションでは、「SNI」「IP」のいずれかを指定する。通常は前者を指定して、一般的なSNI(Server Name Indication: 1つのIPアドレスで複数のドメインを運用するための仕組み)を適用する。IPアドレスとSSLサーバ証明書を1対1で割り当てるなら後者を選択する(ただし有料)。
<母印>と<FQDN>は、以下のように「az webapp config ssl show」コマンドで表示できる。
az webapp config ssl show --certificate-name <App Service内での証明書名> -g <証明書のリソースグループ名> --query "[subjectName,thumbprint]"
FQDNは証明書のSubjectNameから推定できる。
※Microsoftのレファレンス: az webapp config ssl show
Key Vaultとひも付けたApp ServiceのSSLサーバ証明書を更新する
上記の手順で設定したSSLサーバ証明書の有効期限が間近となり、その更新版を「.pfx」ファイルで入手したら、Key Vaultの同じ証明書名に対して前述の「az keyvault certificate import」コマンドでインポートを実行する。これにより、更新版が最新バージョンとしてKey Vaultに追加されるとともに、デフォルトでその更新版が他のサービスへ提供されるようになる。
そのまま放置していると、以前にKey Vaultからインポートされた(ひも付けられた)App Service内の証明書は、24時間以内に自動で最新バージョン(更新版)に差し替わる。
すぐに最新バージョンへ差し替えたい場合は、証明書名などを変えることなく前述の「az webapp config ssl import」コマンドを実行するとよい。即座にKey VaultとApp Serviceの間で証明書の同期が取られて、最新バージョンに差し替わる。
Key VaultからApp Serviceへの証明書のインポートに失敗する場合は?
「az webapp config ssl import」コマンドでKey VaultからApp ServiceへSSLサーバ証明書をインポートするのに失敗することがある。その症状は以下の通りだ。
- 「az webapp config ssl import」コマンドの実行時にエラーは表示されず、一見するとインポートに成功したように見える
- 「az webapp config ssl bind」コマンドでApp ServiceのカスタムドメインにSSLサーバ証明書を割り当てようとすると、「Certificate <母印> was not found.」というエラーが生じる
- Azureポータルで対象のApp Serviceのページを開き、[設定]−[証明書]−[Bring Your Own Certificate(.pfx)]タブを選ぶと表示される証明書の一覧に、インポートしたはずの証明書が見つからない
- 「az webapp config ssl list」コマンドを実行すると、インポートした証明書の内容が表示される。ただし、その証明書の[keyVaultSecretStatus]プロパティが「Initialized」のままで「Succeeded」にならない
筆者が試した限りでは、このトラブルが発生した時、インポートした証明書をいったん「az webapp config ssl remove」コマンドで削除してから、PowerShellの「Import-AzWebAppKeyVaultCertificate」コマンドレットでインポートし直したら、その後のSSLサーバ証明書の割り当てにはひとまず成功した。「Import-AzWebAppKeyVaultCertificate」コマンドレットの使い方などについては、Tech TIPS「【Azure】Key VaultにSSLサーバ証明書をインポートしてApp Serviceで利用する(PowerShell編)」を参照していただきたい。根本的な解決策が判明したら、本ページを更新するつもりだ。
■関連リンク
- Azure App Service で TLS/SSL 証明書を追加および管理する(Microsoft Learn)
- Key Vault アクセス ポリシーを割り当てる (レガシ)(Microsoft Learn)
- チュートリアル:Azure Key Vault に証明書をインポートする(Microsoft Learn)
- Azure Key Vault 証明書のインポートに関する FAQ(Microsoft Learn)
- クイック スタート:Azure CLI を使用して Azure Key Vault から証明書の設定と取得を行う(Microsoft Learn)
- Azure Key Vault の証明書について(Microsoft Learn)
- Key Vault 証明書の概要(Microsoft Learn)
- Azure Key Vault の証明書の更新(Microsoft Learn)
- CLI を使用してカスタム TLS/SSL 証明書を App Service アプリにバインドする(Microsoft Learn)
- 「az account」コマンドのレファレンス(Microsoft Learn)
- JMESPath クエリを使用して Azure CLI コマンドの出力に対してクエリを実行する方法(Microsoft Learn)
Copyright© Digital Advantage Corp. All Rights Reserved.