🌊

Cloudflare DNS Proxy モード と CNAME Flattening (ALIASレコード)について

2023/03/19に公開

先日こちらの福岡ミートアップでCloudflareのDNS Proxyという設定が話題となりましたので、その機能や混同されがちなCNAME Flattening (ALIASレコード)についてまとめます。

クラスメソッドの大栗さんも記事をまとめてくれていますので併せて参考にしてください。

DNS Proxyモードとは

CloudflareのDNS設定はではProxy モードとDNS Onlyモードの2種類があります。
Proxyモード

DNS Onlyモード

これはいわゆる一般的なDNSプロキシとことなり、DNSリゾルバに対する問い合わせをCloudflareが代理で行う機能ではありません。(勿論Cloudflareが外部のDNS権威サーバと連携してユーザーのDNSを管理する機能は別途提供しています)

DNSステータスが"Proxied"となることで、DNSリゾルバに対する名前解決の結果CloudflareのIPアドレスが応答されるようになります。クライアントはそのIPアドレスにアクセスを行うことでオリジンへのリクエストはCloudflare内部ネットワークを通ることになります。
Cloudflareでは285以上のエッジでIP Anycastをサポートしており、単一IPアドレスに対してのリクエストがどのエッジで処理をされても、オリジンまで問題なく通信がルーティングされます。
つまりユーザーからするとCloudflare全体がオリジンと同一の存在であるとDNS側で処理が行われます。DNSそのものには名前解決後の通信を保護する&最適化する機能は提供されていませんので、これはCloudflare独自の機能です。
この機能を用いることでDDoS対策などがCloudflare側で行われることになります。

"DNS Only"モードであれば、オリジンのIPが直接クライアントに応答されるため、通信はCloudflareを通らず直接インターネット経由となります。

このプロキシーモードはA,AAAA,CNAMEに設定が可能ですが大きなメリットは以下2点です。
1.GlobalのCloudflareネットワークを通信が通ることとなりますが、Cloudflareでは内部ネットワークにIP Anycastルーティングをベースとした独自機能を提供しており、インターネット上の輻輳遅延を回避することが可能です。ほとんどの場合この機能を使うことで通信は高速化されます。

2.CNAMEの場合、オリジンのドメイン名&IPアドレスを隠匿化することが可能なので、オリジンを保護することが可能となる。CDNを使った場合でも、オリジンへ直接アクセスを試みたり、DDoS攻撃パケットを送り付けることは可能です。通常はそれを防ぐために様々な設定が追加で必要となりますが、プロキシーモードによって簡易な防御が可能となります。
あえて簡易と書くのは、CNAME元のドメイン名やIPアドレスはインターネット上に存在しており、別経路でIPアドレスやドメインが漏洩した場合、直接アクセスは可能となるためです。

実際にやってみる

では実際に見ていきましょう。AWS EC2を使ってオリジンを立てます。AWSの使い方は本記事からは割愛します。

IP Address:43.207.143.30
FQDN:http://ec2-43-207-143-30.ap-northeast-1.compute.amazonaws.com/

まずIPとFQDN両方でアクセスできることを確認しておきます。

まずはDNS OnlyモードでCloudflare上で管理しているドメインに対するCNAMEを張ります。

IP Address:43.207.143.30
FQDN:http://ec2-43-207-143-30.ap-northeast-1.compute.amazonaws.com/
CNAME:http://ec2test.harunobukameda.labrat.online/

になります。この時点では3つともブラウザからアクセスが可能です。
nslookupコマンドでCNAMEドメインを調べると以下の通りですから、オリジンのFQDNとIP Addressは外部に公開されていることがわかります。

nslookup ec2test.harunobukameda.labrat.online
サーバー:  UnKnown
Address:  240d:1a:331:6a00:ce1a:faff:feb9:3e64

権限のない回答:
名前:    ec2test.harunobukameda.labrat.online
          2606:4700:3032::6815:1d37
          43.207.143.30

ではCloudflareのCNAME設定をProxiedに変更します。
その後数分待ったのち再度nslookupを実行するとIPアドレスが異なっていることがわかります。

nslookup ec2test.harunobukameda.labrat.online
サーバー:  UnKnown
Address:  240d:1a:331:6a00:ce1a:faff:feb9:3e64

権限のない回答:
名前:    ec2test.harunobukameda.labrat.online
Addresses:  2606:4700:3034::ac43:ab61
          2606:4700:3032::6815:1d37
          104.21.29.55
          172.67.171.97

