[アップデート] AWS Network FirewallとAWS Transit Gatewayを関連付けて簡単に通信の検査をできるようになりました

[アップデート] AWS Network FirewallとAWS Transit Gatewayを関連付けて簡単に通信の検査をできるようになりました

管理リソースとルーティングで考えることが少し減った
Clock Icon2025.06.17

AWS Network Fiweallを配置するInspection VPCを用意するの面倒だな

こんにちは、のんピ(@non____97)です。

皆さんはAWS Network Fiweallを配置するInspection VPCを用意するの面倒だなと思ったことはありますか? 私はあります。

VPC間の通信を検査する場合、以下AWS公式ブログで紹介されている「1) East-Westトラフィック検査モデル」のようにInspection VPCを用意する形になります。

https://aws.amazon.com/jp/blogs/news/networking-and-content-delivery-deployment-models-for-aws-network-firewall/

私の過去ブログ記事でも以下のような構成を組みました。

cc8ee5cd36ecc94b9f8034ba83652497-2048x1142.png (2048×1142)

見て分かるように、なかなか複雑です。メンテナンスするのも一苦労します。

今回アップデートで、AWS Network FirewallとAWS Transit Gatewayを関連付けて簡単に通信の検査をできるようになりました

https://aws.amazon.com/jp/about-aws/whats-new/2025/06/aws-network-firewall-transit-gateway-native-integration/

これによってNetwork Fiweallを配置するInspection VPCを用意する必要がなくなりました。構成図的にかなりスッキリですね。

実際に試してみたので、紹介します。

いきなりまとめ

  • AWS Network FirewallとAWS Transit Gatewayを関連付けて簡単に通信の検査をできるようになった
  • 関連付けをするとNetwork FirewallのTransit Gatewayアタッチメントが作成される
  • 作成されたNetwork FirewallのTransit Gatewayアタッチメントにルーティングをすることで検査をする
    • 一度Network FirewallのTransit Gatewayアタッチメントにルーティングをするため、VPC間で直接通信をする場合と比べて通信に対する課金は2倍かかる想定
  • Network Firewallと関連付けるTransit Gatewayは別AWSアカウントでも良い
    • RAMで共有する

注意点

利用時の注意点は以下のとおりです。

  • Transit Gatewayの所有者とNetwork Firewallの所有者が異なるAWSアカウントの場合:
    • Network Firewallアカウントの所有者は、Transit Gatewayの所有者がTransit Gatewayを共有してもらう必要がある
    • Network Firewallアカウントの所有者は、Network Firewall Pollicyで使用されるデフォルト値とは異なるHOME_NETを使用するようにルールグループを設定する必要がある
    • Network Firewallの所有者もTransit Gatewayの所有者もTransit Gatewayに接続されたNetwork Firewallを削除できる
    • Transit Gatewayの所有者は、Network Firewallの詳細を確認できない
    • Transit Gatewayは関連するTransit Gatewayに接続されたNetwork Firewallを含む、すべてのTransit Gatewayアタッチメントを削除するまで、共有Transit Gatewayを削除できない
  • Transit Gatewayに接続されたNetwork Firewallは、共有Transit Gatewayが既に有効になっているのと同じAZで設定する必要がある
  • Transit Gatewayに接続されたNetwork Firewallのトラフィックは、VPCルートテーブルではなく、Transit Gatewayルートテーブルを通じてルーティングする必要がある
  • Transit Gatewayに接続されたNetwork Firewallでは、アプライアンスモードが常に有効になっている

参考 : Considerations for transit gateway-attached firewalls - AWS Network Firewall

RAMで共有されたTransit Gatewayに対してもNetwork Firewallを接続できるのは嬉しいですね。

とはいえ、この通信はNetwork Firewallにルーティングする/しないはTransit Gatewayルートテーブルで管理する形だと思うので、個人的にはTransit GatewayとNetwork Firewallは同一アカウントで管理するのがスムーズだとは思います。

料金

この機能を使うにあたって追加料金は不要です。

