AWS Transit Gatewayを使ってAWS Network Firewallを通らないバイパスを作ってみた

バイパスは作れるけど非対称ルーティングに注意しよう
2024.02.09

この通信はAWS Network Firewallを通らせたくない

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

皆さんはAWS Network Firewallを通らないバイパスを用意したいなと思ったことはありますか? 私はあります。

Network Firewall、Gateway Load BalancerにおいてTCPの場合はアイドルタイムアウトが350秒、TCPではない場合はアイドルタイムアウトが120秒で固定で設定されています。

既存のフロー

Gateway Load Balancer は、プロトコルに基づいて既存のフローを処理します。

  • TCP: 350 秒以上アイドル状態の場合、既存のフローは閉じられます。
  • その他のプロトコル: 120 秒以上アイドル状態の場合、既存のフローは閉じられます。

Gateway Load Balancer のターゲットグループ - Elastic Load Balancing

そのため、TCPの350秒以上通信が発生しない場合はTCPのコネクションが切断されます。例えば、実行完了までの時間が350秒以上かかるクエリを叩いた場合は、クエリ結果が正常に返ってこないことが考えられます。

この仕様の対応として一般的なのは、「クライアントまたはサーバー側のOSやミドルウェア、アプリケーションの設定で350秒/120秒のKeepAliveを設定する」ことです。KeepAliveで定期的に通信を行うことで、タイムアウトとなることを避けてネットワークのフローの維持を行います。KeepAliveの設定の詳細は以下AWS Blogをご覧ください。

ただし、設定対象のクライアントやサーバー、アプリケーションが多い場合は運用が回らないことが考えられます。そのような場合、セキュリティ要件を満たすのであれば、Network FirewallやGateway Load Balancerを通らないバイパスの用意を検討します。

実際にバイパスを作成してみました。

いきなりまとめ

  • AWS Transit Gatewayを使ってAWS Network Firewallを通らないバイパスは作れる
  • Transit Gateway attachmentに接続しているネットワーク内にバイパスしたいものと、したくないものが混在しないことがベスト
    • バイパス対象の送信元からバイパス対象でない送信先に対してリクエストをすると、リクエストだけNetwork Firewallを通る
    • バイパス対象でない送信元からバイパス対象の送信先にリクエストをすると、レスポンスだけNetwork Firewallを通る
    • レスポンスだけNetwork Firewallを通る場合は、レスポンスがNetwork Firewallでドロップされ正常な通信ができない
  • Transit Gateway attachmentに関連付けしているTransit Gateway route tableに対して、バイパスの対向のTransit Gateway attachmentからPropagationし合うのが良い

やってみた

検証環境

検証環境は以下のとおりです。

検証環境構成図

VPC AからVPC Bに通信するときにNetwork Firewallを通るようにしています。いわゆるEast-Westの通信を検査しています。Network Firewallのデプロイモデルは以下AWS Blogをご覧ください。

検証環境はAWS CDKでデプロイしました。使用したコードは以下リポジトリに保存しています。

Network Firewallを経由していることを確認

EC2 Instance A1から各EC2インスタンスに対してICMP、UDP、TCPで通信してみます。

EC2 Instance A1 to EC2 Instance A2

$ ping -c 4 10.1.1.49
PING 10.1.1.49 (10.1.1.49) 56(84) bytes of data.
64 bytes from 10.1.1.49: icmp_seq=1 ttl=127 time=1.09 ms
64 bytes from 10.1.1.49: icmp_seq=2 ttl=127 time=0.683 ms
64 bytes from 10.1.1.49: icmp_seq=3 ttl=127 time=0.651 ms
64 bytes from 10.1.1.49: icmp_seq=4 ttl=127 time=0.881 ms

--- 10.1.1.49 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3077ms
rtt min/avg/max/mdev = 0.651/0.825/1.086/0.174 ms

$ traceroute 10.1.1.49
traceroute to 10.1.1.49 (10.1.1.49), 30 hops max, 60 byte packets
 1  ip-10-1-1-49.ec2.internal (10.1.1.49)  0.684 ms  0.909 ms  0.893 ms