このIPアドレスはCloudflare のIP Address Ranges範囲内であることがわかります。
つまりオリジンのFQDNおよびIPアドレスが隠匿化されていることがわかります。
ただし、オリジンの
IP Address:43.207.143.30
FQDN:http://ec2-43-207-143-30.ap-northeast-1.compute.amazonaws.com/
に引き続き直接可能であることに注意してください。つまりこの手法は完全なオリジン保護のセキュリティとは言えず、オリジンのIP及びFQDNは別経路で漏洩した場合引き続き攻撃対象となりえます。

ではこの時点でdigコマンドを実行してみると以下のような値が戻ります。

;; ANSWER SECTION:
ec2test.harunobukameda.labrat.online. 300 IN A	104.21.29.55
ec2test.harunobukameda.labrat.online. 300 IN A	172.67.171.97

;; AUTHORITY SECTION:
harunobukameda.labrat.online. 300 IN	NS	vicky.ns.cloudflare.com.
harunobukameda.labrat.online. 300 IN	NS	rosalie.ns.cloudflare.com.

CloudflareのIPアドレスがAレコードで戻ってきています。
通常のCNAME,Cloudflareでいうところの"DNS Only"モードであれば以下の回答が一般的です。

;; ANSWER SECTION:
ec2test.harunobukameda.labrat.online. 197 IN CNAME ec2-43-207-143-30.ap-northeast-1.compute.amazonaws.com.
ec2-43-207-143-30.ap-northeast-1.compute.amazonaws.com.	604800 IN A 43.207.143.30

;; AUTHORITY SECTION:
ap-northeast-1.compute.amazonaws.com. 797 IN NS	ns4.p31.dynect.net.
ap-northeast-1.compute.amazonaws.com. 797 IN NS	u5.amazonaws.com.
ap-northeast-1.compute.amazonaws.com. 797 IN NS	u1.amazonaws.com.
ap-northeast-1.compute.amazonaws.com. 797 IN NS	pdns5.ultradns.info.
ap-northeast-1.compute.amazonaws.com. 797 IN NS	pdns1.ultradns.net.
ap-northeast-1.compute.amazonaws.com. 797 IN NS	u2.amazonaws.com.
ap-northeast-1.compute.amazonaws.com. 797 IN NS	ns1.p31.dynect.net.
ap-northeast-1.compute.amazonaws.com. 797 IN NS	pdns3.ultradns.org.
ap-northeast-1.compute.amazonaws.com. 797 IN NS	u3.amazonaws.com.
ap-northeast-1.compute.amazonaws.com. 797 IN NS	u4.amazonaws.com.
ap-northeast-1.compute.amazonaws.com. 797 IN NS	ns2.p31.dynect.net.
ap-northeast-1.compute.amazonaws.com. 797 IN NS	u6.amazonaws.com.
ap-northeast-1.compute.amazonaws.com. 797 IN NS	ns3.p31.dynect.net.

AレコードとしてCNAMEが戻ってきます。
これと似た動きをするのがAWSのRoute53などでサポートされているALIASレコード、CloudflareではCNAME Flatteningというものになりますが技術的には別物です。折角ですのでその違いをまとめておきます。

CNAME FlatteningとALIASレコード

Zone Apex(kamedatest.com等のように、サブドメインを持たないもの)はRFC違反となるため、CNAMEで用いることができません。具体的には以下のルールが矛盾します。
1.CNAMEに用いられるレコードではCNAMEエントリしか記載ができない (RFC1921)
2.Zone ApexではCNAME以外にNSレコードなど複数エントリがルール上必須(RFC1035)
この問題を解決するのがAWS等でサポートされているALIASレコードであり、CloudflareではCNAME Flatteningという違いがあります。二つの主な違いはALIASレコードは明示的にCNAMEではないことを宣言して設定する必要があるのに対して、CNAME FlatteningではCNAMEで設定され自動で判別されます。

基本的な動作は以下です。先ほどの環境を例にとります。

IP Address:43.207.143.30
FQDN:http://ec2-43-207-143-30.ap-northeast-1.compute.amazonaws.com/
ALIAS:http://harunobukameda.labrat.online/

ALIASレコードの「harunobukameda.labrat.online」として名前解決がされた場合、43.207.143.30が直接IPアドレスとして回答されます。通常CNAMEはまずec2-43-207-143-30.ap-northeast-1.compute.amazonaws.comが回答されたのち、再度DNS問い合わせが発生し、43.207.143.30が回答されるという二段階の動作をしますので、CNAMEがRFC違反であるということを解決する以外に通信の高速化も期待できます。ただし、43.207.143.30を調べればFQDNが
ec2-43-207-143-30.ap-northeast-1.compute.amazonaws.comであることはすぐ判明します。

一方CNAME Flattening+DNS プロキシーモードではharunobukameda.labrat.onlineに対する問い合わせ結果がCloudflareのIPアドレスになります。DNS OnlyモードではALIASレコードと同じ動きをしオリジンのIPアドレスを応答します。

Discussion