ACM証明書のDNS検証:CNAMEレコードを使ったドメイン所有者確認の仕組み

AWSIaC

AWS Certificate Manager(ACM)を使ってSSL/TLS証明書を発行する際には、ドメイン所有権を確認するプロセスが必要です。ACMでは「DNS検証」と「メール検証」の2つの方法でドメイン所有者の確認を行なっています。

[Terraform] aws_acm_certificateリソース(DNS検証)
resource "aws_acm_certificate" "dns_cert" {
  domain_name       = "*.example.com"
  validation_method = "DNS" # DNS検証を指定

  tags = {
    Name = "example-wildcard-cert"
  }
}
[Terraform] aws_acm_certificateリソース(メール検証)
resource "aws_acm_certificate" "email_cert" {
  domain_name       = "*.example.com"
  validation_method = "EMAIL" # メール検証を指定

  tags = {
    Name = "example-email-cert"
  }
}

今回は、より自動化に適した「DNS検証」(CNAMEレコード)を利用したドメイン確認の流れについて解説していきます。

(詳細の実装手順は、こちらで記事にしています。)


0. 前提

CNAMEレコード

CNAME(Canonical Name)レコードは、DNSレコードの種類の一つで、「あるドメイン名を別のドメイン名に紐付ける(エイリアスを設定する)」ために使用されます。

CNAMEレコードの例 sample.example.com → example.com
この設定では、sample.example.comへのDNS問い合わせを行うと、DNSサーバーからexample.comの情報が返ってきます。
つまり、「sample.example.com」のDNS情報は、「example.com」に設定された情報を参照する形になる。

この機能を利用して、ACMのDNS検証では「ドメイン所有者の確認」を行なっています。

1. CNAMEレコードを使ったドメイン所有者確認の仕組み

1-1. ACMリソース作成時のdomain_validation_optionsの生成

ACMでは”DNS検証”を選択すると、ACMリソース作成時にDNS検証(ドメイン所有者の確認プロセス)のために、domain_validation_options(ドメイン所有者の確認プロセスで使うCNAMEレコード情報)が自動生成されます。

domain_validation_optionsデータ生成例
(ドメイン「example.com」にサブドメイン「api」「www」「blog」登録済みの場合)

"domain_validation_options": [
    {
        "domain_name": "api.example.com",  // 証明書が発行されるドメイン名(例: api.example.com)
        "resource_record_name": "_abcdef1234567890.api.example.com",  // DNS検証用のCNAMEレコード名(例: _abcdef1234567890.api.example.com)
        "resource_record_type": "CNAME",  // DNSレコードタイプ(通常は "CNAME")
        "resource_record_value": "_xyz9876543210.acm-validations.aws"  // 設定すべきCNAMEレコードの値(ACMが提供する検証用のレコード値)
    },
    {
        "domain_name": "www.example.com",  // 証明書が発行される別のドメイン名(例: www.example.com)
        "resource_record_name": "_ghijk1234567890.www.example.com",  // このドメインの検証用CNAMEレコード名
        "resource_record_type": "CNAME",  // DNSレコードタイプ(通常は "CNAME")
        "resource_record_value": "_uvw9876543210.acm-validations.aws"  // 検証用のCNAMEレコード値
    },
    {
        "domain_name": "blog.example.com",  // 証明書が発行される別のドメイン名(例: blog.example.com)
        "resource_record_name": "_lmnop1234567890.blog.example.com",  // このドメインの検証用CNAMEレコード名
        "resource_record_type": "CNAME",  // DNSレコードタイプ(通常は "CNAME")
        "resource_record_value": "_rst9876543210.acm-validations.aws"  // 検証用のCNAMEレコード値
    }
]


各フィールド説明

項目KeyValue
名前(Name)resource_record_name_randomstring1.example.com
タイプ(Type)resource_record_typeCNAME
値(Value)resource_record_value_randomstring2.acm-validations.aws

1-2. このdomain_validation_optionsを用いて、対象のゾーンファイルにCNAMEレコードを追加
$TTL 300
@    IN    SOA   ns1.example.com. admin.example.com. (
               2025011201 ; Serial
               3600       ; Refresh
               1800       ; Retry
               1209600    ; Expire
               86400 )    ; Minimum TTL

@               IN    NS    ns1.example.com.
@               IN    NS    ns2.example.com.

; A Records for Subdomains
api             IN    A     192.0.2.1
www             IN    A     192.0.2.2
blog            IN    A     192.0.2.3

# ACM証明書発行に必要なドメイン所有者確認プロセスのためにCNAMEレコードを追加
# (各値はdomain_validation_optionsの値を使用)
; CNAME Records for ACM validation
_abcdef1234567890.api    IN    CNAME    _xyz9876543210.acm-validations.aws.
_ghijk1234567890.www     IN    CNAME    _uvw9876543210.acm-validations.aws.
_lmnop1234567890.blog    IN    CNAME    _rst9876543210.acm-validations.aws.
ポイント
  • ACMが生成するCNAMEレコードの「名前」と「値」は一意(ACM内部で管理)。【1-1】
  • ACMを作成しようとしている人(わたし)のみが、このCNAMEレコード「名前」と「値」の一意の情報を知ることができる【1-1】
  • 対象のゾーンに、CNAMEレコードを設定【1-2】
  • このため、正しいCNAMEレコードを設定できるのは、そのドメインを管理している”わたし”のみである

以上から、ACMが生成するCNAMEレコード情報を使って、正しいCNAMEレコードを設定できるのはACMを作成しようとする人であることを証明しています。

2. ACMのDNS問い合わせの流れ

2-1. DNSに問い合わせを行う

ACMは指定されたドメイン(例:example.com)のサブドメインに関連するCNAMEレコードをDNSサーバーに問い合わせます。

_abcdef1234567890.api    IN    CNAME    _xyz9876543210.acm-validations.aws.
_ghijk1234567890.www     IN    CNAME    _uvw9876543210.acm-validations.aws.
_lmnop1234567890.blog    IN    CNAME    _rst9876543210.acm-validations.aws.

上記は、「api」「www」「blog」サブドメインに対するACM証明書のドメイン所有者確認用のCNAMEレコード。

2-2. DNS問い合わせの流れ
  • ACMは最初に、_abcdef1234567890.api.example.comというCNAMEレコードの存在をDNSサーバーに問い合わせます。
  • もしそのレコードが存在する場合、DNSサーバーはその値(例えば、_xyz9876543210.acm-validations.aws)を返します。
  • ACMは、受け取った値と、ACM側で設定された値が一致するかを確認し、正しければドメインの所有者が正しいと判断されます。

同様に、その他のサブドメイン(例えば、_ghijk1234567890.www.example.com_lmnop1234567890.blog.example.com)についても、指定されたCNAMEレコードの値が一致するかを確認します。

(正しい値が設定されていない場合)
設定されたCNAMEレコードが間違っている、またはDNSサーバーに設定されていない場合、ACMは証明書の発行を停止します。