$ curl -I 10.1.1.49
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Thu, 08 Feb 2024 07:58:49 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Fri, 13 Oct 2023 13:33:26 GMT
Connection: keep-alive
ETag: "65294726-267"
Accept-Ranges: bytes

EC2 Instance A1 to EC2 Instance B1

$ ping -c 4 10.1.2.11
PING 10.1.2.11 (10.1.2.11) 56(84) bytes of data.
64 bytes from 10.1.2.11: icmp_seq=1 ttl=123 time=4.12 ms
64 bytes from 10.1.2.11: icmp_seq=2 ttl=123 time=1.99 ms
64 bytes from 10.1.2.11: icmp_seq=3 ttl=123 time=2.01 ms
64 bytes from 10.1.2.11: icmp_seq=4 ttl=123 time=2.02 ms

--- 10.1.2.11 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3003ms
rtt min/avg/max/mdev = 1.987/2.533/4.122/0.917 ms

$ traceroute 10.1.2.11
traceroute to 10.1.2.11 (10.1.2.11), 30 hops max, 60 byte packets
 1  * * *
 2  * * *
 3  * * *
 4  * * *
 5  ip-10-1-2-11.ec2.internal (10.1.2.11)  3.848 ms  4.650 ms  3.817 ms

$ curl -I 10.1.2.11
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Thu, 08 Feb 2024 07:59:26 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Fri, 13 Oct 2023 13:33:26 GMT
Connection: keep-alive
ETag: "65294726-267"
Accept-Ranges: bytes

EC2 Instance A1 to EC2 Instance B2

$ ping -c 4 10.1.2.43
PING 10.1.2.43 (10.1.2.43) 56(84) bytes of data.
64 bytes from 10.1.2.43: icmp_seq=1 ttl=123 time=5.52 ms
64 bytes from 10.1.2.43: icmp_seq=2 ttl=123 time=2.27 ms
64 bytes from 10.1.2.43: icmp_seq=3 ttl=123 time=2.32 ms
64 bytes from 10.1.2.43: icmp_seq=4 ttl=123 time=2.48 ms

--- 10.1.2.43 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 2.266/3.145/5.518/1.371 ms

$ traceroute 10.1.2.43
traceroute to 10.1.2.43 (10.1.2.43), 30 hops max, 60 byte packets
 1  * * *
 2  * * *
 3  * * *
 4  * * *
 5  ip-10-1-2-43.ec2.internal (10.1.2.43)  4.265 ms  4.604 ms  3.590 ms

$ curl -I 10.1.2.43
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Thu, 08 Feb 2024 07:59:55 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Fri, 13 Oct 2023 13:33:26 GMT
Connection: keep-alive
ETag: "65294726-267"
Accept-Ranges: bytes

いずれも問題なく通信できました。また、その他のEC2インスタンスでも相互に通信できました。

また、Network Firewallでは全ての通信をアラートとしてログ記録するようにしています。以下のようにログが記録されていました。

ICMP

{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1b",
    "event_timestamp": "1707377659",
    "event": {
        "icmp_type": 8,
        "src_ip": "10.1.1.8",
        "src_port": 0,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 1398185865822070,
        "dest_ip": "10.1.2.11",
        "proto": "ICMP",
        "icmp_code": 0,
        "dest_port": 0,
        "timestamp": "2024-02-08T07:34:19.545803+0000"
    }
}
{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1b",
    "event_timestamp": "1707377659",
    "event": {
        "icmp_type": 0,
        "src_ip": "10.1.2.11",
        "src_port": 0,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 1398185865822070,
        "dest_ip": "10.1.1.8",
        "proto": "ICMP",
        "icmp_code": 0,
        "dest_port": 0,
        "timestamp": "2024-02-08T07:34:19.546775+0000"
    }
}

UDP

