Application Gateway に Let’s Encrypt 証明書を使用する方法

Application GatewayでLet’s Encrypt証明書を設定しようとして、はまりにはまったので対応方法をメモしておく。

今回は、Application GatewayにカスタムドメインのサブドメインをAzure DNSで割り当てて、DNS-01認証でLet’s Encrypt証明書を取得する。取得には、win-acmeを使用した。

Application GatewayのURL:yyy.xxx.example.com
Azure DNSのDNSゾーン:xxx.example.com
発行したい証明書: yyy.xxx.example.com

  1. Application Gatewayを立てる
    とりあえず自己証明書などでたててしまう。DNS-01認証なのでアクセスできる必要はないと思うけど、まぁHTTPSでたててしまう。
  2. 今回はAzure DNSを使用して、DNS-01認証をするので、カスタムドメインの向き先をAzure DNSにする。
    ちなみに今回は、xxx.example.comをAzure DNSに向けた。
    当然、Azure DNSのDNSゾーン登録はxxx.example.comになる。
    CNAMEで、「yyy」をApplication GatewayのURLに向ける。
  3. Azure DNS validationのドキュメントに従って、作業をする。
    3-1. LetsEncryptというサービスプリンシパルを作成する。
    サービスプリンシパルは、Azure Active Directoryの「アプリの登録」に登録される。表示されない場合は、「すべてのアプリケーションの表示」ボタンが表示されれたらクリック、ない場合はドロップダウンなどでフィルタリング条件を変更するといい。

    3-2. Azure DNSでDNS ゾーン(xxx.example.com)に作成したLetsEncryptサービスプリンシパルのアクセス権を付与する。
    アクセス制御画面で、「DNSゾーンの共同作成者」ロールで、LetsEncryptを登録する。

  4. win-acmeをダウンロードする。なお、サブドメインに対して、証明書を発行したい場合、特にAzure DNSに登録しているDNSゾーンが「example.com」ではなく、「xxx.example.com」のようにサブドメインの場合は、win-acmeの問題でDNS-01認証が正常に完了しない。完了させるためにはコードを修正する必要があるので、ソースコードをダウンロードする。
    Visual Studioで開いて下記部分を修正して、ビルドして実行する。

修正前

        _dnsClient.RecordSets.CreateOrUpdate(_azureDnsOptions.ResourceGroupName, 
            url.RegistrableDomain,
            url.SubDomain,
            RecordType.TXT, 
            recordSetParams);

修正後

        _dnsClient.RecordSets.CreateOrUpdate(_azureDnsOptions.ResourceGroupName, 
            "xxx.example.com",//url.RegistrableDomain,
            "_acme-challenge.yyy".//url.SubDomain,
            RecordType.TXT, 
            recordSetParams);

5. ビルドしたletencrypt.exeを起動する。
M: create new certificate with advanced optionsを選択
1: Manually input host names を選択
yyy.xxx.example.com を入力
1: [dns-01] Azure DNS を選択
Tenant Idを入力する。(Get-AzureRmSubscriptions)
Client Idを入力する。(Get-AzureRmADServicePrincipal|where DisplayName -EQ LetsEncrypt のApplication Id)
SecretはService Principalを作成するときに設定したパスワード
DNS Subscription IDは、xxx.example.comのDNSゾーンで表示されるもの
DNS Resource Groupは、xxx.example.comのDNSゾーンで表示されるもの

これで無事に証明書が発行される。

エラー

次のエラーが出るときは、「xxx.example.com」へのアクセス権を付与していることと、ソースコードを修正していることを確認してください。ソースコードを修正していないと、「example.com」DNSゾーンにレコードを作ろうとするので下記エラーが発生します。

The client ‘d38f55be-xxxx-xxxx-xxxx-xxxxx’ with object id ‘d38f55be-xxxx-xxxx-xxxx-xxxxx’ does not have authorization to perform action ‘Microsoft.Network/dnszones/TXT/delete’ over scope