Transit Gateway、Network Firewallの料金ページを確認しましたが、いずれもこの機能についての言及はありませんでした。

https://aws.amazon.com/transit-gateway/pricing/?nc1=h_ls

https://aws.amazon.com/network-firewall/pricing/?nc1=h_ls

リージョン

2025/6/17時点で使用できるリージョンは以下の5リージョンです。

  • ケープタウン
  • ハイデラバード
  • ストックホルム
  • チューリッヒ
  • UAE

東京リージョンはまだなので期待して待ちましょう。

やってみた

検証環境

それでは実際にやってみましょう。検証環境は以下のとおりです。

[アップデート] AWS Network FirewallとAWS Transit Gatewayを関連付けて簡単に通信の検査をできるようになりました.png

VPC A → VPC Bに対して通信を行い、それがNetwork Firewallを通っていることを確認します。

Network Firewall以外は作成している状態です。Transit Gatewayルートテーブルは以下のようになっています。

1.Transit Gatewayルートテーブル.png

Network Firewallの作成

Network Firewallを作成します。

名前を入力します。

2.ファイアウォールの説明 .png

アタッチメントタイプについて設定します。

ここが新しい設定です。

3.アタッチメントタイプ.png

事前に用意しておいたTransit GatewayとFirewall EndpointをデプロイしたいAZを指定します。

続いて詳細設定です。ログ出力先のCloudWatch Logsやダッシュボードの設定をします。

4.詳細設定を行う.png

続いて、ファイアウォールポリシーの関連付けです。空のものを関連付けます。

5.ファイアウォールポリシーを関連付ける .png

確認して、Network Firewallを作成します。

6.確認して作成.png

準備完了になりました。

7.準備完了.png

VPC A → VPC Bの通信

それでは、VPC A → VPC Bの通信を行なってみます。

pingを叩きます。

sh-5.2$ ping 10.1.16.66 -c 4
PING 10.1.16.66 (10.1.16.66) 56(84) bytes of data.
64 bytes from 10.1.16.66: icmp_seq=1 ttl=126 time=2.71 ms
64 bytes from 10.1.16.66: icmp_seq=2 ttl=126 time=1.30 ms
64 bytes from 10.1.16.66: icmp_seq=3 ttl=126 time=1.25 ms
64 bytes from 10.1.16.66: icmp_seq=4 ttl=126 time=1.32 ms

--- 10.1.16.66 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 1.251/1.644/2.707/0.614 ms

問題なくできましたね。

ただし、メトリクスを見ても何も流れていないように見えます。

8.pingとHTTP通信をしてもモニタリングされない.png

VPC BのEC2インスタンスにnginxをインストールして、HTTPでアクセスします。

VPC BのEC2インスタンスにnginxをインストール
sh-5.2$ sudo dnf install nginx
Amazon Linux 2023 Kernel Livepatch repository                  157 kB/s |  17 kB     00:00
Dependencies resolved.
===============================================================================================
 Package                   Architecture Version                        Repository         Size
===============================================================================================
Installing:
 nginx                     x86_64       1:1.26.3-1.amzn2023.0.1        amazonlinux        33 k
Installing dependencies:
 generic-logos-httpd       noarch       18.0.0-12.amzn2023.0.3         amazonlinux        19 k
 gperftools-libs           x86_64       2.9.1-1.amzn2023.0.3           amazonlinux       308 k
 libunwind                 x86_64       1.4.0-5.amzn2023.0.2           amazonlinux        66 k
 nginx-core                x86_64       1:1.26.3-1.amzn2023.0.1        amazonlinux       670 k
 nginx-filesystem          noarch       1:1.26.3-1.amzn2023.0.1        amazonlinux       9.6 k
 nginx-mimetypes           noarch       2.1.49-3.amzn2023.0.3          amazonlinux        21 k

Transaction Summary
===============================================================================================
Install  7 Packages