{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1a",
    "event_timestamp": "1707377748",
    "event": {
        "src_ip": "10.1.1.8",
        "src_port": 53478,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 1917597743633708,
        "dest_ip": "10.1.2.11",
        "proto": "UDP",
        "app_proto": "failed",
        "dest_port": 33444,
        "timestamp": "2024-02-08T07:35:48.775468+0000"
    }
}

TCP (HTTP)

{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1b",
    "event_timestamp": "1707379166",
    "event": {
        "src_ip": "10.1.1.8",
        "src_port": 40020,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 1211367774098826,
        "dest_ip": "10.1.2.11",
        "proto": "TCP",
        "dest_port": 80,
        "timestamp": "2024-02-08T07:59:26.529802+0000"
    }
}
{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1b",
    "event_timestamp": "1707379166",
    "event": {
        "src_ip": "10.1.2.11",
        "src_port": 80,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 1211367774098826,
        "dest_ip": "10.1.1.8",
        "proto": "TCP",
        "dest_port": 40020,
        "timestamp": "2024-02-08T07:59:26.532518+0000"
    }
}
{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1b",
    "event_timestamp": "1707379166",
    "event": {
        "src_ip": "10.1.1.8",
        "src_port": 40020,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 1211367774098826,
        "dest_ip": "10.1.2.11",
        "proto": "TCP",
        "dest_port": 80,
        "timestamp": "2024-02-08T07:59:26.534200+0000"
    }
}
{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1b",
    "event_timestamp": "1707379166",
    "event": {
        "app_proto": "http",
        "src_ip": "10.1.1.8",
        "src_port": 40020,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 1211367774098826,
        "dest_ip": "10.1.2.11",
        "proto": "TCP",
        "http": {
            "hostname": "10.1.2.11",
            "url": "/",
            "http_user_agent": "curl/8.5.0",
            "http_method": "HEAD",
            "protocol": "HTTP/1.1",
            "length": 0
        },
        "dest_port": 80,
        "timestamp": "2024-02-08T07:59:26.534247+0000"
    }
}
{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1b",
    "event_timestamp": "1707379166",
    "event": {
        "app_proto": "http",
        "src_ip": "10.1.2.11",
        "src_port": 80,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 1211367774098826,
        "dest_ip": "10.1.1.8",
        "proto": "TCP",
        "http": {
            "hostname": "10.1.2.11",
            "url": "/",
            "http_user_agent": "curl/8.5.0",
            "http_method": "HEAD",
            "protocol": "HTTP/1.1",
            "length": 0
        },
        "dest_port": 40020,
        "timestamp": "2024-02-08T07:59:26.535338+0000"
    }
}
{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1b",
    "event_timestamp": "1707379166",
    "event": {
        "app_proto": "http",
        "src_ip": "10.1.2.11",
        "src_port": 80,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 1211367774098826,
        "dest_ip": "10.1.1.8",
        "proto": "TCP",
        "http": {
            "hostname": "10.1.2.11",
            "url": "/",
            "http_user_agent": "curl/8.5.0",
            "http_content_type": "text/html",
            "http_method": "HEAD",
            "protocol": "HTTP/1.1",
            "status": 200,
            "length": 0
        },
        "dest_port": 40020,
        "timestamp": "2024-02-08T07:59:26.535494+0000"
    }
}
{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1b",
    "event_timestamp": "1707379166",
    "event": {
        "app_proto": "http",
        "src_ip": "10.1.1.8",
        "src_port": 40020,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 1211367774098826,
        "dest_ip": "10.1.2.11",
        "proto": "TCP",
        "http": {},
        "dest_port": 80,
        "timestamp": "2024-02-08T07:59:26.536535+0000"
    }
}
{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1b",
    "event_timestamp": "1707379166",
    "event": {
        "app_proto": "http",
        "src_ip": "10.1.1.8",
        "src_port": 40020,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 1211367774098826,
        "dest_ip": "10.1.2.11",
        "proto": "TCP",
        "http": {},
        "dest_port": 80,
        "timestamp": "2024-02-08T07:59:26.536721+0000"
    }
}
{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1b",
    "event_timestamp": "1707379166",
    "event": {
        "app_proto": "http",
        "src_ip": "10.1.2.11",
        "src_port": 80,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 1211367774098826,
        "dest_ip": "10.1.1.8",
        "proto": "TCP",
        "http": {},
        "dest_port": 40020,
        "timestamp": "2024-02-08T07:59:26.537724+0000"
    }
}
{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1b",
    "event_timestamp": "1707379166",
    "event": {
        "app_proto": "http",
        "src_ip": "10.1.1.8",
        "src_port": 40020,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 1211367774098826,
        "dest_ip": "10.1.2.11",
        "proto": "TCP",
        "http": {},
        "dest_port": 80,
        "timestamp": "2024-02-08T07:59:26.538730+0000"
    }
}

