ちょっと話題の記事

AWSの基礎を学ぼう 特別編 最新サービスをみんなで触ってみる 〜Amazon Route 53 Resolver DNS Firewall〜 ハンズオン手順 #awsbasics

恥ずかしながら DNS トンネリングの仕組みについて初めて知りました。結果、「DNS セキュリティめっちゃ大事やん!」と思った。
2021.07.31

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

今回は2021年7月31日に開催されました「AWSの基礎を学ぼう 特別編 最新サービスをみんなで触ってみる 〜Amazon Route 53 Resolver DNS Firewall 編〜」のハンズオン資料として本記事を投稿しています。

「AWSの基礎を学ぼう?ナニソレ?」

という方は、以下の記事をあわせてお読みいただけると幸いです。

Amazon Route 53 Resolver DNS Firewall

Amazon Route 53 Resolver は VPC 用の DNS サーバーとして提供されています。これらの IP アドレスは予約されており、以下のアドレスが使用されます。

  • 169.254.169.253
  • VPC IPv4 ネットワーク範囲に +2 したアドレス(例:192.168.0.0/24の場合、192.168.0.2

Amazon Route 53 Resolver DNS Firewallは、これらの Route 53 Resolver への DNS クエリに対するファイアウォールです。

なぜ DNS を守る必要があるのか?

一般的に HTTP などの Web プロトコルに対するセキュリティ意識は高いものの、DNS セキュリティまで意識されている環境はどれだけあるでしょうか。

  • 「DNS なんて名前解決するだけでしょ?」
  • 「ファイル転送とか出来ないし、DNS クエリは全リクエスト許可して大丈夫だよね」

このような認識から、ネットワークファイアウォールでプライベート環境からインターネットへのアウトバウンドは制限しているけど、 DNS クエリはプライベート環境からでも最終的に外部の DNS へクエリが送信可能な環境は少なくありません。攻撃者はこのようにセキュリティへの意識の低いところを突いてくるものです。

結論から言えばDNS クエリを使ってサーバーのシステム情報や、機密データを転送することは可能です。

代表的な攻撃手法は2015年後半から登場した「DNS トンネリング」です。ネットワークファイアウォールを入れている環境でも、DNS クエリに対する対策を行っていなければ防ぐことも気づくことさえも難しいでしょう。

攻撃手法の詳細は本筋ではないので割愛しますが、以下の記事と動画がとても解りやすいので是非一読ください。DNS セキュリティへの意識がきっと高まると思います。

このように、近年では DNS を使った攻撃がどんどん進化し普及している背景から、DNS セキュリティを高めるためのサービスが求められています。

防げるもの・防げないもの

DNS Firewallが防げるものは Amazon Route 53 Resolver に対する DNS/UDP トラフィックです。よって以下のようなものは防ぐことは出来ません。

  • HTTP、SSH、TLS、FTP などのアプリケーション層プロトコルに対するトラフィック
    • これらを防ぎたい場合は、Network Firewall を検討ください
  • Amazon Route 53 Resolver 以外での名前解決
    • ローカル hosts
    • 外部 DNS へのクエリ

料金

以下の2つに対して、料金が発生します。

  • ドメイン名:1ドメインあたり $0.0005/月
  • クエリ:$0.60/100万クエリあたり

なお、DNS Firewallで提供されているマネージドドメインリストに対してはドメイン料金は発生しません。

ハンズオン手順

今回のハンズオンで作成する環境は以下のような構成になります。

1. VPC関連リソースの作成

今回の作業用にコチラの CloudFormation テンプレートをダウンロードしてください。このテンプレートでは以下のリソースを作成します。

  • VPC
  • パブリックサブネット
  • ルートテーブル
  • インターネットゲートウェイ

Step 1-1

AWS 管理コンソールから CloudFormation を開き、[スタックの作成]をクリック。[テンプレートファイルのアップロード]を選択し、[ファイルの選択]から先程ダウンロードしたリポジトリ内にあるテンプレートファイル 20210731_handson.yml を指定し、[次へ]をクリック。

Step 1-2

任意のスタック名(handson0731)を入力し、その他はデフォルト値で問題ありませんので[次へ]-[次へ]-[スタックの作成]と進めて実行します。1分程度でリソース作成が完了し、スタックのステートが CREATE_COMPLETEに変わります。

VPC 関連リソースの作成は以上です。

2. Cloud9 の起動

今回は VPC 内から DNS クエリを投げるための環境として Cloud9 を利用します。

Step 2-1

AWS管理コンソールから Cloud9 を開き[Create environment]をクリック。任意の環境名(handson0731)を入力し、[Next step]に進みます。

Step 2-2

画面下部の[Network settings (advanced)]を展開し、CloudFormation で作成した VPC およびサブネットを選択します。その他はデフォルト値のまま[Next step]に進み、[Create environment]で作成します。

Cloud9 の起動まで 2 分ほど待ちます。

Step 2-3

Cloud9 が起動したらデフォルト状態でexample.comへの DNS クエリが正常応答することを確認しておきます。

$ dig example.com

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14686
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;example.com.                   IN      A

;; ANSWER SECTION:
example.com.            300     IN      A       93.184.216.34

;; Query time: 1 msec
;; SERVER: 10.1.0.2#53(10.1.0.2)
;; WHEN: Sun Jul 25 00:11:22 UTC 2021
;; MSG SIZE  rcvd: 56

Cloud9 の起動は以上です。

3. DNS Firewall 設定

それでは今日の本題となる DNS Firewall の設定をしていきましょう。

  • Cloud9 のコンソールから AWS 管理コンソールに戻るには左上の「9」マークをクリックし、Go To Your Dashborardをクリックします

Step 3-1

AWS 管理コンソールで VPC を開き、[DNS FIREWALL]-[ルールグループ]-[ルールグループを作成]をクリックします。

余談ですが、Route 53 の管理メニューからも同様の操作が可能ですが、執筆時点では Route 53 側のメニューは日本語対応していませんでした。

Step 3-2

任意のルールグループ名(handson0731-gr)を入力し[Next]をクリック。

Step 3-3

ルールグループに追加するフィルタリングルールを作成しますので[ルールを追加]をクリック。任意のルール名(handson0731-rule)を入力します。

Step 3-4

次にルールに追加するドメインリストを指定します。

[ドメインリスト]は独自のドメインリストを追加を選択します。ドメインリスト選択のプルダウンメニューから新しいドメインリストを作成を選択し、任意のドメインリスト名(example-list)を入力し、フィルタリングするドメイン名を入力します。今回はexample.comを指定します。

もし、www.example.comなどのサブドメインすべても対象にしたい場合は、*.example.com追加します。

Step 3-5

次に DNS クエリが一致した場合のアクションを指定します。

今回はBLOCKを選択し、BLOCK アクションのレスポンスはNODATAを指定します。さいごに[ルールを追加]をクリックします。

[Next]をクリックしてしまうとルールが追加されないまま、ルールグループ作成メニューが進んでしまいすのでご注意ください。

Step 3-6

追加したルールが表示されていることを確認し、[Next]をクリック。

ここでルールが表示されていない場合は、Step 3-5の操作で[ルールを追加]ではなく、誤って[Next]をクリックしていると思いますので、Step 3-5に戻りルールの追加設定を行ってください。

Step 3-7

次にルールの優先度設定画面ですが、今回はルールが1つしかないのでデフォルトのまま[Next]をクリック。タグ付けも今回は行わず[Next]をクリックし、[Create rule group]でルールグループを作成します。

Step 3-8

作成したルールグループをクリックし、[関連付けられた VPC]タブから、VPC を関連付けをクリックします。

Step 3-9

CloudFormation で作成した VPC を選択して[関連付ける]をクリックします。(2 分ほど待ちます)

ステータスが完了になりましたら、関連付けは終了です。

4. 動作確認

Step 4-1

それでは Cloud9 のターミナルに戻り、DNS クエリを投げて意図したフィルタリングが動作することを確認します。

IP アドレスが参照できなくなっていれば、正常に動作しています。

$ dig example.com

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29354
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;example.com.                   IN      A

;; Query time: 2 msec
;; SERVER: 10.1.0.2#53(10.1.0.2)
;; WHEN: Sun Jul 25 02:46:21 UTC 2021
;; MSG SIZE  rcvd: 40

Step 4-2

また、以下のように Route 53 Resolver 以外への DNS クエリについてはブロック出来ないことも確認します。

$ dig example.com @8.8.8.8

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> example.com @8.8.8.8
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 27922
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;example.com.                   IN      A

;; ANSWER SECTION:
example.com.            21017   IN      A       93.184.216.34

;; Query time: 2 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Mon Jul 26 22:26:31 UTC 2021
;; MSG SIZE  rcvd: 56

このように DNS Firewall は特定ドメインへのアクセス制御を行うことで、マルウェアドメインや C&C ドメインを利用した DNS ベースの攻撃に対するリスクを低減することは出来ますが、すべての DNS クエリをブロック出来るものではありません。

必要に応じてサーバから外部 DNS へのクエリを制限するなどの対応も検討するのが良いでしょう。

5. DNSクエリログの記録

フィルタリングにより BLOCK されたこと、または ALERT 状況をモニタリングおよび通知するためには DNS クエリのログ記録を行う必要があります。

Step 5-1

AWS 管理コンソールから Route 53 を開き、[リゾルバー]-[クエリのログ記録]-[クエリログ記録の設定]をクリックします。

Step 5-2

任意の設定名(handson0731)を入力します。今回はクエリログの送信先としてCloudWatch Logs のロググループを使用します。

[CloudWatch Logs ログのグループ]はCreate log groupを選択し、[New log group name]で任意のロググループ名(/aws/route53/handson0731)を入力します。

Step 5-3

[クエリをログ記録するVPC]-[VPCを追加]をクリックし、CloudFormation で作成したVPCを選択し[追加]して、[クエリログの設定]で設定します。

Step 5-4

ステータスがCreatedになっていれば、DNSクエリログ記録の設定は完了です。

Step 5-5

Cloud9 のターミナルに戻り、digコマンドでexample.comへの DNS クエリを投げてブロックされたイベントを作成しておきます

$ dig example.com

Step 5-6

AWS 管理コンソールから CloudWatch を開き、[ログ]-[ロググループ]の一覧から先程作成したロググループをクリックします。

Step 5-7

[Search log group]をクリックし、イベントフィルターに{ $.firewall_rule_action = "BLOCK" }と入力して検索を実行します。

すると以下のように、DNS FIrewall でブロックされた DSN クエリの情報が見つかります。(見つからない場合は、しばらく待った後にリトライしてください)

手順は割愛しますが、[Create Metric Filter]からカスタムメトリクスを作成することで、フィルタリング件数等をモニタリングすることも出来ます。以下の例ではディメンションに$.query_nameを設定することでブロックされた DNS 名のカウントを設定しています。

これらのカスタムメトリクスを利用して CloudWatch アラームを設定し、フィルタリングされる DNS クエリ件数の異常を検知するのも良いでしょう。

DNS トンネリングは DNS プロトコルの仕組み上、一度に大きなデータを送ることは出来ません。データを抜き出そうとする際には大量の異常な DNS クエリ(異常に長いクエリ名、大量の TXT レコードのクエリなど)が発生している可能性が高いです。異常な振る舞いを早期に検知し、停止させることが重要になります。

本日のハンズオンは以上で終了です。

6. 片付け

以下の順に削除していきます。

  • [Route 53] クエリのログ記録を停止(stop-loggingと入力)
  • [Route 53] クエリのログ記録を削除(deleteと入力)
  • [CloudWatch]CloudWatch ロググループを削除
  • [VPC] ルールグループ内のルールを削除(削除と入力)
  • [VPC] ルールグループと VPC の関連付けを解除(関連付けを解除と入力)
  • [VPC] ルールグループを削除(削除と入力)
    • なぜかルールグループ内の削除メニューからは削除できないので、ルールグループ一覧から削除メニューを開いてください
  • [VPC] ドメインリストを削除(削除と入力)
  • [Cloud9] 環境を削除(Deleteと入力)
  • [CloudFormation] スタックの削除

まとめ

  • ネットワークファイアウォールに守られたプライベートなネットワーク内のサーバでも、プロキシを介して DNS クエリはインターネットへ抜けれる環境は少なくない
  • 近年のマルウェアはセキュリティ意識の低い DNS トラフィックを利用した攻撃が増えている
  • DNS クエリを使って機密データを盗み出すことが可能(DNS トンネリング)
  • Amazon Route 53 Resolver DNS Firewall は Route 53 Resolver 専用の DNS ファイアウォール
  • EC2 から直接外部 DNS へ送られる DNS クエリは防御できない
  • DNS クエリログを使って DNS クエリの異常な振る舞いを早期に検知し、すべてのデータを送らせないことが重要

以上!大阪オフィスの丸毛(@marumo1981)でした!