Total download size: 1.1 M
Installed size: 3.6 M
Is this ok [y/N]: y
Downloading Packages:
(1/7): generic-logos-httpd-18.0.0-12.amzn2023.0.3.noarch.rpm   543 kB/s |  19 kB     00:00
.
.
(中略)
.
.

Installed:
  generic-logos-httpd-18.0.0-12.amzn2023.0.3.noarch
  gperftools-libs-2.9.1-1.amzn2023.0.3.x86_64
  libunwind-1.4.0-5.amzn2023.0.2.x86_64
  nginx-1:1.26.3-1.amzn2023.0.1.x86_64
  nginx-core-1:1.26.3-1.amzn2023.0.1.x86_64
  nginx-filesystem-1:1.26.3-1.amzn2023.0.1.noarch
  nginx-mimetypes-2.1.49-3.amzn2023.0.3.noarch

Complete!

sh-5.2$ sudo systemctl enable nginx --now
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.

sh-5.2$ systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: disabled)
     Active: active (running) since Tue 2025-06-17 00:35:24 UTC; 7s ago
    Process: 24021 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
    Process: 24077 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
    Process: 24106 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
   Main PID: 24129 (nginx)
      Tasks: 3 (limit: 1057)
     Memory: 3.2M
        CPU: 53ms
     CGroup: /system.slice/nginx.service
             ├─24129 "nginx: master process /usr/sbin/nginx"
             ├─24134 "nginx: worker process"
             └─24135 "nginx: worker process"
sh-5.2$ curl -I http://10.1.16.66
HTTP/1.1 200 OK
Server: nginx/1.26.3
Date: Tue, 17 Jun 2025 00:36:13 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 11 Feb 2025 02:00:47 GMT
Connection: keep-alive
ETag: "67aaaf4f-267"
Accept-Ranges: bytes

200 OKが返ってきましたね。

しかし、変わらずメトリクスとしては記録されていませんでした。

VPC A → VPC BのIPレベルで通信をドロップするようなルールを追加しました。

10.アンマネージドルールグループを追加.png

13.これでも異なるAZ間の通信は検出できない.png

しかし、変わらずメトリクスとしては記録されていませんでした。Network Firewallのフローログも出力されていません。

Transit Gatewayルートテーブルの修正

Transit Gatewayアタッチメントを見ていると、リソースタイプがNetwork FunctionのTransit Gatewayアタッチメントが作成されていました。

11.Network FunctionのTransit Gatewayアタッチメントが作成されていた.png

現状、Transit GatewayルートテーブルにはこのTransit Gatewayアタッチメントへのルートはありません。

12.ルートは設定されていない.png

もしかすると、Network Firewallへの明示的なルートが必要なのでしょうか。

以下のようにTransit Gatewayルートテーブルを設定してみます。

検証環境構成図.png

ファイアウォールルールグループのルールは以下のとおりです。

14.現在のルールグループ.png

この状態で通信してみましょう。

sh-5.2$ ping 10.1.16.66 -c 4
PING 10.1.16.66 (10.1.16.66) 56(84) bytes of data.
64 bytes from 10.1.16.66: icmp_seq=1 ttl=123 time=4.66 ms
64 bytes from 10.1.16.66: icmp_seq=2 ttl=123 time=1.89 ms
64 bytes from 10.1.16.66: icmp_seq=3 ttl=123 time=1.84 ms
64 bytes from 10.1.16.66: icmp_seq=4 ttl=123 time=1.83 ms

--- 10.1.16.66 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 1.827/2.554/4.658/1.214 ms

sh-5.2$ curl -I http://10.1.16.66
HTTP/1.1 200 OK
Server: nginx/1.26.3
Date: Tue, 17 Jun 2025 09:53:46 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 11 Feb 2025 02:00:47 GMT
Connection: keep-alive
ETag: "67aaaf4f-267"
Accept-Ranges: bytes

フローログに以下が記録されていました。

