ENGINEER BLOG ENGINEER BLOG
  • 公開日
  • 最終更新日

【Network Firewall】AWS Network Firewall の最小構成を作り、SNI ログから許可ドメインを絞り込む

この記事を共有する

目次

はじめに

アウトバウンド通信をドメインベースで制御したい場合、最初から必要な FQDN をすべて洗い出すのは意外と難しいです。
実際の運用では、まず *.example.com のようなワイルドカードを含む広めの許可から始め、通信ログを見ながら必要な FQDN に絞っていく進め方のほうが現実的なことがあります。

今回は、AWS Network Firewall(以下 NFW)の最小構成を作成し、TLS通信がalert log に出力するSNI(Server Name Indicator ) event.tls.sni を CloudWatch Logs Insights で確認することで、ワイルドカード指定のドメイン ALLOWLIST を FQDN 単位に絞り込めるかを検証しました。


今回やりたいこと

今回のゴールは、次のような運用が現実的に回せるかを確かめることです。

  1. まずは ALLOWLIST をワイルドカードで粗く許可する
  2. 実通信ログの event.tls.sni から、実際に使われた FQDN を洗い出す
  3. その結果をもとに、ALLOWLIST をより具体的な FQDN 単位に絞る

つまり、最初から正解のドメインリストを作るのではなく、 実際に流れたTLS通信を観測しながらSNIで許可範囲を狭めていく ことが今回の主題です。


検証構成

今回検証した構成は以下です。

VPC
 ├ IGW
 ├ firewall subnet
 │   └ AWS Network Firewall
 ├ protected subnet
 │   ├ EC2 (検証用)
 │   └ SSM Interface VPCE
 └ route
     protected → firewall → IGW
     IGW → firewall → protected

protected subnet 上の EC2 からインターネットへ出る通信を、必ず NFW 経由にします。
また、検証用 EC2 には SSM で接続したかったため、ssm / ssmmessages / ec2messages の Interface VPC Endpoint も protected subnet に配置しました。
architecture.drawio.png

使用した主なリソース

要件 リソース
VPC aws_vpc.this (10.2.0.0/16)
IGW aws_internet_gateway.this
firewall subnet aws_subnet.firewall (10.2.2.0/24)
AWS Network Firewall aws_networkfirewall_firewall.this + ドメイン ALLOWLIST
protected subnet aws_subnet.protected (10.2.1.0/24)
EC2(検証用) aws_instance.test(SSM ロール付き)
SSM Interface VPCE ssm / ssmmessages / ec2messages
protected → firewall → IGW aws_route.protected_default_to_nfw aws_route.firewall_default_to_igw
IGW → firewall → protected aws_route.igw_to_protected_via_nfw(IGW edge route)


ルーティングのポイント

今回の構成で一番重要なのは、NFW を作ることそのものより、通信をきちんと NFW に通すルーティングを組むことです。

インターネットへの通信経路は次のようになります。

Internet
IGW
AWS Network Firewall
EC2 (protected subnet)
SSM Interface VPCE
ssm / ssmmessages / ec2messages

NFW を経由させるには、行きと戻りの両方で NFW エンドポイントを通す必要があります。
このため、ルートテーブルは 3 つ用意しました。

ルートテーブル アタッチ先 ルート 役割
protected RT protected subnet 0.0.0.0/0 → NFW Endpoint EC2 からの外向き通信を NFW 経由にする
firewall RT firewall subnet 0.0.0.0/0 → IGW NFW を通過した通信をインターネットへ出す
IGW edge RT IGW(Gateway Route Table) 10.2.1.0/24 → NFW Endpoint インターネットからの戻り通信を NFW 経由で protected subnet に返す

ポイントは以下です。

  • protected subnet 側だけでなく、戻り通信も NFW を通す必要がある
  • そのために、IGW にアタッチする Gateway Route Table を使う
  • 今回は NAT Gateway を置かず、EC2 にパブリック IP を付与したため、Security Group と NFW の両方でインバウンドを意識する必要がある

通信の流れをまとめると、次のようになります。

【アウトバウンド 外向き通信(EC2 → Internet)】
EC2 → protected RT (0.0.0.0/0 → NFW) → NFW → firewall RT (0.0.0.0/0 → IGW) → IGW → Internet
【アウトバウンド 戻り通信(Internet → EC2)】
Internet → IGW → IGW edge RT (10.2.1.0/24 → NFW) → NFW → EC2

NFW ルールグループ構成

今回の狙いは、許可対象の通信について SNI を alert log に残しつつ、マネージドルールで脅威ドメインも先に評価することです。
そのため、ルールグループは以下の順で構成しました。

Priority ルールグループ 動作
10 ALERTLIST(alert tls のみ) SNI を alert log に記録し、次の priority へ進む
20 BotNetCommandAndControlDomainsStrictOrder 既知のボットネット C2 ドメインを drop
30 AbusedLegitMalwareDomainsStrictOrder 侵害された正規ドメイン(マルウェア)を drop
40 MalwareDomainsStrictOrder 既知のマルウェアドメインを drop
50 AbusedLegitBotNetCommandAndControlDomainsStrictOrder 侵害された正規ドメイン(ボットネット)を drop
60 ALLOWLIST(domain list) 許可ドメインを pass
default aws:drop_strict + aws:alert_strict どのルールにもマッチしない通信を drop + alert

