AWS Network Firewallを試してみた
IT技術
はじめに
今回はAWSサービスのNetwork Firewallについて触れていこうと思います。
Network Firewallは、ネットワークトラフィックを細かく制御するためのファイアウォールルールを設定できるサービスです。通常、AWSでトラフィックを制御する際にはセキュリティグループやWAFを使用しますが、FQDNを用いたトラフィック制御やより詳細な制御が必要な場合、Network Firewallが適しています。公式サイトでのユースケースは、このように紹介されています。
- インバウンドのインターネットトラフィックを検査
- アウトバウンドトラフィックをフィルタリングする
- インバウンドのインターネットトラフィックの侵入を防ぐ
- AWS Direct Connect と VPN のトラフィックを保護する
AWS Network Firewallの特徴
Network Firewallの主な特徴です。
ステートフルおよびステートレスのルールエンジン
- ステートフルルールエンジン: このエンジンはネットワークトラフィックのパターンを把握し、過去のトラフィックとの関連性を認識します。例えば、あるウェブサイトと安全に接続が確立された後にのみ、情報の送受信を許可するようなルールを作ることができるということです。
- ステートレスルールエンジン: こちらは各ネットワークパケットを個別に評価し、アクセスの許可や拒否を決定します。このタイプのルールは迅速で、IPアドレスやポート番号に基づいたフィルタリングに主に用いられます。こちらは特定のアドレスからのデータのみを受け入れるようなシンプルなルールに使用されます。
フルマネージド型のサービス
- スケーラビリティ: AWS Network Firewallはフルマネージド型のサービスなので、ネットワークトラフィックの増減に応じて自動的にスケールアップ・ダウンします。このため、ユーザーはインフラストラクチャのスケーリングについて心配する必要がありません。
- メンテナンスフリー: セキュリティの更新やパフォーマンスの向上に関する作業はAWSによって自動的に行われるのでメンテナンス作業に時間を割く必要がないです。
ネットワーク構成
AWS Network Firewallを導入する際、まず注意しなければならないのは、そのネットワーク構成が通常のものとは異なる点です!
Network Firewallのエンドポイントはサブネットに作成する必要があります。
通常のInternet Gateway 経由で利用する際の基本構成(Multi-AZ 構成)はこんな感じですよね。
Network Firewallを設置する場合は、下記のようにルーティングする必要があります。
新しい構成では、Firewall Subnet(ファイアウォール専用のサブネット)にエンドポイントを配置し、このエンドポイントをインターネットゲートウェイに接続します。
インターネットからの返信トラフィックは、インターネットゲートウェイに設定されたルーティングテーブルを経由して、ファイヤーウォールのElastic Network Interface(ENI)に送り返されます。
公式ドキュメントによると AWS Network Firewall を紐づけた(エンドポイントを作成した)サブネットごとに料金が発生するので注意が必要です。
この金額については後ほど詳しく説明しますが結構高いです。。。
今回は個人で検証するだけなのでシングルAZで進めていきます。
Network Firewallの基本構成要素
Network Firewallには3つの構成要素があります。
作成前に理解しておいた方が良いのでざっくり解説した後にそれぞれを実際に設定していきます。
Firewall(ファイアウォール本体)
Network Firewallの核となる部分です。サブネット内にFirewallエンドポイントが作成され、ネットワークのパケットがこのエンドポイントを通過するようになります。
Firewall Policy(ファイアウォールポリシー)
Rule Groupの集合体であり、特定のFirewallに適用されるポリシーです。
同じFirewall Policyを複数のFirewallに適用することが可能です。
Rule Group(ルールグループ)
Stateless Rule GroupとStateful Rule Groupの2種類があります。
複数の Rule group を Firewall policy と紐づけて利用します。
複数のRule GroupをFirewall Policyに紐付けて使用します。各Rule Group内では複数のルールを設定でき、トラフィックの制御を細かく行うことが可能です。
それではコンソール画面から順番に作成していきます!
Terraformでの構築する際のコードも一緒に記載します。
Rule Groupの作成
今回はStateful rule groupでドメイン名でトラフィックを許可するルールを作成します。
ステートフルルールグループで、ドメインリストを指定します。
ルール評価の順序は、厳密な順序にします。
厳密な順序を指定することで各ルールに優先度を決定して、優先度に従ってルールが評価されます。
適当に名前をつけて、キャパシティーを決定します。
このキャパシティは後から変更することができないので余裕を持って設定しましょう。
キャパシティの詳しい計算方法は省略しますが、ドメインリストの場合は下記で計算できます。
1キャパシティ = ( ドメイン数 + 1 ) * プロトコル数
今回はテストなので50くらいで設定します。
キャパシティの上限は30000となっています。
指定したドメインの通信を許可します。
yahooとgoogleのドメインを登録しておきます。
これでrule groupの作成完了です。
1## firewall rule groupの作成
2locals {
3 firewall_allow_fqdn_list = [
4 ".google.com",
5 ".yahoo.com",
6 ]
7}
8
9resource "aws_networkfirewall_rule_group" "fqdn" {
10 name = "test-rule-group"
11 description = "FQDN for allowing traffic"
12 capacity = 100
13 type = "STATEFUL"
14 rule_group {
15 rules_source {
16 rules_source_list {
17 generated_rules_type = "ALLOWLIST"
18 target_types = ["TLS_SNI", "HTTP_HOST"]
19 targets = [for fqdn in local.firewall_allow_fqdn_list : fqdn]
20 }
21 }
22}
Firewall policyの作成
Firewall policyを作成していきます。
AWS Network Firewall を通る通信は図のように、まず設定してあるステート レス ルールグループで評価されます。
ステートレスルールグループは設定した優先度の順に上から評価されていき、どれかのルールに一致すると、それ以降のルールは評価されません。
どのルールにも合致しなかった場合は、デフォルトアクションが適用されます。
今回は、特定のドメインで通信を許可したいので青矢印のポリシーを作成します。
引用元:https://docs.aws.amazon.com/network-firewall/latest/developerguide/firewall-rules-engines.html
適当に名前をつけます。
ストリーム例外ポリシーは、ネットワークの接続が途中で中断した際に、どのようにトラフィックを処理するかを指定するポリシーです。
ドロップや拒否のポリシーはセキュリティを強化しますが、一方で通信の品質が低下する可能性があります。
逆に、続行するポリシーは通信の途切れを最小限に抑えることができますが、セキュリティリスクが高まる可能性があります。
今回はドロップを選択します。
オプションでステートフルルールグループに転送を選択して、先ほど作成したルールグループを追加します。
これでfirewall policyの作成完了です。
1## firewall policyの作成
2resource "aws_networkfirewall_firewall_policy" "default" {
3 name = "test-firewall-policy"
4 firewall_policy {
5 stateless_default_actions = ["aws:forward_to_sfe"]
6 stateless_fragment_default_actions = ["aws:forward_to_sfe"]
7 stateful_rule_group_reference {
8 resource_arn = aws_networkfirewall_rule_group.fqdn.arn
9 }
10 }
11}
Network Firewall の作成
適当な名前をつけて次へ
VPCとFirewall Endpointを設置するSubnetを選択します。
KMSは今回は使用しません。
削除保護をつけて次へ
先ほど作成したfirewll policyを選択します。
これで作成完了です。
1
2## Network firewallの作成
3resource "aws_networkfirewall_firewall" "default" {
4 name = "test-firewall"
5 vpc_id = aws_vpc.default.id
6 delete_protection = true
7 subnet_change_protection = true
8 firewall_policy_arn = aws_networkfirewall_firewall_policy.default.arn
9 subnet_mapping {
10 subnet_id = aws_subnet.firewall.id
11 }
12}
ルーティングの設定追加
通常のルーティング箇所は省略しますが、Ingress Route Table の作成が少し難しかったので軽く解説します。
インターネット側から入ってくる通信も、Network Firewall を経由するルーティングを設定する必要があります。
NAT Gateway が稼働している Public Subnet 宛の通信を、Network Firewall の Endpoint に指定します。
先ほどの画像のこの部分です。
ルートテーブルを作成します。
public subnetからのターゲットをfirewall endpointに指定します。
Edgeの関連付けを編集でinternet gatewayを選択します。
terraform で記述する際の注意点は、firewall endpoint_idはかなり深い階層に存在します。
生成された VPC エンドポイントの情報は
の set の中に一つずつ入っています。firewall_status[0].sync_states
1
2resource "aws_route_table" "ingress_route_table" {
3 vpc_id = aws_vpc.default.id
4 route {
5 cidr_block = local.subnet.public
6 vpc_endpoint_id = tolist(aws_networkfirewall_firewall.default.firewall_status[0].sync_states)[0].attachment[0].endpoint_id
7 }
8 tags = {
9 Name = "test-ingress-route-table"
10 }
11}
12
13resource "aws_route_table_association" "ingress_route_table" {
14 gateway_id = aws_internet_gateway.default.id
15 route_table_id = aws_route_table.ingress_route_table.id
16}
動作確認
設定が完了したので、Network Firewallが期待通りに機能しているかを確認していきます。
特定ドメインへのアクセス確認
Private Subnetに配置されたEC2インスタンスから許可したドメインにHTTPリクエストを送ります。
今回はgoogle.comとyahoo.comです。
両方のドメインからHTTPステータスコード「200」が返ってきました。
期待通りの結果です。
1[ec2-user@ip-10-1-0-245 ~]$ curl -v https://www.google.com/ 2>&1 | grep '< HTTP/'
2< HTTP/2 200
3[ec2-user@ip-10-1-0-245 ~]$ curl -v https://www.yahoo.com/ 2>&1 | grep '< HTTP/'
4< HTTP/2 200
許可されていないドメインへのアクセス確認
許可していないドメインと通信が遮断されているか確認します。
EC2インスタンスからのHTTPリクエストに対するレスポンスは返ってこないはずです。
youtube.comにリクエストしてもレスポンスが返ってきませんね。
1[ec2-user@ip-10-1-0-245 ~]$ curl -v http://www.youtube.com
2* Trying 172.217.31.174:80...
3* Connected to www.youtube.com (172.217.31.174) port 80
4> GET / HTTP/1.1
5> Host: www.youtube.com
6> User-Agent: curl/8.3.0
7> Accept: */*
8>
Firewall Subnetからのアクセス確認
Firewall SubnetにEC2を作成してyoutube.comにHTTPリクエストを送るとどうなるでしょう?
1[ec2-user@ip-10-1-2-11 .ssh]$ curl -v https://www.youtube.com/ 2>&1 | grep '< HTTP/'
2< HTTP/2 200
HTTPステータスコード「200」が返ってきました。
Firewall Subnetからエンドポイントを通らずにインターネットゲートウェイにトラフィックが流れているからです。
つまり、Firewallはエンドポイント配下のリソースに適用されるということです。
Cloud Watchでログ確認
Cloud Watchでログを確認するために設定を追加します。
Cloud Watchロググループを作成してALERTとFLOWのログをfirewallの変更画面からログ記録を設定します。
Cloud Watchのログを見てみると、youtube.comへのアクセスがNetwork Firewall によっってブロックされていることが分かります。actionがblockedになっていて、hostname にリクエストヘッダーに含まれるドメインが記録されています。
1
2{
3 "firewall_name": "test-firewall",
4 "availability_zone": "ap-northeast-1a",
5 "event_timestamp": "1699774612",
6 "event": {
7 "tx_id": 0,
8 "app_proto": "http",
9 "src_ip": "10.1.0.245",
10 "src_port": 54898,
11 "event_type": "alert",
12 "alert": {
13 "severity": 1,
14 "signature_id": 3,
15 "rev": 1,
16 "signature": "not matching any HTTP allowlisted FQDNs",
17 "action": "blocked",
18 "category": ""
19 },
20 "flow_id": 229950411303581,
21 "dest_ip": "172.217.175.238",
22 "proto": "TCP",
23 "http": {
24 "hostname": "www.youtube.com",
25 "url": "/",
26 "http_user_agent": "curl/8.3.0",
27 "http_method": "GET",
28 "protocol": "HTTP/1.1",
29 "length": 0
30 },
31 "dest_port": 80,
32 "timestamp": "2023-11-12T07:36:52.652134+0000"
33 }
34}
Network Firewallの料金
引用元:https://aws.amazon.com/jp/network-firewall/pricing/
前半部分で少し触れましたが、Network Firewallの料金は1つのアベイラビリティゾーン(AZ)ごとに発生します。
例として、アジアリージョンで3つのAZにVPCエンドポイントを作成した場合の1ヶ月の運用料金を計算してみましょう。
1つのNetwork Firewallエンドポイントは1時間あたり0.395USDのコストがかかります。
そのため、1日のコストは以下のようになります。
0.395 USD/時間 × 24時間 = 9.48 USD/日
この金額に3つのAZを乗じると、1ヶ月の合計コストは次のようになります。
9.48 USD/日 × 3AZ × 30日 = 853.2 USD/月(約127,800円/月)
なかなか高いですね。
個人で試す場合は、必要ない時は忘れずに削除するようにしましょう。
消し忘れてたら死にます。
まとめ
今回、AWSサービスの一つであるNetwork Firewallに焦点を当ててみました。個人での利用機会は少ないかもしれませんが、WAFやセキュリティグループでは制御できないトラフィックを制御できるため、非常に便利なツールです。今回は取り上げませんでしたが、Suricata互換性ルールを使用すれば、さらに細かいトラフィック制御が可能になります。
今後もAWSサービスに関するさまざまな情報をブログで共有していきたいと思います。
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ
あだっちー(エンジニア)
8月から入社しました。安達です。 前職ではメカ設計・生産技術の業務をしておりました。 趣味はスノボとキャンプです! 日々邁進して参りますのでよろしくお願いいたします!
おすすめ記事
ライトコードの営業マンって何してるの?〜高橋さん編〜
広告メディア事業部
2024.05.08
日常
移転したライトコード大阪オフィスを調査せよ!
広告メディア事業部
2024.04.03
日常
【GCP】BIG QUERYを触り程度に理解してみる
かねまさ(エンジニア)
2024.04.02
IT技術
【Android】Github ActionsでFirebase Test Labの実行を分散する
笹川(エンジニア)
2024.04.02
IT技術
【Next.js】App Router で使用できるキャッシュまとめ
モーリー(エンジニア)
2024.03.29
IT技術