ステートフルドメインリスト
Network Firewall を利用して特定のドメインのアクセスを許可または拒否するには、ステートフルドメインリストまたは Suricata 対応の IPS ルールで対応可能かと思いますが、今回は ステートフルドメインリストを利用してみたいと思います。
なお、ステートフルドメイン名の検査は以下を見て行われるようである。
-
HTTP
- HTTP ホストヘッダー
-
HTTPS
- TLS ハンドシェイクの Server Name Indication (SNI) におけるserver_name
環境
環境は下記の方の CloudFormationテンプレートを利用させてもらいました。
なお、ログも確認してみたかったので、AWSコンソールから、CloudWatch log group にログを配信しておくように設定を追加しました。
アクションの順序と厳密な順序
-
アクションの順序
- パスアクションを含むルールが最初に処理され、その後にドロップ、拒否、アラートアクションが続きます。
-
厳密な評価順序
- ルールは、最初のルールから、定義された順序で処理されます。
アクションの順序
まず、CloudFormationテンプレートをデプロイするとアクションの順序でデプロイされます。
下記の通り、VPC内の 10.0.0.0/16 からは www.yahoo.co.jp もしくは .ap-northeast-1.amazonaws.com へのアクセスのみ許可し、それ以外の通信は拒否するということになります。(ホワイトリスト形式)
こちらは期待通り、 https://www.yahoo.co.jp への通信が可能であることが確認できました。
curl -v https://www.yahoo.co.jp
{
"firewall_name": "NetworkFirwallTestXYZ",
"availability_zone": "ap-northeast-1a",
"event_timestamp": "1700121275",
"event": {
"tcp": {
"tcp_flags": "1b",
"syn": true,
"fin": true,
"psh": true,
"ack": true
},
"app_proto": "tls",
"src_ip": "10.0.1.254",
"src_port": 46036,
"netflow": {
"pkts": 20,
"bytes": 1863,
"start": "2023-11-16T07:53:10.841142+0000",
"end": "2023-11-16T07:53:10.909158+0000",
"age": 0,
"min_ttl": 63,
"max_ttl": 63
},
"event_type": "netflow",
"flow_id": 718044618216886,
"dest_ip": "182.22.24.252",
"proto": "TCP",
"dest_port": 443,
"timestamp": "2023-11-16T07:54:35.629281+0000"
}
}
{
"firewall_name": "NetworkFirwallTestXYZ",
"availability_zone": "ap-northeast-1a",
"event_timestamp": "1700121275",
"event": {
"tcp": {
"tcp_flags": "1f",
"syn": true,
"fin": true,
"rst": true,
"psh": true,
"ack": true
},
"app_proto": "tls",
"src_ip": "182.22.24.252",
"src_port": 443,
"netflow": {
"pkts": 38,
"bytes": 42781,
"start": "2023-11-16T07:53:10.841142+0000",
"end": "2023-11-16T07:53:10.909158+0000",
"age": 0,
"min_ttl": 52,
"max_ttl": 246
},
"event_type": "netflow",
"flow_id": 718044618216886,
"dest_ip": "10.0.1.254",
"proto": "TCP",
"dest_port": 46036,
"timestamp": "2023-11-16T07:54:35.629316+0000"
}
}
こちらも期待通り、 https://www.yahoo.co.jp 以外への通信は、"not matching any TLS allowlisted FQDNs"という理由で、"blocked"され、"alert"として上がっていることが確認できました。
curl -v https://www.google.co.jp
{
"firewall_name": "NetworkFirwallTestXYZ",
"availability_zone": "ap-northeast-1a",
"event_timestamp": "1700116541",
"event": {
"app_proto": "tls",
"src_ip": "10.0.1.254",
"src_port": 51102,
"event_type": "alert",
"alert": {
"severity": 1,
"signature_id": 3,
"rev": 1,
"signature": "not matching any TLS allowlisted FQDNs",
"action": "blocked",
"category": ""
},
"flow_id": 1890905392752842,
"dest_ip": "172.217.175.3",
"proto": "TCP",
"tls": {
"sni": "www.google.co.jp",
"version": "UNDETERMINED",
"ja3": {},
"ja3s": {}
},
"dest_port": 443,
"timestamp": "2023-11-16T06:35:41.537802+0000"
}
}
次に、GeneratedRulesType
をDENYLIST
にし、下記の通り、VPC内の 10.0.0.0/16 からは www.yahoo.co.jp へのアクセスのみ拒否し、それ以外の通信は許可するように CloudFormationテンプレートを変更しましょう。(ブラックリスト形式)
なお、.ap-northeast-1.amazonaws.com はセッションマネージャーで接続できなくなってしまうのでコメンアウトにしておきます。
ブラックリスト形式
RulesSource:
RulesSourceList:
Targets:
- "www.yahoo.co.jp"
# - ".ap-northeast-1.amazonaws.com"
TargetTypes:
- "TLS_SNI"
- "HTTP_HOST"
GeneratedRulesType: "DENYLIST"
こちらは期待通り、 https://www.yahoo.co.jp への通信は"matching TLS denylisted FQDNs"という理由で、"blocked"され、"alert"となっていることが確認できました。
curl -v https://www.google.co.jp
{
"firewall_name": "NetworkFirwallTestXYZ",
"availability_zone": "ap-northeast-1a",
"event_timestamp": "1700122951",
"event": {
"tx_id": 0,
"app_proto": "tls",
"src_ip": "10.0.1.254",
"src_port": 56346,
"event_type": "alert",
"alert": {
"severity": 1,
"signature_id": 1,
"rev": 1,
"signature": "matching TLS denylisted FQDNs",
"action": "blocked",
"category": ""
},
"flow_id": 1694041691850110,
"dest_ip": "182.22.24.124",
"proto": "TCP",
"tls": {
"sni": "www.yahoo.co.jp",
"version": "UNDETERMINED",
"ja3": {},
"ja3s": {}
},
"dest_port": 443,
"timestamp": "2023-11-16T08:22:31.660423+0000"
}
}
こちらも期待通り、 https://www.google.co.jp へのアクセスはアクセス可能であることが確認できました。
curl -v https://www.google.co.jp
{
"firewall_name": "NetworkFirwallTestXYZ",
"availability_zone": "ap-northeast-1a",
"event_timestamp": "1700122941",
"event": {
"tcp": {
"tcp_flags": "1b",
"syn": true,
"fin": true,
"psh": true,
"ack": true
},
"app_proto": "tls",
"src_ip": "10.0.1.254",
"src_port": 47938,
"netflow": {
"pkts": 27,
"bytes": 2302,
"start": "2023-11-16T08:18:18.144463+0000",
"end": "2023-11-16T08:18:18.292059+0000",
"age": 0,
"min_ttl": 63,
"max_ttl": 63
},
"event_type": "netflow",
"flow_id": 569172560589903,
"dest_ip": "172.217.175.99",
"proto": "TCP",
"dest_port": 443,
"timestamp": "2023-11-16T08:22:21.095674+0000"
}
}
{
"firewall_name": "NetworkFirwallTestXYZ",
"availability_zone": "ap-northeast-1a",
"event_timestamp": "1700122941",
"event": {
"tcp": {
"tcp_flags": "1f",
"syn": true,
"fin": true,
"rst": true,
"psh": true,
"ack": true
},
"app_proto": "tls",
"src_ip": "172.217.175.99",
"src_port": 443,
"netflow": {
"pkts": 29,
"bytes": 25922,
"start": "2023-11-16T08:18:18.144463+0000",
"end": "2023-11-16T08:18:18.292059+0000",
"age": 0,
"min_ttl": 56,
"max_ttl": 56
},
"event_type": "netflow",
"flow_id": 569172560589903,
"dest_ip": "10.0.1.254",
"proto": "TCP",
"dest_port": 47938,
"timestamp": "2023-11-16T08:22:21.095773+0000"
}
}
厳密な順序
ステートフルルールの順序は後から変更できないので、CloudFormationテンプレートを修正してデプロイしなおします。
NetworkFirewallPolicy
: 以下の通り書き換えます。
StatefulRuleGroup
: コメントアウトしてしまいます。
StatefulRuleGroup2
: 新しく作成します。
NetworkFirewallPolicy:
Type: AWS::NetworkFirewall::FirewallPolicy
Properties:
FirewallPolicyName: NetworkFirewallPolicyTestXYZ
FirewallPolicy:
StatelessDefaultActions:
- 'aws:forward_to_sfe'
StatelessFragmentDefaultActions:
- 'aws:forward_to_sfe'
StatefulDefaultActions:
- 'aws:drop_established'
- "aws:alert_established"
StatefulEngineOptions:
RuleOrder: 'STRICT_ORDER'
StreamExceptionPolicy: 'DROP'
StatefulRuleGroupReferences:
- ResourceArn: !Ref StatefulRuleGroup2
Priority: 100
Tags:
- Key: Name
Value: NetworkFirewallPolicy
# StatefulRuleGroup:
# Type: AWS::NetworkFirewall::RuleGroup
# Properties:
# RuleGroupName: StatefulRuleGroupTestXYZ
# Type: STATEFUL
# Capacity: 100
# RuleGroup:
# RuleVariables:
# IPSets:
# HOME_NET:
# Definition:
# - "10.0.0.0/16"
# RulesSource:
# RulesSourceList:
# Targets:
# - "www.yahoo.co.jp"
# - ".ap-northeast-1.amazonaws.com"
# TargetTypes:
# - "TLS_SNI"
# - "HTTP_HOST"
# GeneratedRulesType: "ALLOWLIST"
# Tags:
# - Key: Name
# Value: AllowDomainList
StatefulRuleGroup2:
Type: AWS::NetworkFirewall::RuleGroup
Properties:
RuleGroupName: StatefulRuleGroupTestABC
Type: STATEFUL
Capacity: 100
RuleGroup:
RuleVariables:
IPSets:
HOME_NET:
Definition:
- "10.0.0.0/16"
RulesSource:
RulesSourceList:
Targets:
- "www.yahoo.co.jp"
- ".ap-northeast-1.amazonaws.com"
TargetTypes:
- "TLS_SNI"
- "HTTP_HOST"
GeneratedRulesType: "ALLOWLIST"
StatefulRuleOptions:
RuleOrder: STRICT_ORDER
Tags:
- Key: Name
Value: AllowDomainList
順序が厳密な順序になっただけで後はアクションの順序と同じです。
今回はルールが 1 つしかないので実際は順序も何もあまり関係ありませんが、ルールにマッチしない場合、デフォルトのアクションの動作となり「確率された接続のパケットをドロップ」するということになるはずです。
そのため、下記の通り、VPC内の 10.0.0.0/16 からは www.yahoo.co.jp もしくは .ap-northeast-1.amazonaws.com へのアクセスのみ許可し、それ以外の通信はドロップするということになるはずです。
また、アラートとして記録しておきたいため、アラートアクションは「確立済み」にしておきます。
期待通り、https://www.yahoo.co.jp へのアクセスは可能でした。
curl -v https://www.yahoo.co.jp
{
"firewall_name": "NetworkFirwallTestXYZ",
"availability_zone": "ap-northeast-1a",
"event_timestamp": "1700219087",
"event": {
"tcp": {
"tcp_flags": "1b",
"syn": true,
"fin": true,
"psh": true,
"ack": true
},
"app_proto": "tls",
"src_ip": "10.0.1.238",
"src_port": 60922,
"netflow": {
"pkts": 21,
"bytes": 1915,
"start": "2023-11-17T11:01:34.112672+0000",
"end": "2023-11-17T11:01:34.210978+0000",
"age": 0,
"min_ttl": 63,
"max_ttl": 63
},
"event_type": "netflow",
"flow_id": 1694101666707488,
"dest_ip": "183.79.217.124",
"proto": "TCP",
"dest_port": 443,
"timestamp": "2023-11-17T11:04:47.499730+0000"
}
}
{
"firewall_name": "NetworkFirwallTestXYZ",
"availability_zone": "ap-northeast-1a",
"event_timestamp": "1700219087",
"event": {
"tcp": {
"tcp_flags": "1f",
"syn": true,
"fin": true,
"rst": true,
"psh": true,
"ack": true
},
"app_proto": "tls",
"src_ip": "183.79.217.124",
"src_port": 443,
"netflow": {
"pkts": 36,
"bytes": 42760,
"start": "2023-11-17T11:01:34.112672+0000",
"end": "2023-11-17T11:01:34.210978+0000",
"age": 0,
"min_ttl": 47,
"max_ttl": 47
},
"event_type": "netflow",
"flow_id": 1694101666707488,
"dest_ip": "10.0.1.238",
"proto": "TCP",
"dest_port": 60922,
"timestamp": "2023-11-17T11:04:47.499773+0000"
}
}
こちらは期待通り、 https://www.google.co.jp への通信は"aws:alert_established action"で、"blocked"となり、"alert"となっていることが確認できました。
curl -v https://www.google.co.jp
{
"firewall_name": "NetworkFirwallTestXYZ",
"availability_zone": "ap-northeast-1a",
"event_timestamp": "1700291239",
"event": {
"app_proto": "tls",
"src_ip": "10.0.1.241",
"src_port": 32912,
"event_type": "alert",
"alert": {
"severity": 3,
"signature_id": 4,
"rev": 0,
"signature": "aws:alert_established action",
"action": "blocked",
"category": ""
},
"flow_id": 143082048128413,
"dest_ip": "216.58.220.99",
"proto": "TCP",
"tls": {
"sni": "www.google.co.jp",
"version": "UNDETERMINED",
"ja3": {},
"ja3s": {}
},
"dest_port": 443,
"timestamp": "2023-11-18T07:07:19.856035+0000"
}
}
参考