App ServiceによるWebサイトやWeb APIにAzure外で発行したSSLサーバ証明書を割り当てる場合、App Serviceに直接インポートすると更新時に手間が掛かりやすい。機密情報を安全に取り扱える「Azure Key Vault」を使って、効率良く証明書を更新できるようにしよう。
対象:Azure Key Vault(キーコンテナ)、Azure App Service、Azure CLI
Azure App ServiceでWebサイトあるいはWeb APIを構築する際、Azure外で発行されたSSLサーバ証明書を割り当てなければならない場合もあるだろう(つまりApp Serviceマネージド証明書は使えない状況)。
App Serviceには.pfxの証明書を直接インポートして割り当てる機能があるため、これを使えばAzure外で発行されたSSLサーバ証明書の割り当ても可能だ。しかし、この方法だと、証明書の更新のたびにそのインポートとカスタムドメインへの割り当てという作業が強いられる。もし負荷分散や耐障害性のために、同じWebサイトを複数リージョンに展開している場合、その手間はサイト数に比例して増えてしまう恐れがある。
Azureの「Key Vault」と呼ばれる証明書やシークレット(パスワードなどの秘密情報)を安全かつ効率良く扱うための機能が用意されている。本Tech TIPSでは、SSLサーバ証明書を対象として、このKey Vaultに証明書をインポートする方法や、そこからApp Serviceにインポートして使えるようにする方法を説明する。
Key Vault自体の作成については、Microsoft Learnの解説記事を参考にしていただきたい。またKey Vaultの種類のうち、HSM(ハードウェアによる保護)は対象外としている。
ここから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証明書名>
「-n(--name)」オプションで指定する<Key Vault証明書名>は、他の証明書と区別できる一意な名称を指定する。筆者は以下の例のように、「cert-<FQDNの「.」を「-」に差し替えた文字列>-<必要なら付ける接尾辞>」としている。
管理しやすくするために、この名称に証明書の有効期限など日付を表す文字列を加えたくなるかもしれない(.pfxファイル名ではそのようにしている人も多いのではないだろうか)。しかし、それは止めておいた方がよい。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 Secret: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
「--certificate-permissions」オプションの後には、Key Vault内の証明書に対して許可する操作を表す単語を列挙する。上記の例では「get(取得)」を許可している。同様にシークレットについても「--secret-permissions」オプションで「get」を許可しておく。
また「--spn」オプションの後には、許可を与える先のリソースのサービスプリンシパル名を指定する。上記で指定している「abfa0a7c-a6b6-4736-8310-5855508787cd」は、App Serviceのサービスプリンシパル名だ。これは一意に決まっていて、通常は他のサブスクリプションでも共通である。
ただAzure Governmentなど別の環境ではサービスプリンシパル名が異なることもある。そのような場合は、以下のように「az ad sp list」コマンドを実行するとApp Serviceのサービスプリンシパル名を確認すればよい。
az ad sp list --filter "DisplayName eq 'Microsoft.Azure.WebSites' " --query "[].servicePrincipalNames"
Key Vaultに保存した証明書をApp Serviceで利用するには、まずそれをApp Serviceにインポートする必要がある。それには以下のように「az webapp config ssl import」コマンドを実行する。
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内での証明書名>
Key VaultとApp Service双方の名称を指定しなければいけないため、オプションを混同しないように注意すること。証明書名についても同様に注意したい。
<App Service内での証明書名>については、筆者の場合、どのApp Serviceにひも付けているか一目で分かるように「<Key Vault内での証明書名>-<App Service名>」と命名している。
最後に、上記の手順でインポートした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
「--ssl-type」オプションでは、「SNI」「IP」のいずれかを指定する。IPアドレスごとにSSLサーバ証明書を割り当てるなら後者、そうでなければ前者を選ぶこと(後者は有料である)。
<拇印>と<FQDN>は、以下のように「az webapp config ssl show」コマンドで表示できる。
az webapp config ssl show --certificate-name <App Service内での証明書名> -g <証明書のリソースグループ名> --query "[subjectName,thumbprint]"
上記の手順で設定したSSLサーバ証明書の有効期限が間近となり、その更新版を.pfxファイルで入手したら、Key Vaultの同じ証明書名に対して「az keyvault certificate import」コマンドでインポートを実行する。これにより、更新版(新しい証明書)が最新バージョンとしてKey Vaultに追加される。
そのまま放置していると、Key Vaultとひも付けたApp Service内の証明書は、24時間以内に自動で最新バージョン(更新版)に差し替わる。
すぐに最新バージョンへ差し替えたい場合は、証明書名などを変えることなく前述の「az webapp config ssl import」コマンドを実行すること。即座にKey VaultとApp Serviceの間で証明書の同期が取られて、最新バージョンに差し替わる。
■関連リンク
Copyright© Digital Advantage Corp. All Rights Reserved.