[アップデート] AWS Network Firewall が VPC プレフィックスリストのサポートをしました
Network Firewall でマネージドプレフィックスリスト使いたいな
こんにちは、のんピ(@non____97)です。
皆さんは Network Firewall でマネージドプレフィックスリスト使いたいなと思ったことはありますか? 私はあります。
Network Firewall のルールで複数の IP アドレスを定義したい場合は、IP セット変数を使うのが便利です。
ただし、IP セット変数はルールグループ単位で設定する必要があります。複数のルールグループで共通のネットワークアドレスを指定したい場合は各ルールグループで IP セット変数を定義する必要があります。
それではルールグループが大量にある場合は管理が大変です。
そんな折、AWS Network Firewall が VPC プレフィックスリストのサポートをしました。
Network Firewall がマネージドプレフィックリストをサポートしたことにより、マネージドプレフィックリストに登録しているIPアドレスを変更すれば複数のルールグループでIPアドレスが更新されるようになります。
それぞれ変更する必要がなくなるので、これは便利です。
早速試してみたので紹介します。
いきなりまとめ
- Network Firewall のルールグループからマネージドプレフィックスリストを参照できる
- IP セット参照はルールグループごとに最大 5 つの IP セット参照を設定できる
- Network Firewall に設定できる IP セット参照は 1,000,000 CIDR 分まで
- 2022/8/19 時点では マネジメントコンソールから AWS マネージドプレフィックスリストは参照できない
- AWS CLI からは指定可能
検証の構成
検証環境は以下の通りです。
Spoke VPC A と Spoke VPC B の EC2 インスタンス間の通信の制御や、外部 IP アドレスへの通信の制御を Network Firewall で行えるように構成します。
そして、検証ではマネージドプレフィックリストに登録されたIPアドレスへの通信は遮断されることを確認します。
検証環境のデプロイ
検証環境は AWS CDK でデプロイします。
使用した AWS CDK のコードは以下リポジトリに保存しています。
npx cdk deploy
でデプロイ後、Spoke VPC A と B の各 EC2 インスタンスの IP アドレスを確認しておきます。
$ aws ec2 describe-instances \ --filters Name=vpc-id,Values=[vpc-0385984d6176c3b6e,vpc-02ada1787d2da440a] \ --query 'Reservations[*].Instances[*].{Name:Tags[?Key==`Name`].Value, VPC:VpcId, Subnet:SubnetId, PrivateIpAddress:NetworkInterfaces[].PrivateIpAddress}' [ [ { "Name": [ "NetworkFirewallStack/Spoke VPC B EC2 Instance 1" ], "VPC": "vpc-02ada1787d2da440a", "Subnet": "subnet-0a421373b0ce71371", "PrivateIpAddress": [ "10.0.3.60" ] } ], [ { "Name": [ "NetworkFirewallStack/Spoke VPC A EC 2Instance 1" ], "VPC": "vpc-0385984d6176c3b6e", "Subnet": "subnet-00ba18c3c45dd6058", "PrivateIpAddress": [ "10.0.2.60" ] } ], [ { "Name": [ "NetworkFirewallStack/Spoke VPC B EC2 Instance 0" ], "VPC": "vpc-02ada1787d2da440a", "Subnet": "subnet-065c61559dc974a04", "PrivateIpAddress": [ "10.0.3.44" ] } ], [ { "Name": [ "NetworkFirewallStack/Spoke VPC A EC 2Instance 0" ], "VPC": "vpc-0385984d6176c3b6e", "Subnet": "subnet-0a8f1bb206482b727", "PrivateIpAddress": [ "10.0.2.36" ] } ] ]
AWS CDK でデプロイしてから 10 分ほど待つと各 EC2 インスタンスに SSM セッションマネージャーで接続できるようになります。SSM セッションマネージャーでSpoke VPC A EC 2Instance 0
に接続して、Spoke VPC B の EC2 インスタンスに ping で疎通確認をします。
# Spoke VPC B EC2 Instance 0 への疎通確認 $ ping 10.0.3.44 -c 5 PING 10.0.3.44 (10.0.3.44) 56(84) bytes of data. 64 bytes from 10.0.3.44: icmp_seq=1 ttl=251 time=4.13 ms 64 bytes from 10.0.3.44: icmp_seq=2 ttl=251 time=1.82 ms 64 bytes from 10.0.3.44: icmp_seq=3 ttl=251 time=1.78 ms 64 bytes from 10.0.3.44: icmp_seq=4 ttl=251 time=1.78 ms 64 bytes from 10.0.3.44: icmp_seq=5 ttl=251 time=1.64 ms --- 10.0.3.44 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4006ms rtt min/avg/max/mdev = 1.648/2.234/4.136/0.953 ms # Spoke VPC B EC2 Instance 1 への疎通確認 $ ping 10.0.3.60 -c 5 PING 10.0.3.60 (10.0.3.60) 56(84) bytes of data. 64 bytes from 10.0.3.60: icmp_seq=1 ttl=251 time=4.40 ms 64 bytes from 10.0.3.60: icmp_seq=2 ttl=251 time=2.03 ms 64 bytes from 10.0.3.60: icmp_seq=3 ttl=251 time=2.07 ms 64 bytes from 10.0.3.60: icmp_seq=4 ttl=251 time=2.09 ms 64 bytes from 10.0.3.60: icmp_seq=5 ttl=251 time=2.07 ms --- 10.0.3.60 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4005ms rtt min/avg/max/mdev = 2.036/2.535/4.403/0.935 ms
Network Firewall のアラートログを確認すると、以下のように VPC 間の ICMP 通信が記録されていました。
# Spoke VPC A EC2 Instance 0 から Spoke VPC B EC2 Instance 0 への Echo Request { "firewall_name": "NetworkFirewall", "availability_zone": "us-east-1a", "event_timestamp": "1660872586", "event": { "timestamp": "2022-08-19T01:29:46.643298+0000", "flow_id": 1386711385559266, "event_type": "alert", "src_ip": "10.0.2.36", "src_port": 0, "dest_ip": "10.0.3.44", "dest_port": 0, "proto": "ICMP", "icmp_type": 8, "icmp_code": 0, "alert": { "action": "allowed", "signature_id": 1000001, "rev": 1, "signature": "icmp alert", "category": "", "severity": 3 } } } # Spoke VPC B EC2 Instance 0 から Spoke VPC A EC2 Instance 0 への Echo Reply { "firewall_name": "NetworkFirewall", "availability_zone": "us-east-1a", "event_timestamp": "1660872586", "event": { "timestamp": "2022-08-19T01:29:46.644819+0000", "flow_id": 1386711385559266, "event_type": "alert", "src_ip": "10.0.3.44", "src_port": 0, "dest_ip": "10.0.2.36", "dest_port": 0, "proto": "ICMP", "icmp_type": 0, "icmp_code": 0, "alert": { "action": "allowed", "signature_id": 1000001, "rev": 1, "signature": "icmp alert", "category": "", "severity": 3 } } } # Spoke VPC A EC2 Instance 0 から Spoke VPC B EC2 Instance 1 への Echo Request { "firewall_name": "NetworkFirewall", "availability_zone": "us-east-1a", "event_timestamp": "1660872514", "event": { "timestamp": "2022-08-19T01:28:34.365379+0000", "flow_id": 1998761400374083, "event_type": "alert", "src_ip": "10.0.2.36", "src_port": 0, "dest_ip": "10.0.3.60", "dest_port": 0, "proto": "ICMP", "icmp_type": 8, "icmp_code": 0, "alert": { "action": "allowed", "signature_id": 1000001, "rev": 1, "signature": "icmp alert", "category": "", "severity": 3 } } } # Spoke VPC B EC2 Instance 1 から Spoke VPC A EC2 Instance 0 への Echo Reply { "firewall_name": "NetworkFirewall", "availability_zone": "us-east-1a", "event_timestamp": "1660872514", "event": { "timestamp": "2022-08-19T01:28:34.367394+0000", "flow_id": 1998761400374083, "event_type": "alert", "src_ip": "10.0.3.60", "src_port": 0, "dest_ip": "10.0.2.36", "dest_port": 0, "proto": "ICMP", "icmp_type": 0, "icmp_code": 0, "alert": { "action": "allowed", "signature_id": 1000001, "rev": 1, "signature": "icmp alert", "category": "", "severity": 3 } } }
ここでSpoke VPC B EC2 Instance 1
に疎通確認できない場合は、Inspection VPC の Transit Gateway attachment でアプライアンスモードが有効になっていない可能性があります。
詳細は以下記事をご覧ください。
マネージドプレフィックリストを使った通信の制御
マネージドプレフィックリストの作成
それではマネージドプレフィックリストの使った通信の制御をしてみます。
まず、AWS CLI で Spoke VPC A と B の CIDR を登録したマネージドプレフィックリストを作成します。
$ aws ec2 create-managed-prefix-list \ --address-family IPv4 \ --max-entries 10 \ --entries Cidr=10.0.2.0/24,Description="Spoke VPC A" Cidr=10.0.3.0/24,Description="Spoke VPC B" \ --prefix-list-name "Spoke VPC" { "PrefixList": { "PrefixListId": "pl-04cc71660eade4c98", "AddressFamily": "IPv4", "State": "create-in-progress", "PrefixListArn": "arn:aws:ec2:us-east-1:<AWSアカウントID>:prefix-list/pl-04cc71660eade4c98", "PrefixListName": "Spoke VPC", "MaxEntries": 10, "Version": 1, "Tags": [], "OwnerId": "<AWSアカウントID>" } }
Network Firewall のルールグループの設定変更
次に Network Firewall のルールグループの設定変更を行います。
Network Firewall のルールグループを選択し、IP セット参照の編集
をクリックします。
IPセット参照を追加
をクリックします。なお、一つのルールグループにつき設定できる IP セット参照は 5 個までです。
IP セット参照変数名と作成したマネージドプレフィックリストを指定します。マネージドプレフィックリストの最大エントリ数を10
にしたので、Network Firewall 全体で IP セット参照で使用できる CIDR の合計数が10 / 1,000,000
となりました。確認をしたら保存
をクリックします。
ここら辺の制限事項については以下 AWS 公式ドキュメントをご覧ください。
ちなみに 2022/8/19 時点では、S3 や CloudFront などの AWS マネージドプレフィックスリストをマネジメントコンソールから選択することはできませんでした。アップデートで対応するのを待ちましょう。
一方、AWS CLI では AWS マネージドプレフィックスリストをIPセット参照に指定ができました。
# マネージドプレフィックスリストの一覧を取得 $ aws ec2 describe-managed-prefix-lists { "PrefixLists": [ { "PrefixListId": "pl-04cc71660eade4c98", "AddressFamily": "IPv4", "State": "modify-complete", "PrefixListArn": "arn:aws:ec2:us-east-1:<AWSアカウントID>:prefix-list/pl-04cc71660eade4c98", "PrefixListName": "Spoke VPC", "MaxEntries": 10, "Version": 2, "Tags": [], "OwnerId": "<AWSアカウントID>" }, { "PrefixListId": "pl-02cd2c6b", "AddressFamily": "IPv4", "State": "create-complete", "PrefixListArn": "arn:aws:ec2:us-east-1:aws:prefix-list/pl-02cd2c6b", "PrefixListName": "com.amazonaws.us-east-1.dynamodb", "Tags": [], "OwnerId": "AWS" }, { "PrefixListId": "pl-0e5696d987d033653", "AddressFamily": "IPv4", "State": "create-complete", "PrefixListArn": "arn:aws:ec2:us-east-1:aws:prefix-list/pl-0e5696d987d033653", "PrefixListName": "com.amazonaws.global.groundstation", "Tags": [], "OwnerId": "AWS" }, { "PrefixListId": "pl-3b927c52", "AddressFamily": "IPv4", "State": "create-complete", "PrefixListArn": "arn:aws:ec2:us-east-1:aws:prefix-list/pl-3b927c52", "PrefixListName": "com.amazonaws.global.cloudfront.origin-facing", "Tags": [], "OwnerId": "AWS" }, { "PrefixListId": "pl-63a5400a", "AddressFamily": "IPv4", "State": "create-complete", "PrefixListArn": "arn:aws:ec2:us-east-1:aws:prefix-list/pl-63a5400a", "PrefixListName": "com.amazonaws.us-east-1.s3", "Tags": [], "OwnerId": "AWS" } ] } # ルールグループの更新に必要なパラメーターを設定 $ ip_set_reference_name=S3 $ ip_set_reference_arn=arn:aws:ec2:us-east-1:aws:prefix-list/pl-63a5400a $ rule_group_arn=arn:aws:network-firewall:us-east-1:<AWSアカウントID>:stateful-rulegroup/icmp $ update_token=$(aws network-firewall describe-rule-group \ --rule-group-arn "$rule_group_arn" \ --query UpdateToken \ --output text ) $ update_rule_group_input=$(cat <<EOM { "RuleGroup": { "ReferenceSets": { "IPSetReferences": { "$ip_set_reference_name": { "ReferenceArn": "$ip_set_reference_arn" } } }, "RulesSource": { "StatefulRules": [ { "Action": "PASS", "Header": { "Protocol": "ICMP", "Source": "10.0.0.0/16", "SourcePort": "Any", "Direction": "ANY", "Destination": "10.0.0.0/16", "DestinationPort": "Any" }, "RuleOptions": [ { "Keyword": "msg:\"icmp alert\"" }, { "Keyword": "sid:1000001" }, { "Keyword": "rev:1" } ] } ] } } } EOM ) # ルールグループの更新 $ aws network-firewall update-rule-group \ --update-token "$update_token" \ --rule-group-arn "$rule_group_arn" \ --cli-input-json "$update_rule_group_input" { "UpdateToken": "2eb503da-89cf-4d45-9fc6-96e1299ef141", "RuleGroupResponse": { "RuleGroupArn": "arn:aws:network-firewall:us-east-1:<AWSアカウントID>:stateful-rulegroup/icmp", "RuleGroupName": "icmp", "RuleGroupId": "a725066f-c6bd-4e89-8889-2675604c9224", "Type": "STATEFUL", "Capacity": 100, "RuleGroupStatus": "ACTIVE", "Tags": [], "ConsumedCapacity": 1, "EncryptionConfiguration": { "KeyId": "AWS_OWNED_KMS_KEY", "Type": "AWS_OWNED_KMS_KEY" }, "LastModifiedTime": "2022-08-24T00:48:03.988000+00:00" } } # AWS マネージドプレフィックスリストをIPセット参照に追加できていることを確認 $ aws network-firewall describe-rule-group \ --rule-group-arn "$rule_group_arn" { "UpdateToken": "2eb503da-89cf-4d45-9fc6-96e1299ef141", "RuleGroup": { "ReferenceSets": { "IPSetReferences": { "S3": { "ReferenceArn": "arn:aws:ec2:us-east-1:aws:prefix-list/pl-63a5400a" } } }, "RulesSource": { "StatefulRules": [ { "Action": "PASS", "Header": { "Protocol": "ICMP", "Source": "10.0.0.0/16", "SourcePort": "Any", "Direction": "ANY", "Destination": "10.0.0.0/16", "DestinationPort": "Any" }, "RuleOptions": [ { "Keyword": "msg:\"icmp alert\"" }, { "Keyword": "sid:1000001" }, { "Keyword": "rev:1" } ] } ] } }, "RuleGroupResponse": { "RuleGroupArn": "arn:aws:network-firewall:us-east-1:<AWSアカウントID>:stateful-rulegroup/icmp", "RuleGroupName": "icmp", "RuleGroupId": "a725066f-c6bd-4e89-8889-2675604c9224", "Type": "STATEFUL", "Capacity": 100, "RuleGroupStatus": "ACTIVE", "Tags": [], "ConsumedCapacity": 1, "NumberOfAssociations": 0, "EncryptionConfiguration": { "KeyId": "AWS_OWNED_KMS_KEY", "Type": "AWS_OWNED_KMS_KEY" }, "LastModifiedTime": "2022-08-24T00:48:03.988000+00:00" } }
ちょっと横道にそれました。
IP セット参照が正しく保存されたことを確認します。
こちらの IP セット参照を利用するルールを追加します。
ルールのルールを編集
から、IP セット参照を利用するルールを追加しました。今回はマネージドプレフィックリストに追加したネットワーク間の ICMP の通信はドロップするようにしました。
IP セット参照の変数を表現する場合は IP セット参照変数名の先頭に@
を付けます。一方ルール変数の場合は先頭に$
を付けるので要注意です。
To reference a prefix list in your rule group, specify a IP set variable name and associate it with the prefix list's Amazon Resource Name (ARN). Then, specify the variable in one or more of your rules, prefacing the variable with @, such as @IP_Set_Variable. The variable represents the IPv4 prefix list that you are referencing. For more information about using IP set references, see Referencing Amazon VPC prefix lists.
Examples of stateful rules for Network Firewall - AWS Network Firewall
ルールグループを保存
をクリックして、ルールが追加されたことを確認します。
なお、今回はルールグループのステートフルルールの順序をデフォルト (default)にしています。デフォルトだと以下の順番でルールが評価されます。
- パス
- ドロップ
- アラート
アラートの優先順位を上げたり、ルールの優先順位を自分でコントロールしたい場合は厳密 (strict)に変更してください。
Evaluation order for stateful rule groups - AWS Network Firewall
動作確認
動作確認をします。
Spoke VPC A EC2 Instance 0
に接続して、Spoke VPC B の EC2 インスタンスに ping で疎通確認をします。
# Spoke VPC B EC2 Instance 0 への疎通確認 $ ping 10.0.3.44 -c 5 PING 10.0.3.44 (10.0.3.44) 56(84) bytes of data. --- 10.0.3.44 ping statistics --- 5 packets transmitted, 0 received, 100% packet loss, time 4079ms # Spoke VPC B EC2 Instance 1 への疎通確認 $ ping 10.0.3.60 -c 5 PING 10.0.3.60 (10.0.3.60) 56(84) bytes of data. --- 10.0.3.60 ping statistics --- 5 packets transmitted, 0 received, 100% packet loss, time 4095ms
どちらも通信できなくなりました。
Network Firewall のアラートログを確認すると、以下のように VPC 間の ICMP 通信をドロップしたことが記録されていました。
# Spoke VPC A EC2 Instance 0 から Spoke VPC B EC2 Instance 0 への Echo Request { "firewall_name": "NetworkFirewall", "availability_zone": "us-east-1a", "event_timestamp": "1660880431", "event": { "timestamp": "2022-08-19T03:40:31.064104+0000", "flow_id": 1386707604732520, "event_type": "alert", "src_ip": "10.0.2.36", "src_port": 0, "dest_ip": "10.0.3.44", "dest_port": 0, "proto": "ICMP", "icmp_type": 8, "icmp_code": 0, "alert": { "action": "blocked", "signature_id": 1000002, "rev": 0, "signature": "", "category": "", "severity": 3 } } } # Spoke VPC A EC2 Instance 0 から Spoke VPC B EC2 Instance 1 への Echo Request { "firewall_name": "NetworkFirewall", "availability_zone": "us-east-1b", "event_timestamp": "1660880453", "event": { "timestamp": "2022-08-19T03:40:53.256265+0000", "flow_id": 1270318287415561, "event_type": "alert", "src_ip": "10.0.2.36", "src_port": 0, "dest_ip": "10.0.3.60", "dest_port": 0, "proto": "ICMP", "icmp_type": 8, "icmp_code": 0, "alert": { "action": "blocked", "signature_id": 1000002, "rev": 0, "signature": "", "category": "", "severity": 3 } } }
なお、同じ VPC 内の EC2 インスタンスや外部の IP アドレス8.8.8.8
には引き続き疎通できます。
# Spoke VPC A EC2 Instance 1 への疎通確認 $ ping 10.0.2.60 -c 5 PING 10.0.2.60 (10.0.2.60) 56(84) bytes of data. 64 bytes from 10.0.2.60: icmp_seq=1 ttl=255 time=1.12 ms 64 bytes from 10.0.2.60: icmp_seq=2 ttl=255 time=0.743 ms 64 bytes from 10.0.2.60: icmp_seq=3 ttl=255 time=0.740 ms 64 bytes from 10.0.2.60: icmp_seq=4 ttl=255 time=0.682 ms 64 bytes from 10.0.2.60: icmp_seq=5 ttl=255 time=0.829 ms --- 10.0.2.60 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4076ms rtt min/avg/max/mdev = 0.682/0.823/1.124/0.160 ms # Google Public DNS への疎通確認 $ ping 8.8.8.8 -c 5 PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. 64 bytes from 8.8.8.8: icmp_seq=1 ttl=104 time=4.46 ms 64 bytes from 8.8.8.8: icmp_seq=2 ttl=104 time=2.47 ms 64 bytes from 8.8.8.8: icmp_seq=3 ttl=104 time=2.46 ms 64 bytes from 8.8.8.8: icmp_seq=4 ttl=104 time=2.44 ms 64 bytes from 8.8.8.8: icmp_seq=5 ttl=104 time=2.48 ms --- 8.8.8.8 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4006ms rtt min/avg/max/mdev = 2.441/2.865/4.462/0.798 ms
外部の IP アドレスへの通信を制御
マネージドプレフィックリストに登録された IP アドレスを Network Firewall で通信制御できることが分かりました。
ついでに、外部の IP アドレスに対しても通信制御してみます。
Google Public DNS の IP アドレス8.8.8.8
を先ほどのマネージドプレフィックリストに追加します。
# Google Public DNS の IP アドレス 8.8.8.8 をマネージドプレフィックリストに追加 $ aws ec2 modify-managed-prefix-list \ --prefix-list-id pl-04cc71660eade4c98 \ --add-entries Cidr=8.8.8.8/32,Description="Google Public DNS" \ --current-version 1 { "PrefixList": { "PrefixListId": "pl-04cc71660eade4c98", "AddressFamily": "IPv4", "State": "modify-in-progress", "PrefixListArn": "arn:aws:ec2:us-east-1:<AWSアカウントID>:prefix-list/pl-04cc71660eade4c98", "PrefixListName": "Spoke VPC", "MaxEntries": 10, "Version": 1, "OwnerId": "<AWSアカウントID>" } } # Google Public DNS の IP アドレス 8.8.8.8 がマネージドプレフィックリストに追加されたことを確認 aws ec2 get-managed-prefix-list-entries \ --prefix-list-id pl-04cc71660eade4c98 { "Entries": [ { "Cidr": "8.8.8.8/32", "Description": "Google Public DNS" }, { "Cidr": "10.0.2.0/24", "Description": "Spoke VPC A" }, { "Cidr": "10.0.3.0/24", "Description": "Spoke VPC B" } ] }
この状態で8.8.8.8
に疎通確認してみます。
$ ping 8.8.8.8 -c 5 PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. --- 8.8.8.8 ping statistics --- 5 packets transmitted, 0 received, 100% packet loss, time 4081ms
通信できなくなりましたね。
Network Firewall のアラートログにも記録されていました。
{ "firewall_name": "NetworkFirewall", "availability_zone": "us-east-1a", "event_timestamp": "1660881173", "event": { "timestamp": "2022-08-19T03:52:53.206162+0000", "flow_id": 1003918693049682, "event_type": "alert", "src_ip": "10.0.2.36", "src_port": 0, "dest_ip": "8.8.8.8", "dest_port": 0, "proto": "ICMP", "icmp_type": 8, "icmp_code": 0, "alert": { "action": "blocked", "signature_id": 1000002, "rev": 0, "signature": "", "category": "", "severity": 3 } } }
Network Firewallのルールで使うIPアドレスの管理が簡単に
AWS Network Firewall が VPC プレフィックスリストのサポートをしたアップデートを紹介しました。
Network Firewallがまた使いやすくなりましたね。現状はルールグループに設定できるIPセット参照は5個までなので、それ以上使いたい場合はルールグループの分割をする必要がありそうです。こちらの上限も緩和されるとありがたいですね。
この記事が誰かの助けになれば幸いです。
以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!