AWS Network Firewall + NAT Gateway + ALBの構成を構築する際に、次の構成図でVPC外部からのネットワークトラフィックをどのようにALBからFirewall Endpointへ到達させ、またルールグループに基づいて検知させるか?について色々と調べて検証したため、その内容についてアウトプットいたします。
※本構成で使用されるVPC CIDR範囲やIPアドレスは検証用として使用しているものです。
構成図
この構成ではVPC外部からのトラフィックをALB -> Firewall Endpointを経由して、Network Firewallにて設定したルールに基づいて、トラフィックを検査し、パスもしくはドロップする構成となっております。
VPC内部 (EC2)からVPC外へ出ていく通信に関しては検査の対象外としています。
※注意点
本構成図はシングルAZでの図となっておりますが、ALBの仕様上、複数AZに配置させる必要があります。
そのため、本構成を作成する場合には厳密には「PublicSubnetは各AZに作成し、各AZに作成されたPublicSubnet双方対して構成図で示しているルートテーブルを設定する」必要があります。
はじめ、私は片方のPublicSubnet (リソースを何も配置していない方)にFirewall Endpointを経由するルートテーブルを設定しなかったため、Firewall Endpointを飛び越えてEC2にトラフィックが到達してしまってどうやってもファイアウォールのブロックが働かなくて沼にはまりました。
今回のポイント
この構成を構築する際の最も重要なポイントは以下の通りです。
- Network Firewallのステートフルデフォルトアクションはドロップしない設定
- ルートテーブルの設計
- EC2のセキュリティグループの設定
- ALBのターゲットタイプの設定
上記の設定をしっかりと行わないと、VPC外部からのトラフィックをInternet Gateway -> ALB -> Firewall Endpoint ->EC2という経路をたどってトラフィックを流すことができません。
Network Firewallのステートフルデフォルトアクション
ステートレスルールのデフォルトアクションは「ステートフルルールへ転送」としています。
その上でステートフルルールのデフォルトアクションについては「なし」を設定し、ブラックリスト方式で検証します。
ブラックリスト方式にして、一旦すべての通信が問題なくファイアウォールを経由させ、後続のEC2に到達できることを確認した上でdenyルールを適用したときに通信が意図したようにブロックされるかを確認したいためです。
ルートテーブルの設計
次にルートテーブルの設計です。
MSR(More Specific Routing)というアップデートのおかげで、従来VPC CIDR範囲でしか設定できなかったルートテーブルの設定が、VPC CIDR範囲よりも詳細な範囲である、サブネットCIDR範囲のルートを設定できるようになったため、以下のようなルーティングの設定ができるようになりました。
この設定例では、EC2が配置されているサブネットのCIDR範囲を送信先とし、ターゲットにFirewall Endpointを設定することで、Firewall Endpointを経由してEC2に行ってね、のルーティングとなっています。
また、このルーティングをすることで、TLSの終端をALBまでとすることで、通信の内容が暗号化されていないトラフィックをFirewall Endpointへ流すことが可能になりNetwork Firewallで通信の中身を見ることができます。(厳密にはAWS Network FirewallにおいてもTLSインスペクション設定をすることで暗号化された通信と復号化したうえで検査することは可能ですが、今回は上記構成を中心に解説するため詳細は割愛します)
Network Firewall側で復号化 -> 検査 -> 暗号化 -> ALBへトラフィックを流す、という構成はレイテンシーに影響が発生する懸念があります。
EC2の配置されたPrivateSubnetのルーティングの設定は下図のように設定が必要です。
送信先 | ターゲット |
10.0.0.0/21 | local |
0.0.0.0/0 | Firewall Endpoint |
EC2のセキュリティグループの設定
EC2のセキュリティグループについてはFirewall SubnetのCIDR範囲からアクセスを許可するインバウンド許可が必要になります。
Reachability Analyzerを使用して気づいた内容なのですがFirewall Endpoint -> EC2のルートの到達ができないことを確認し、EC2のセキュリティグループのインバウンドルールにFirewall SubnetのCIDR範囲からのアクセスを許可するようにすることで、ルートの到達確認もできました。
ALBターゲットタイプの設定
今回の構成を構築する際に、AWS DIVE DEEPの以下資料には
ELBのターゲットタイプとしてIPの指定が必要
と記載があります。
クリックして20220929_22th_ISV_DiveDeepSeminar_Amazon-Network-Firewall.pdfにアクセス
この構成では、ALB -> EC2へのターゲットのインスタンスIDを指定して登録するのではなく、IPアドレスを指定して登録する必要があります。
これでヘルスチェックを確認し、問題なく”Helthy”になっていればルーティングの設定は完了です。
検証してみる
実際にallowルールとdenyルールを作成して、トラフィックが通過してalertログが取れるか、トラフィックをブロックしてdropログが取れるかを確認します。
詳細なルールは以下
firewall-rule-allow
プロトコル | 送信元 | 送信先 | 送信元ポート | 送信先ポート | 方向 | アクション | キーワード |
TCP | ANY | PrivateSubnet CIDR範囲 | ANY | 80 | 転送 | アラート | sid: 1 |
TCP | ANY | PrivateSubnet CIDR範囲 | ANY | 80 | 転送 | パス | sid: 2 |
上記のルールの詳細をお話いたしますとネットワークファイアウォールのログ分析でセキュリティを向上に記載があるのですが、パスのルールにマッチした通信がアラートログに記録されないため、先にパスルールの前にアラートルールを設定することで、”allowd”のログが記録されるようになります。
firewall-rule-deny
プロトコル | 送信元 | 送信先 | 送信元ポート | 送信先ポート | 方向 | アクション | キーワード |
TCP | ANY | PrivateSubnet CIDR範囲 | ANY | 80 | 転送 | ドロップ | sid: 1 |
ルールが空の状態の挙動
ステートフルルールのデフォルトアクションはパスするように設定しているため(デフォルトアクションのチェックボックスは何も選択sない)EC2への通信は問題なくリクエスト ⇔ レスポンスが返ってきます。
allowルール
allowのルールを適用します。
ALBのDNS名でアクセスし、これも問題なくアクセスできることが確認できます。
CloudWatch Logsに”allowed”のログが記録されました。
※ALBを使用している本構成では、外部からのトラフィックがALBに到達するとALBのIPアドレスに変わってしまうため、正確に外部IPアドレスを特定することができません。
denyルール
次にdenyルールを適用してみます。
ALBのヘルスチェックを確認すると”Unhelthy”になりました。
ALBのDNS名でアクセスすると、504エラーでEC2へ到達することができなくなり、タイプアウトとなりました。
CloudWatch Logsに”blocked”が記録されました。
※こちらも同様に、外部からのトラフィックがALBに到達するとALBのIPアドレスに変わってしまうため、正確に外部IPアドレスを特定することができません。
AWS Network Firewallを使用した検証は以上となります。
今回は検証のため最小構成かつバックエンドをEC2の構成で実施しましたが、これがEKSコンテナにした場合にALBのターゲットタイプをIPアドレスにした場合にPodのIPアドレスは動的に変更になる想定なので、トラフィックを問題なく流せるのかどうか?が少し課題があります。
その点は改めて検証できた際にアウトプット出来たらと思っております。