🔥

AWS Network Firewall を NAT Gateway の前に配置して、NAT される前にトラフィックを検査する

2021/10/19に公開
5

はじめに

今まで EC2 Instance -> AWS Network Firewall -> NAT Gateway -> Internet Gateway といった構成は VPC の Local ルートよりも詳細なルート情報を書けないといった VPC のルーティングの制約上できませんでしたが、先日 VPC の Local ルートよりも詳細なルート情報を書けるようになりました。
https://aws.amazon.com/jp/blogs/news/inspect-subnet-to-subnet-traffic-with-amazon-vpc-more-specific-routing/

上記のアップデートにより、AWS Network Firewall も恩恵を受けて、上述のルーティングが可能となりました。
とりあえず、やってみましょう。

1. VPC を用意する

既に用意してる方はこのセクションは飛ばして頂いて OK です。
まず VPC を作りますが、今回はシンプルにシングルアベイラビリティゾーンな構成で作成しています。

VPC CIDR : 10.60.0.0/16
Firewall Subnet : 10.60.10.0/24
NAT Gateway Subnet : 10.60.20.0/24
Private Subnet(EC2 インスタンスを配置する予定): 10.60.30.0/24

上記の通りサブネットまで用意したら、ルートテーブルの作成に…と行きたい所ですが、そもそもルートテーブルで AWS Network Firewall が作成する VPC Endpoint へのルートを記載しないといけないので、先に AWS Network Firewall を作成します。

Firewall を作り終えたら、ルートテーブル……ではなくて、先に Internet Gateway を作成して、当該 VPC にアタッチしましょう。その後に NAT Gateway を当該 VPC の NAT Gateway Subnet に作成します。
ここで微妙に手こずったり、詰まったりするので、忘れずに。

ここまで作成できたら、ルートテーブルをそれぞれのサブネット用に作成します。
今回はサブネット 3 つで構成してますので、ルートテーブルも 3 つ作成しましょう。

上記で作成した 3 つのルートテーブルに、それぞれ作成したサブネットを 1 つずつ関連付けます。
私の場合は下記のように作りました。(そのまんまですけどね)

FW-RTB : Firewall Subnet 10.60.10.0/24 に関連付け
NATGW-RTB : NAT Gateway Subnet 10.60.20.0/24 に関連付け
Private-RTB : Private Subnet 10.60.30.0/24 に関連付け

2. ルートテーブルを設定する

セクション分ける必要あるのか? と書いてる途中で思いましたが、もう書いちゃったのでそのままにします。

関連付けた後、下記のようにルートテーブルを設定していきます。
こういう時、(個人的には)通信方向に沿って設定していくと、混乱せずに設定できる気がしているので、まずは Private-RTB から設定していきます。

Private-RTB

EC2 インスタンスからの通信は全て AWS Network Firewall に検査してもらいたいので、Private-RTB では下記の設定を行います。

送信先 ターゲット
0.0.0.0/0 vpce-xxxxxxxxxxxx

全ての通信(0.0.0.0/0) を AWS Network Firewall が作成した VPC Endpoint に向けています。

FW-RTB

AWS Network Firewall にて検査されたトラフィックはその後 NAT Gateway を抜けてインターネットへと抜けていって欲しいので、下記のように設定します。

送信先 ターゲット
0.0.0.0/0 nat-xxxxxxxxxxxx

NATGW-RTB

NAT Gateway に到着したトラフィックはインターネットに抜けていってほしいのと、戻り通信を AWS Network Firewall に返さないといけないので、下記のように設定します。

送信先 ターゲット
0.0.0.0/0 igw-xxxxxxxxxxxx
10.60.30.0/24(Private Subnet) vpce-xxxxxxxxxxxx

これでルートテーブルの設定は完了です。
「あれ? VPC Ingress Routing は?」と思った方、今までだいぶ AWS Network Firewall と戯れてきたのではないでしょうか。

今回 NAT Gateway が存在するサブネットを関連付けたルートテーブルで、より詳細なルートを書けるようになった事で、Internet Gateway にルートテーブルを関連付けて、戻り通信を記載しなくてもよくなりました。
なので、Internet Gateway 用のルートテーブル、VPC Ingress Routing をしない構成となった、という事ですね。