バイパスの作成

バイパスを作成します。

EC2 Instance A1 と EC2 Instance B1の通信はNetwork Firewallを通らないようにTransit Gateway route tableを変更します。VPC内のルートテーブルを変更する必要はありません。

具体的には以下を行なっています。

  • VPC AのTransit Gateway attachmentを関連づけているTransit Gateway route tableにて、EC2 Instance B1のIPアドレス(10.1.2.11/32)への通信はVPC BのTransit Gateway attachmentに転送するルートを追加
  • VPC BのTransit Gateway attachmentを関連づけているTransit Gateway route tableにて、EC2 Instance A1のIPアドレス(10.1.1.8/32)への通信はVPC BのTransit Gateway attachmentに転送するルートを追加

図示すると以下のとおりです。

バイパス追加後の検証環境構成図

EC2 Instance A1 と EC2 Instance B1 間の通信

実際に通信してみましょう。

まずは、EC2 Instance A1 から EC2 Instance B1 への通信です。図で表すと以下のようになります。

バイパス追加後のA1-to-B1

通信結果は以下のとおりです。

EC2 Instance A1 to EC2 Instance B1

$ ping -c 1 10.1.2.11
PING 10.1.2.11 (10.1.2.11) 56(84) bytes of data.
64 bytes from 10.1.2.11: icmp_seq=1 ttl=126 time=1.29 ms

--- 10.1.2.11 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.286/1.286/1.286/0.000 ms

$ traceroute 10.1.2.11
traceroute to 10.1.2.11 (10.1.2.11), 30 hops max, 60 byte packets
 1  * * *
 2  * ip-10-1-2-11.ec2.internal (10.1.2.11)  0.891 ms *

$ curl -I 10.1.2.11
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Thu, 08 Feb 2024 08:12:42 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Fri, 13 Oct 2023 13:33:26 GMT
Connection: keep-alive
ETag: "65294726-267"
Accept-Ranges: bytes

問題なく通信できました。Network Firewallのメトリクスやアラートログを確認しましたが、通信をした時間帯に記録されたものはありませんでした。そのため、Network Firewallを経由せずに通信できていることが分かります。

また、tracerouteの実行結果からNetwork Firewallを通らない場合は、ホップ数が減っていることも分かります。

同様にEC2 Instance B1 から EC2 Instance A1 への通信もしてみます。

EC2 Instance B1 to EC2 Instance A1

$ ping -c 1 10.1.1.8
PING 10.1.1.8 (10.1.1.8) 56(84) bytes of data.
64 bytes from 10.1.1.8: icmp_seq=1 ttl=126 time=1.02 ms

--- 10.1.1.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.015/1.015/1.015/0.000 ms

$ traceroute 10.1.1.8
traceroute to 10.1.1.8 (10.1.1.8), 30 hops max, 60 byte packets
 1  * * *
 2  ip-10-1-1-8.ec2.internal (10.1.1.8)  0.823 ms  0.841 ms  0.826 ms

$ curl -I 10.1.1.8
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Thu, 08 Feb 2024 08:13:27 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Fri, 13 Oct 2023 13:33:26 GMT
Connection: keep-alive
ETag: "65294726-267"
Accept-Ranges: bytes

