Cloudflare DNS Firewall とは
DNS インフラを悪意ある攻撃から保護し、アップタイムを向上させ、高速なパフォーマンスを実現する DNS のための Firewall-as-a-Service (FWaaS) です。
例えば、オンプレにある権威DNSサーバー (BIND) 運用を維持したまま、ランダムサブドメイン攻撃や DDoS 攻撃などからオリジン権威 DNS サーバーを保護したい場合に有効なソリューションです。
Enterprise のお客様を対象とした有償アドオン機能になります。
また、主な特徴は以下の通りです。
権威DNSサーバ (BIND) 準備
DNS Firewall セットアップ
ネームサーバーのIPをCloudflareに向けるだけです。
以下のステップで実装します。
- DNS Firewall クラスタ設定
- レジストラでグルーレコード変更
- ゾーンファイルでネームサーバーAレコード変更
- オリジンで Cloudflare IP を許可
DNS Firewall クラスタ設定
権威DNSサーバー (BIND) のオリジン IP を入れて作成します。
Cloudflare の IP が払い出されますので、次のステップ以降で使います。
レジストラでグルーレコード変更
お名前.com では、以下の手順で変更できます。
グルーレコードを払い出された Cloudflare IP に設定します。
ゾーンファイルでネームサーバーAレコード変更
権威DNSサーバー (BIND) 側でも、ネームサーバーの A レコードを払い出された Cloudflare IP に設定します。
@ IN NS ns1.example.com.
@ IN NS ns2.example.com.
ns1 IN A 172.x.x.x
ns2 IN A 172.y.y.y
オリジンで Cloudflare IP を許可
Cloudflare の公開 IP レンジを、オリジン側で TCP / UDP port 53
が通るように許可してください。
名前解決の確認
dig +trace
により、払い出された Cloudflare IP 172.x.x.x
が権威 DNS として応答することを確認します。
% dig +trace +nodnssec example.com
; <<>> DiG 9.18.20 <<>> +trace +nodnssec example.com
;; global options: +cmd
. 511072 IN NS a.root-servers.net.
. 511072 IN NS b.root-servers.net.
. 511072 IN NS c.root-servers.net.
. 511072 IN NS d.root-servers.net.
. 511072 IN NS e.root-servers.net.
. 511072 IN NS f.root-servers.net.
. 511072 IN NS g.root-servers.net.
. 511072 IN NS h.root-servers.net.
. 511072 IN NS i.root-servers.net.
. 511072 IN NS j.root-servers.net.
. 511072 IN NS k.root-servers.net.
. 511072 IN NS l.root-servers.net.
. 511072 IN NS m.root-servers.net.
;; Received 239 bytes from 2606:4700:4700::1111#53(2606:4700:4700::1111) in 6 ms
site. 172800 IN NS b.z.net.
site. 172800 IN NS f.z.net.
site. 172800 IN NS a.z.net.
site. 172800 IN NS e.z.net.
;; Received 289 bytes from 202.12.27.33#53(m.root-servers.net) in 5 ms
example.com. 3600 IN NS ns1.example.com.
example.com. 3600 IN NS ns2.example.com.
;; Received 109 bytes from 2a04:2b00:13ff::61#53(f.z.net) in 62 ms
example.com. 86400 IN A 34.z.z.z
example.com. 86400 IN NS ns1.example.com.
example.com. 86400 IN NS ns2.example.com.
;; Received 125 bytes from 172.x.x.x#53(ns1.example.com) in 17 ms
追加で API 設定できる項目
こちらにある API パラメータ(ダッシュボードにないものが含まれる)を指定できます。
export EMAIL='YOUR_EMAIL'
export APIKEY='YOUR_APIKEY'
export ACCOUNT_ID='YOUR_ACCOUNT_ID'
curl -s "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/dns_firewall" \
-H "X-Auth-Email: $EMAIL" \
-H "X-Auth-Key: $APIKEY" | jq
Rate Limit
API パラメータを使って、Rate Limit(データセンターあたり1秒あたりのクエリー数)を指定できます。
データセンターごとの1秒あたりのクエリ数の上限が、クラスタに設定されたオリジン権威 DNS サーバーに送信される DNS クエリに適用されます。
export CLUSTER_TAG='YOUR_CLUSTER_TAG'
curl -X PATCH "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/dns_firewall/$CLUSTER_TAG" \
-H "X-Auth-Email: $EMAIL" \
-H "X-Auth-Key: $APIKEY" \
-H "Content-Type: application/json" \
--data '{
"ratelimit":600
}'
ランダムサブドメイン攻撃(ランダムプレフィックス撃)保護
以下のようなランダムサブドメイン攻撃(ランダムプレフィックス撃)に対して、自動保護機構を有効化できます。
以下の API 操作により、有効化できます。
攻撃を検知すると、サブドメインやサブサブドメインなど、オリジン権威 DNS サーバーへの問い合わせを一時的に停止します。その後、Cloudflare はキャッシュされたレスポンスで応答します(TTLがまだ失効していない場合)。
FAQs — DNS Firewall · Cloudflare DNS docs
DNSファイアウォールはどのくらい古いオブジェクトをキャッシュしますか?
DNS Firewallは、割り当てられたメモリに応じてキャッシュの寿命を設定します。
十分な割り当てメモリがある限り、Cloudflareは、TTLが失効しても、キャッシュからアイテムを強制的にクリアしません。この機能により、ネームサーバーがオフラインの場合、Cloudflareはキャッシュから古いオブジェクトを提供することができます。
また、log_only
モードや only_when_upstream_unhealthy
のオプションも設定できます。
export CLUSTER_TAG='YOUR_CLUSTER_TAG'
curl -X PATCH "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/dns_firewall/$CLUSTER_TAG" \
-H "X-Auth-Email: $EMAIL" \
-H "X-Auth-Key: $APIKEY" \
-H "Content-Type: application/json" \
--data '{"attack_mitigation":{
"enabled":true,
"log_only":true,
"only_when_upstream_unhealthy":false
}
}'
【参考】ランダムサブドメイン問い合わせ
例えば、自らテストしたい場合には以下のツールを使って ChatGPT に教えてもらったランダムなサブドメインに DNS クエリを投げることができます。
dnsbench run --nameserver=8.8.4.4 --count=3000 --names "domains_to_lookup.txt"
統計データ・ログ
Analytics
以下の API から統計データを取得できます。
export CLUSTER_TAG='YOUR_CLUSTER_TAG'
% curl -s "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/dns_firewall/$CLUSTER_TAG/dns_analytics/report" \
-H "X-Auth-Email: $EMAIL" \
-H "X-Auth-Key: $APIKEY" | jq
{
"result": {
"rows": 1,
"data": [
{
"metrics": [
112
]
}
],
"data_lag": 0,
"min": {},
"max": {},
"totals": {
"queryCount": 112
},
"query": {
"dimensions": [],
"metrics": [
"queryCount"
],
"since": "2023-12-12T23:36:00Z",
"until": "2023-12-13T05:36:00Z",
"limit": 100000
}
},
"success": true,
"errors": [],
"messages": []
}
Logpugh
個々の詳細ログを確認するには、Logpush を構成する必要があります。
ログを見ていると、ランダムに大文字を含む問い合わせや存在しないサブドメインへの問い合わせがあることがわかります。
{
"ClientResponseCode": 3, // NXDOMAIN
"ClusterID": "xxx",
"ColoCode": "NRT",
"EDNSSubnet": "",
"EDNSSubnetLength": 0,
"QueryDO": true,
"QueryName": "gaLActic-EXPlOrATIon.ExAMPLe.CoM",
"QueryRD": false,
"QuerySize": 62,
"QueryTCP": false,
"QueryType": 1,
"ResponseCached": false,
"ResponseCachedStale": false,
"SourceIP": "173.194.168.132",
"Timestamp": "2023-12-13T15:33:38Z",
"UpstreamIP": "x.x.x.x",
"UpstreamResponseCode": 3,
"UpstreamResponseTimeMs": 9
}
まとめ
Cloudflare DNS Firewall を使って権威 DNS サーバー (BIND) を保護する構成が取れることが確認できました。
統計データやログなどに関わる部分でも十分に透明性が期待できます。
オンプレなどに権威 DNS サーバー (BIND) をお持ちの方は、参考にしてみてください。