{
    "firewall_name": "non-97-nfw",
    "availability_zone": "eu-north-1a",
    "event_timestamp": "1750154088",
    "event": {
        "tcp": {
            "tcp_flags": "1b",
            "syn": true,
            "fin": true,
            "psh": true,
            "ack": true
        },
        "app_proto": "http",
        "src_ip": "10.0.7.160",
        "src_port": 57606,
        "netflow": {
            "pkts": 6,
            "bytes": 394,
            "start": "2025-06-17T09:53:46.757499+0000",
            "end": "2025-06-17T09:53:46.765272+0000",
            "age": 0,
            "min_ttl": 125,
            "max_ttl": 125,
            "state": "closed",
            "reason": "timeout",
            "alerted": false
        },
        "event_type": "netflow",
        "flow_id": 720160452845270,
        "dest_ip": "10.1.16.66",
        "proto": "TCP",
        "dest_port": 80,
        "timestamp": "2025-06-17T09:54:48.233302+0000"
    }
}
{
    "firewall_name": "non-97-nfw",
    "availability_zone": "eu-north-1a",
    "event_timestamp": "1750154088",
    "event": {
        "tcp": {
            "tcp_flags": "1b",
            "syn": true,
            "fin": true,
            "psh": true,
            "ack": true
        },
        "app_proto": "http",
        "src_ip": "10.1.16.66",
        "src_port": 80,
        "netflow": {
            "pkts": 4,
            "bytes": 454,
            "start": "2025-06-17T09:53:46.757499+0000",
            "end": "2025-06-17T09:53:46.765272+0000",
            "age": 0,
            "min_ttl": 125,
            "max_ttl": 125
        },
        "event_type": "netflow",
        "flow_id": 720160452845270,
        "dest_ip": "10.0.7.160",
        "proto": "TCP",
        "dest_port": 57606,
        "timestamp": "2025-06-17T09:54:48.233427+0000"
    }
}
{
    "firewall_name": "non-97-nfw",
    "availability_zone": "eu-north-1a",
    "event_timestamp": "1750154138",
    "event": {
        "src_ip": "10.0.7.160",
        "icmp_type": 8,
        "netflow": {
            "pkts": 4,
            "bytes": 336,
            "start": "2025-06-17T09:53:33.679509+0000",
            "end": "2025-06-17T09:53:36.684818+0000",
            "age": 3,
            "min_ttl": 125,
            "max_ttl": 125,
            "state": "established",
            "reason": "timeout",
            "alerted": false
        },
        "event_type": "netflow",
        "flow_id": 1511097740599632,
        "dest_ip": "10.1.16.66",
        "proto": "ICMP",
        "icmp_code": 0,
        "app_proto": "unknown",
        "timestamp": "2025-06-17T09:55:38.788301+0000"
    }
}
{
    "firewall_name": "non-97-nfw",
    "availability_zone": "eu-north-1a",
    "event_timestamp": "1750154138",
    "event": {
        "src_ip": "10.1.16.66",
        "icmp_type": 0,
        "netflow": {
            "pkts": 4,
            "bytes": 336,
            "start": "2025-06-17T09:53:33.679509+0000",
            "end": "2025-06-17T09:53:36.684818+0000",
            "age": 3,
            "min_ttl": 125,
            "max_ttl": 125
        },
        "event_type": "netflow",
        "flow_id": 1511097740599632,
        "dest_ip": "10.0.7.160",
        "proto": "ICMP",
        "icmp_code": 0,
        "app_proto": "unknown",
        "timestamp": "2025-06-17T09:55:38.788406+0000"
    }
}

pingとHTTPの行きと戻りの通信がそれぞれ記録されていることが分かりますね。

ダッシュボードでも記録されています。

15ダッシュボード.png

ということで、作成されたNetwork FirewallのTransit Gatewayアタッチメントにルーティングをすることで検査をすることが分かりました。ただし、一度Network FirewallのTransit Gatewayアタッチメントにルーティングをするため、VPC間で直接通信をする場合と比べて通信に対する課金は2倍かかると予想します。

マネージドルールグループの追加

せっかくなのでマネージドルールグループの追加をします。