こちらも問題なく通信できました。メトリクスやアラートログからもNetwork Firewallを経由していないことを確認できました。

EC2 Instance A1 から EC2 Instance B2 への通信

それでは、EC2 Instance A1 から EC2 Instance B2 への通信はどうでしょうか。この通信は以下のようにリクエストはNetwork Firewallを通りますが、レスポンスはNetwork Firewallを通りません。図に表すと以下のようになります。

バイパス追加後のA1-to-B2

実際に試してみます。

EC2 Instance A1 to EC2 Instance B2

$ ping -c 1 10.1.2.43
PING 10.1.2.43 (10.1.2.43) 56(84) bytes of data.
64 bytes from 10.1.2.43: icmp_seq=1 ttl=126 time=2.59 ms

--- 10.1.2.43 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 2.594/2.594/2.594/0.000 ms

$ traceroute 10.1.2.43
traceroute to 10.1.2.43 (10.1.2.43), 30 hops max, 60 byte packets
 1  * * *
 2  * * *
 3  * * *
 4  * * *
 5  ip-10-1-2-43.ec2.internal (10.1.2.43)  2.155 ms  2.068 ms  2.175 ms

$ curl -I 10.1.2.43
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Thu, 08 Feb 2024 08:28:24 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Fri, 13 Oct 2023 13:33:26 GMT
Connection: keep-alive
ETag: "65294726-267"
Accept-Ranges: bytes

はい、問題なく通信できました。

アラートログを確認してみます。

ICMP

{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1b",
    "event_timestamp": "1707380890",
    "event": {
        "icmp_type": 8,
        "src_ip": "10.1.1.8",
        "src_port": 0,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 1155563377051454,
        "dest_ip": "10.1.2.43",
        "proto": "ICMP",
        "icmp_code": 0,
        "dest_port": 0,
        "timestamp": "2024-02-08T08:28:10.837438+0000"
    }
}

UDP

{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1a",
    "event_timestamp": "1707380897",
    "event": {
        "src_ip": "10.1.1.8",
        "src_port": 47489,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 1449772932204489,
        "dest_ip": "10.1.2.43",
        "proto": "UDP",
        "app_proto": "failed",
        "dest_port": 33442,
        "timestamp": "2024-02-08T08:28:17.722889+0000"
    }
}

TCP (HTTP)

{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1a",
    "event_timestamp": "1707380904",
    "event": {
        "src_ip": "10.1.1.8",
        "src_port": 48224,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 409566213368430,
        "dest_ip": "10.1.2.43",
        "proto": "TCP",
        "dest_port": 80,
        "timestamp": "2024-02-08T08:28:24.584302+0000"
    }
}
{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1a",
    "event_timestamp": "1707380904",
    "event": {
        "src_ip": "10.1.1.8",
        "src_port": 48224,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 409566213368430,
        "dest_ip": "10.1.2.43",
        "proto": "TCP",
        "dest_port": 80,
        "timestamp": "2024-02-08T08:28:24.586211+0000"
    }
}
{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1a",
    "event_timestamp": "1707380904",
    "event": {
        "src_ip": "10.1.1.8",
        "src_port": 48224,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 409566213368430,
        "dest_ip": "10.1.2.43",
        "proto": "TCP",
        "dest_port": 80,
        "timestamp": "2024-02-08T08:28:24.586258+0000"
    }
}
{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1a",
    "event_timestamp": "1707380904",
    "event": {
        "src_ip": "10.1.1.8",
        "src_port": 48224,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 409566213368430,
        "dest_ip": "10.1.2.43",
        "proto": "TCP",
        "dest_port": 80,
        "timestamp": "2024-02-08T08:28:24.587868+0000"
    }
}
{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1a",
    "event_timestamp": "1707380904",
    "event": {
        "src_ip": "10.1.1.8",
        "src_port": 48224,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 409566213368430,
        "dest_ip": "10.1.2.43",
        "proto": "TCP",
        "dest_port": 80,
        "timestamp": "2024-02-08T08:28:24.588006+0000"
    }
}
{
    "firewall_name": "network-firewall",
    "availability_zone": "us-east-1a",
    "event_timestamp": "1707380904",
    "event": {
        "src_ip": "10.1.1.8",
        "src_port": 48224,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_strict action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 409566213368430,
        "dest_ip": "10.1.2.43",
        "proto": "TCP",
        "dest_port": 80,
        "timestamp": "2024-02-08T08:28:24.589312+0000"
    }
}