今回(ちょっと面倒だったので)図を省略してますが、この記事読みながらお手元で構成を起こして頂くとより理解しやすくなるかもしれませんので、おすすめです。

最後に

後は AWS Systems Manager の権限を適切に IAM Role 等に付与しつつ EC2 インスタンスに割り当て、Private Subnet に起動しましょう。
AWS Systems Manager のセッションマネージャー経由でアクセスして、疎通確認して頂ければと思います。この時点でセッションマネージャーから見えない等といった問題がある場合、EC2 インスタンスがインターネットに出れていない事が多いです。
先程作成した AWS Network Firewall のステートレス・ステートフルルールグループで通信を遮断していないか、デフォルトアクション等に引っかかって通信を遮断していないか、確認してみてください。

Discussion

カイリーーカイリーー

私も現在AWS Network Firewallの部分を学んでいて、色々な資料を見てもわからなかったのでご質問させてください。

NATGW-RTB
NAT Gateway に到着したトラフィックはインターネットに抜けていってほしいのと、戻り通信を AWS Network Firewall に返さないといけないので、下記のように設定します。

上記ですが、NAT Gatewayに対して戻りの通信をNetwork Firewallに返さないといけない理由がよくわかっておりません。
NAT Gatewayは基本的に出ていく通信だけ許可すればいいものと思っていたのですが、もしこの点についてお分かりになればご教示いただきたいです。

nbxvxbnbxvxb

コメントありがとうございます。
私なりの解釈を書きますが、正しい回答はAWSに聞く事をおすすめします☝

NAT Gateway は通信を NAT するので、NAT Gateway が行き戻りをどこに送ればいいか承知済みです。ということで、おっしゃる通り、一般的には行き戻りの通信経路を考慮する必要はありません。
しかしながら、今回は下記のような経路ですよね。

行き:
EC2 -> Network Firewall -> NAT Gateway -> Internet Gateway -> Internet

では NAT Gateway があるルートテーブルで何も記述しなかった場合、どうやって通信が戻るでしょう。
Network Firewall は通信を NAT するわけでもなく、終端もしないので、パケット上では EC2 の IP アドレスが送信元となっているはずです。
となると、下記のように NAT Gateway は EC2 にダイレクトに通信を戻す事になってしまいます。

戻り:
Internet -> Internet Gateway -> NAT Gateway -> EC2

こうなってしまうと、行きと戻りが非対称の経路になってしまいます。
Network Firewall では非対称経路をサポートしていないので、この経路だと予期せぬ動作を引き起こします(通信検査できなかったりなどなど)
資料 : https://docs.aws.amazon.com/ja_jp/network-firewall/latest/developerguide/asymmetric-routing.html

なので、対称の経路にするには、NAT Gateway があるルートテーブルで、Network Firewall の VPC エンドポイントに対して明示的にルート情報を書いて、通信を戻してあげる必要がある、ということです。

こんな感じでわかります…かね?🤔

カイリーーカイリーー

こちら早々にご返信いただきありがとうございます🙇‍♂️
NAT Gatewayも「ルーターの役割をしている」と考えると腑に落ちました。

また、こちらはFirewallのルールを「ステートレスだけ」で設定した場合に限りますよね?🤔
「ステートレス」の場合、EC2からの行きの通信に対して、戻りの通信を返してやらないといけないので、
行き: EC2 -> Firewall -> NAT Gateway -> IGW -> Internet
戻り: Internet -> NAT Gateway (ここできた通信をどこに返すんだっけ?を明示的にFirewallを経由してEC2に返してねのルーティングをする) -> Firewall -> EC2 (ぁ、送った通信に対して返信がきたと認識する)
「ステートフルだけ」で設定した場合は戻りの通信を許容する必要はないので不要なのかなと思いました。

nbxvxbnbxvxb

ファイアウォール内部のルール検査とルートテーブルの動きは関係無いですよー。
ファイアウォールでステートフルルールを使っていたとしても、ファイアウォールまでパケットが戻らないと何の意味もありません。
というか、ステートフルを使っていても、ルートテーブルで通信を戻さなければ、ファイアウォールに到達できません。