この構成にした理由は次の通りです。

  • STRICT_ORDER + stateful_default_actions = ["aws:drop_strict", "aws:alert_strict"] により、ALLOWLIST にマッチしない通信をすべて drop できる
  • ALERTLIST を最初に評価することで、ALLOWLIST に含めた通信でも event.tls.sni を alert log に残せる
  • マネージドルールを ALLOWLIST より先に置くことで、仮に許可対象に含まれるドメインでも、既知の脅威ドメインであれば先にブロックできる

初期の ALLOWLIST

最初は広めに観測するため、以下のワイルドカードドメインを許可しました。

variable "allow_domains" {
  default = [
    ".amazonaws.com",
    ".github.com",
    ".docker.io",
    ".docker.com",
    ".cloudflarestorage.com"
  ]
}

検証手順

1. Terraform で構成を作成する

検証用コードは以下のリポジトリに置きました。

https://github.com/Nka700/pub_aws_conf.git

ホストマシンで以下を実行します。

git clone https://github.com/Nka700/pub_aws_conf.git
cd pub_aws_conf/nfw_minimum_configuration/terraform

tfstate 用バケット名を任意のものに変更後、以下を実行します。

terraform -chdir=env/poc init
terraform -chdir=env/poc apply -auto-approve

2. EC2 に SSM 接続する

aws ssm start-session --target ${インスタンスID} --region ap-northeast-1

3. インターネットへの通信を発生させる(Docker Hub)

今回は docker run hello-world を実行し、Docker Hub 関連の通信を発生させました。

sudo dnf install -y docker
sudo systemctl enable --now docker
sudo usermod -aG docker ssm-user
newgrp docker
docker run hello-world

4. Logs Insights で SNI を確認する

NFW の alert log に対して、以下の Logs Insights クエリを実行します。

fields event.tls.sni as sni
| filter event.alert.action = "allowed"
| filter sni != ""
| stats count(*) as hits,
        min(@timestamp) as first_seen,
        max(@timestamp) as last_seen
  by sni
| sort hits desc

このクエリにより、ワイルドカードで許可しているドメインへの通信が、実際にはどの FQDN(SNI)で行われていたかを確認できます。
Screenshot_20260405_195057.png


観測結果をもとに ALLOWLIST を絞る

docker run hello-world の通信を確認したところ、ワイルドカード指定していた .docker.io .cloudflarestorage.com の配下でも、実際に使われていたホスト名はかなり限定的でした。

そこで、ALLOWLIST を以下のように変更しました。

--- a/nfw_minimum_configuration/terraform/env/poc/var.tf
+++ b/nfw_minimum_configuration/terraform/env/poc/var.tf
@@ -49,9 +49,9 @@ variable "allow_domains" {
   default = [
     ".amazonaws.com",
     ".github.com",
-    ".docker.io",
-    ".docker.com",
-    ".cloudflarestorage.com"
+    "registry-1.docker.io",
+    "auth.docker.io",
+    "docker-images-prod.6aa30f8b08e16409b46e0173d6de2f56.r2.cloudflarestorage.com"
   ]
 }

その後、前回取得したイメージとコンテナを削除し、再度 docker run hello-world でインターネットへの通信を発生させて、より狭い ALLOWLIST でも動作することを確認しました。

docker ps --all
docker rm ${前回のhello-worldのコンテナID}
docker image rm hello-world
docker run hello-world

以上で 厳密な FQDN を決め打ちするのではなく、まずは観測し、通信先として使われているSNIで絞っていく 進め方が有効であることを確認できました。


注意点

今回の検証で重要だったのは、 SNI をログに残したいなら pass ではなく alert を先に置く必要がある 点です。

アクション ログ記録 後続ルール評価 結果
alert tls ✅ alert ログ出力 ✅ 次の priority へ進む マネージドルール → ALLOWLIST の順に評価される
pass tls ❌ alert ログ出力されない ❌ そこで評価終了 マネージドルールをバイパスしてしまう

pass を使うと、次のような問題が起こります。

  • ALLOWLIST ドメインへの通信が alert log に記録されず、観測目的を果たせない
  • その場で評価が終了するため、後段のマネージドルールが適用されない

観測しながら許可対象を絞る ことが目的なら、alert tls を最初に置いて、その後にマネージドルールと ALLOWLIST を評価する構成が扱いやすいです。

実際の運用では、以下も考慮が必要です。

  • 通信試験の内容によって観測できる FQDN は変わる
  • CDN やリダイレクトにより、別のホスト名が追加で必要になる場合がある
  • 一度見えた FQDN が常に固定とは限らない

そのため、ALLOWLIST の絞り込みは一回で終わらせず、一定期間ログを観測しながら進めるのが安全です。


まとめ

AWS Network Firewall の最小構成でも、alert log の event.tls.sni を使うことで、実際に通信したドメインをある程度把握できました。
今回の検証を通じて、次のような進め方が現実的だと分かりました。

  1. まずはワイルドカードを含む広めのドメインリストを ALLOWLIST に設定して通信を許可する
  2. alert log から SNI を収集し、実際に使われた FQDN を確認する
  3. その結果をもとに、ALLOWLIST を段階的に具体的な FQDN に絞る

最初から厳密な許可ドメインを設計するのが難しい場合でも、 NFW のログを使って段階的に精度を上げていく ことで、現実的に運用することができそうです。

この記事は私が書きました

kengo.yamashiro

記事一覧

kengo.yamashiro

この記事を共有する

クラウドのご相談

CONTACT

クラウド導入や運用でお悩みの方は、お気軽にご相談ください。
専門家がサポートします。

サービス資料ダウンロード

DOWNLOAD

ビジネスをクラウドで加速させる準備はできていますか?
今すぐサービス資料をダウンロードして、詳細をご確認ください。