Azure Application GatewayのSSL証明書にLet's Encryptを使う
はじめに
Webサービスを構築・提供する場合、フロントエンドとなる部分はHTTPサーバを直接設定せずに、WAFやロードバランサを入れるのは一般的です。
Azureでもそういったサービスはいくつかあって、Application Gatewayは代表的なもののひとつとなっています。
Application GatewayをWebサービスの入口として構成し、HTTPSアクセスを行う場合、商用の本番環境であればOV証明書・EV証明書を選択する必要があると考えますが、開発環境やステージング環境ではコスト面も考慮する必要があります。
コスト[1]を大きくかけずにDV証明書が取得できる「Let’s Encrypt」は既に皆さんご存じの通りですが、今回はこちらをAzure Application GatewayのSSL証明書として設定する手順をまとめました。
「開発環境はHTTP(平文)でいいよね」「オレオレ証明書でいいかな」といった選択もあるのかなと考えますが、一度ご覧ください。
Azure構成
今回テスト用に作成したいわゆる普通のWebサーバ構成です。
仮想マシンではなくて、App Serviceを使うのべきだったり、バックエンドにあるべきデータベースなどは省略しています。
- Application GatewayはPublic IP Addressを持っており、インターネット側からのアクセスを受け付ける
- HTTPS接続用のSSL証明書はKey Vaultに格納している
- Key VaultはサービスエンドポイントにてApplication Gatewayのあるサブネットからのみ接続可能
- Appication Gatewayはリスナーの設定にてSSL証明書はKey Vault参照をしている(参照時にはUser Managed IDが必要)
- Webサーバは仮想マシン2台で冗長構成となっている(ロードバランスはApplication Gatewayがよしなにやってくれる)
Application Gatewayの証明書管理
Application Gatewayのリスナーで設定する証明書の管理方法は以下の二種類があります。
- 証明書ファイルからのインポート
- Key Vault参照
今回は2番目のKey Vault参照を使っています。
利用したもの
しばやん作の「Key Vault Acmebot」を利用させてもらい、Azure Key Vaultによしなに格納してくれるSSL証明書をAzure Application GatewayからKey Vault参照で利用します。
まあ、こちらのWikiにある手順を読めば全て解決するのですが、諸事情[2]によりApplication Gatewayの連携部分についてより具体的に案内する必要がでましたのでコレを書いています。
Acmebotのデプロイ
先の構成にAcmebotを追加した以下の構成を目指します。
Acmebotから、既存(自分が先に作成した)のKey Vaultへのアクセス権を付与して、Let’s Encryptの証明書をストアしてもらう部分をお願いします。
Application GatewayはAcmebotが作成してくれた証明書を後は参照し続けるだけでOK。
有効期間が切れる前に、Acmebotが証明書の更新も行ってくれるはずです。
まずは既存Key Vaultの「コンテナーのURI」をポータルから確認して控えておきます。
GitHubページからAzureにデプロイ
先にも紹介しましたが、GitHubのページの中ほどにある「Deployment」からAzure(Public)の「Deploy to Azure」をクリックして先に進みます。
パラメータ類は以下の感じで設定します。
設定名 | 設定値 |
---|---|
サブスクリプション リソースグループ |
適当に。対象のKey Vaultがある場所が良いでしょう |
リージョン | 対象のKey Vaultがあるリージョンが良いでしょう |
Location | デフォルトのまま |
Mail Address | Let’s Encryptにリクエストを出すときに使用するメールアドレス |
Acme Endpoint | 今回はLet’s Encryptを使うのでデフォルトのまま |
Create With Key Vault | falseに設定 |
Key Vault Sku Name | 既存のものを使うのでデフォルトのままでOK |
Key Vault Base Url | こちらに先ほど確認した既存Key VaultのURIを入力 |
そしてデプロイが完了したAzureリソース類は以下の通りです。
肝となっているAzure Functionsは従量課金プランとなっており、非常にリーズナブルな構成でデプロイされています。
それでは、今回の環境用に細かく設定していきましょう。
Functionsのアプリケーション設定
ほぼ最初のデプロイ時に入力したパラメータがアプリケーション設定に既に登録されていますが、追加で以下の設定をします。
- Acmebot:MitigateChainOrder
「true」を設定。Application Gatewayでの誤った順序が回避される[3]。 - Acmebot:AzureDns:SubscriptionId
Azure DNSのリソース(今回でいうと、私のnya-n.net)があるAzureサブスクリプションIDを指定。
DNS ProviderはAzure DNS Zoneに限らず、数多く対応しているようです。他のDNS Providerの場合は、以下のWikiを参照して適切な設定をしてください。
Functionsの認証設定
この設定をしないと、Acmebotの管理画面に誰でも入ることが出来てしまうので、Wikiに書かれている通りに設定します。
Functionsの認証設定メニューから、「IDプロバイダーの追加」で「Microsoft」を選択後、後は全てデフォルトの値で「追加」すればとりあえずOKです。
既存のAzure DNSにFunctionsのMSIDに対する権限付与
Azure DNS(今回でいうと私のnya-n.net)に、Acmebotから色々操作させるために「DNS Zone Contributor」権限を付与します。
AcmebotのFunctionsはSystem Managed IDが有効化されているので、そちらをIAMに登録します。
Azure DNSに強い権限を与えないといけない理由ですが、Let’s Encryptが指定されたドメインの所有者確認として、TXTレコードを使って認証しているからです。
参考までに、Acmebotが認証用に追加したTXTレコードは、SSL証明書作成後にはきれいに削除もしてくれていました。
既存のKey VaultにFunctionsからのアクセス権限追加(ネットワーク的な)
今回用意した証明書格納用のKey VaultはPublicネットワークからのアクセスは拒否しているため、従量課金プランで作成されているAcmebotのFunctionsからは、このままではアクセスできません。
Functionsからの送信IPアドレスを以下のサイト情報を参考に確認します。
Azure CLIから以下のコマンドで確認しました。
az functionapp show --resource-group <GROUP_NAME> --name <APP_NAME> --query possibleOutboundIpAddresses --output tsv | sed 's/,/\n/g'
<GROUP_NAME>にはAcmebotをデプロイしたリソースグループ名を、<APP_NAME>にはデプロイされたFunctions名を設定します。
結果として、31個のIPアドレスが出力されたので、これを全てKey Vaultの「ファイアウォールと仮想ネットワーク」に登録します[4]。
既存のKey VaultにFunctionsからのアクセス権限追加(権限的な)
続いて、Key VaultにAcmebotから証明書をストアできるように、IAMの設定も行います。
今回Key Vaultのアクセスポリシーの管理方法は当初からある「コンテナーのアクセスポリシー」と使っています。
「アクセスポリシーの追加」にて、「テンプレートからの構成(省略可能)」のプルダウンから「Certificate Management」を選択後、プリンシパルにAcmebot用FunctionsのSystem Managed IDを設定します。
ダッシュボードへのアクセスと証明書発行
ポータルからFunctionsのエンドポイントURLを確認して、後ろに「/dashboard」を付けてブラウザからアクセスします。
最初にAzure AD認証と、認可して良いか聞かれますので良しなに設定して先に進みます。
こんな画面が出て、エラー的なポップアップ表示がされなければ、ひとまず準備完了です。
「+ Add」ボタンを押すと追加画面が出ます。
こちらの画面の「DNS Zone」で選択できるドメイン一覧は、事前に設定してAcmebotから操作可能なものだけが選択できるようになっています。
今回は私のドメイン「nya-n.net」を選択して、ワイルドカード証明書を作成するので「DNS Names」には「*」を入力後「Add」で追加します。
最後にグリーンの「Add」ボタンをクリックすると、証明書が作成されてKey Vaultに格納されます。
ダッシュボードの一覧に追加されましたね。
Key Vaultの証明書にも追加されています。
Application GatewayのHTTPSリスナー作成
それでは、Application GatewayのHTTPSリスナーを追加していきます(初回デプロイ時にはとりあえずHTTPリスナーで作成してありました)。
Application Gatewayのリスナーの追加で、証明書名は適当に。
「マネージドID」と「キーコンテナ」を指定することで、Acmebotが作成した証明書(この例では「wildcard-nya-n-net」)が選択できるようになっています。
こちらの状態で「追加」します。
他にもApplication Gatewayの設定としては、バックエンドプール、ルールなど各種設定する項目がありますが、こちらは今回の主題とは外れるので省略します。
Application GatewayのPublic IP Addressを、Azure DNSのレコードに追加します。
ワイルドカード証明書なので、FQDN名はなんでも良いです。
アクセス確認
では、ブラウザからhttps://(あなたの設定したFQDN)/ でアクセスしてみましょう。
ばっちりですね。
ちゃんと接続が保護されている旨表示されています。
発行者「R3」(Let’s Encrypt)となっており、有効期限は3ヵ月ほどで想定通りです。
おわりに
Acemebotで証明書更新のデフォルトでは有効期間が切れる30日前に自動更新してくれるようです。
ただし、今回はそこまで確認できませんでした(60日も待てない)。
もともと、こちらのAcmebotは利用者も多く、コントリビュータであるしばやん氏も手厚くメンテナンスしているため、安心して使ってよいと考えます。
もともとこの記事自体には大した追加情報もなく、本家GitHubリポジトリのWikiに全て書かれているのは最初にお伝えした通りですが、Azure Application Gatewayに限定して特定の人に
対して、この記事が少しでも刺さればと考えます。
以上。
-
導入・ランニング・運用コストの事を言っています。 ↩︎
-
https://twitter.com/shibayan/status/1527161773454811136?s=20&t=n4QIm5tODPk8JP_6A08m-w ↩︎
-
https://github.com/shibayan/keyvault-acmebot/discussions/406 ↩︎
-
本格的に利用する場合はAcmebotのプランを変更してサービスエンドポイントで繋げるのが良いと考えますが、今回は省略して手動で31個IPアドレスを登録しています。 ↩︎
Discussion