送信元がEC2 Instance A1で、送信先がEC2 Instance B2のものしか記録されていませんでした。つまりはレスポンスの通信はNetwork Firewallを通っていないようです。

Network Firewallのメトリクスは以下のとおりです。

A1-to-B2_合計

EC2 Instance A2 から EC2 Instance B1 への通信

次にEC2 Instance A2 から EC2 Instance B1 への通信を試してみます。

こちらは以下のようにリクエストはNetwork Firewallを通りませんが、レスポンスはNetwork Firewallを通ります。図に表すと以下のようになります。

バイパス追加後のA2-to-B1

Network Firewallは非対称ルーティングに対応していません。レスポンスの通信がリクエストの通信と同じFirewall Endpointにルーティングされない場合はドロップします。

Network Firewall doesn’t support asymmetric routing. In Network Firewall, asymmetric routing occurs when both request network traffic and its related response network traffic are not routed to the same Network Firewall endpoint. In order for Network Firewall to properly process traffic, the traffic must be routed to the Network Firewall endpoint in both directions.

Considerations for asymmetric routing - AWS Network Firewall

今回のケースでは、そもそもリクエストがNetwork Firewallを通っていません。そのため、レスポンスの通信でドロップすると予想します。

実際に試してみます。

EC2 Instance A2 to EC2 Instance B1

$ ping -c 1 10.1.2.11
PING 10.1.2.11 (10.1.2.11) 56(84) bytes of data.

--- 10.1.2.11 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

$ traceroute 10.1.2.11
traceroute to 10.1.2.11 (10.1.2.11), 30 hops max, 60 byte packets
 1  * * *
 2  * * *
 3  * * *
 4  * * *
 5  * * *
 6  * * *
 7  * * *
 8  * * *
 9  * * *
10  * * *
11  * * *
12  * * *
13  * * *
14  * * *
15  * * *
16  * * *
17  * * *
18  * * *
19  * * *
20  * * *
21  * * *
22  * * *
23  * * *
24  * * *
25  * * *
26  * * *
27  * * *
28  * * *
29  * * *
30  * * *

$ curl -v -m 5 10.1.2.11
*   Trying 10.1.2.11:80...
* Connection timed out after 5003 milliseconds
* Closing connection
curl: (28) Connection timed out after 5003 milliseconds

いずれのパターンも通信できませんでした。やはり、レスポンスの通信がNetwork Firewallでドロップされていると考えます。

ちなみに、対象の時間帯のNetwork Firewallのアラートログに記録された通信はありませんでした。また、メトリクスにも以下のように記録されていませんでした。

A2-to-B1_合計

バイパスは作れるけど非対称ルーティングに注意しよう

AWS Transit Gatewayを使ってAWS Network Firewallを通らないバイパスを作ってみました。

Transit Gatewayでルートテーブルを変更するだけで簡単にバイパスは作れます。

ただし、Transit Gateway attachmentに接続しているネットワーク内にバイパスしたいものと、したくないものが混在しないことがベストです。

Transit Gateway attachmentに関連付けしているTransit Gateway route tableに対して、バイパスの対向のTransit Gateway attachmentからPropagationし合うのが良いでしょう。

もし、Transit Gateway attachmentに接続しているネットワーク内にバイパスしたいものと、したくないものが混在している場合は非対称ルーティングが発生し、Network Firewallを通ってしまう可能性があります。また、レスポンスだけNetwork Firewallを通るという通信はできません。これを加味してTransit Gatewayのルーティングを設計すると良いと考えます。

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

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