ThreatSignaturesWebAttacksStrictOrderを追加しました。

18.ThreatSignaturesExploitsStrictOrderを追加.png

この中の以下ルールグループにある以下ルールにマッチするようなリクエストを投げます。

drop http any any -> $HOME_NET any (msg:"DLink DNS/DNR 320 save_ajax.php AFU HTTP Request";flow:established,to_server;http.method;content:"POST";http.uri;content:"/web/function/save_ajax.php";content:"folder=";reference:url,www.search-lab.hu/media/D-Link_Security_advisory_3_0_public.pdf;classtype:attempted-admin;sid:2811244;rev:3;metadata:created_at 2015_06_04,signature_severity Major,updated_at 2020_05_22;)

HOME_NETを認識できるように、値を指定します。

17.HOME_NET 変数のオーバーライド値.png

リクエストを投げます。

$ curl \
  http://10.1.16.66/web/function/save_ajax.php?folder=param \
  -X POST \
  -m 5
curl: (28) Operation timed out after 5002 milliseconds with 0 bytes received

はい、タイムアウトになりました。

ログを見ると、意図したシグネチャーでドロップしていることが分かります。

{
    "firewall_name": "non-97-nfw",
    "availability_zone": "eu-north-1b",
    "event_timestamp": "1750157929",
    "event": {
        "tx_id": 0,
        "app_proto": "http",
        "src_ip": "10.0.7.160",
        "src_port": 50850,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2811244,
            "rev": 3,
            "metadata": {
                "created_at": [
                    "2015_06_04"
                ],
                "signature_severity": [
                    "Major"
                ],
                "updated_at": [
                    "2020_05_22"
                ]
            },
            "signature": "DLink DNS/DNR 320 save_ajax.php AFU HTTP Request",
            "action": "blocked",
            "category": ""
        },
        "flow_id": 437067361225469,
        "dest_ip": "10.1.16.66",
        "proto": "TCP",
        "verdict": {
            "action": "drop"
        },
        "http": {
            "hostname": "10.1.16.66",
            "url": "/web/function/save_ajax.php?folder=param",
            "http_user_agent": "curl/8.5.0",
            "http_method": "POST",
            "protocol": "HTTP/1.1",
            "length": 0
        },
        "dest_port": 80,
        "pkt_src": "geneve encapsulation",
        "timestamp": "2025-06-17T10:58:49.759667+0000",
        "direction": "to_server"
    }
}
{
    "firewall_name": "non-97-nfw",
    "availability_zone": "eu-north-1b",
    "event_timestamp": "1750157929",
    "event": {
        "tx_guessed": true,
        "tx_id": 0,
        "app_proto": "http",
        "src_ip": "10.0.7.160",
        "src_port": 50850,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 4,
            "rev": 0,
            "signature": "aws:alert_established action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 437067361225469,
        "dest_ip": "10.1.16.66",
        "proto": "TCP",
        "verdict": {
            "action": "drop"
        },
        "http": {
            "hostname": "10.1.16.66",
            "url": "/web/function/save_ajax.php?folder=param",
            "http_user_agent": "curl/8.5.0",
            "http_method": "POST",
            "protocol": "HTTP/1.1",
            "length": 0
        },
        "dest_port": 80,
        "pkt_src": "geneve encapsulation",
        "timestamp": "2025-06-17T10:58:49.759667+0000",
        "direction": "to_server"
    }
}

ダッシュボードでは以下のようになっていました。ドロップされていることが一目瞭然ですね。

19.検証後のトラフィック概要.png

管理リソースとルーティングで考えることが少し減った

AWS Network FirewallとAWS Transit Gatewayを関連付けて簡単に通信の検査をできるようになったアップデートを紹介しました。

管理リソースとルーティングで考えることが少し減った嬉しいアップデートですね。

今後Network Firewallを導入する場合は、基本的にはこの仕組みを使うことになりそうです。

この記事が誰かの助けになれば幸いです。

以上、クラウド事業本部 コンサルティング部の のんピ(@non____97)でした!

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.