AWS Network Firewallのウェブカテゴリベースのフィルタリングをしてみた

AWS Network Firewallのウェブカテゴリベースのフィルタリングをしてみた

業務上使用しないカテゴリについてはブロックしても良いかもしれない
2026.03.30

カテゴリベースでフィルタリングを行いたい

こんにちは、のんピ(@non____97)です。

皆さんはAWS Network Firewallにおいて、カテゴリベースでフィルタリングを行いたいなと思ったことはありますか? 私はあります。

i-FilterのWebプロキシ製品では、カテゴリベースで許可/拒否をコントロールすることが可能です。

これにより、未知のドメインやURLへのアクセスに対しても制御することが可能です。

2026年1月のアップデートにはなるのですが、AWS Network Firewallでも同様にカテゴリベースのドメインやURLフィルタリングをすることが可能になりました。

https://aws.amazon.com/jp/about-aws/whats-new/2026/01/aws-network-firewall-web-category-based-filtering/

実際に試してみました。

いきなりまとめ

  • カテゴリベースのドメインフィルタリングとURLフィルタリングが可能
    • Suricataのキーワードで指定する形
  • URLパスまで含めた細かい制御をする場合はaws_url_category、ホストヘッダーおよびSNIフィールドから判断する場合はaws_domain_categoryを使用する形になる
    • TLSインスペクションを有効化しない場合は、SNIスプーフィングのリスクも理解しよう
  • AWSのサービスエンドポイントはTechnology and Internetにカテゴライズされる
  • 必ず何かのカテゴリが割り当てられるというわけではない

機能紹介

今回のアップデートによるカテゴリベースのドメインフィルタリングとURLフィルタリングは、専用のマネージドルールグループが提供されているのではありません。Suricataベースのルールにおいてキーワードを用いて定義します。

特に追加費用はかからないのは嬉しいポイントです。

今回追加されたのは以下2つのキーワードです。

  • aws_url_category
  • aws_domain_category

情報は以下AWS公式ドキュメントにまとまっています。

https://docs.aws.amazon.com/network-firewall/latest/developerguide/rule-groups-url-filtering.html

特徴をまとめると以下のとおりです。

項目 aws_url_category aws_domain_category
評価対象 完全な URL とドメイン ドメイン情報のみ
サポートプロトコル HTTP TLS, HTTP
TLS インスペクション HTTPS の場合は必須 不要
HTTP トラフィック 完全な URL を評価 Host フィールドからドメインを評価
HTTPS / TLS トラフィック TLS 検査で URL を評価 (なければ評価不可) SNI フィールドからドメインを評価
評価ロジック 1. URL パス評価 (最大30回再帰) → 2. ドメイン評価にフォールバック (最大10回再帰) ドメインレベルのみ評価 (最大10回再帰)
HTTP リクエストの URI フィールド o (HTTPS は TLS インスペクション必須) -
HTTP リクエストの Host フィールド o o
TLS ハンドシェイクの SNI フィールド - o

URLパスまで含めた細かい制御をする場合はaws_url_category、ホストヘッダーおよびSNIフィールドから判断する場合はaws_domain_categoryになります。

aws_domain_categoryはTLSインスペクションは不要と言えど、TLSインスペクションを有効にしなければ以下のとおりSNIスプーフィングが可能であるため、注意しておく必要があるでしょう。

https://dev.classmethod.jp/articles/aws-network-firewall-tls-inspection-sni-spoofing-protection/

現時点でサポートされているカテゴリは以下のとおりです。

  • Abortion
  • Adult and Mature Content
  • Artificial Intelligence and Machine Learning
  • Arts and Culture
  • Business and Economy
  • Career and Job Search
  • Child Abuse
  • Command and Control
  • Criminal and Illegal Activities
  • Cryptocurrency
  • Dating
  • Education
  • Email
  • Entertainment
  • Family and Parenting
  • Fashion
  • Financial Services
  • Food and Dining
  • For Kids
  • Gambling
  • Government and Legal
  • Hacking
  • Health
  • Hobbies and Interest
  • Home and Garden
  • Lifestyle
  • Malicious
  • Malware
  • Marijuana
  • Military
  • News
  • Online Ads
  • Parked Domains
  • Pets
  • Phishing
  • Private IP Address
  • Proxy Avoidance
  • Real Estate
  • Redirect
  • Religion
  • Search Engines and Portals
  • Science
  • Shopping
  • Social Networking
  • Spam
  • Sports and Recreation
  • Technology and Internet
  • Translation
  • Travel
  • Vehicles
  • Violence and Hate Speech

AWSマネジメントコンソールやAWS CLIなどで入力したドメイン、URLがどのカテゴリに属するのか確認する方法は提供されていません。

i-Filterのようにチェックツールが提供されるようになると嬉しいですね。

https://www.pa-solution.net/daj/bs/faq/detail.aspx?id=2891&isCrawler=1

他注意点は以下のとおりです。

  • 1つの URL が複数のカテゴリにマッピングされる場合がある
  • カテゴリデータベースは自動的に維持、更新される
  • 1つのルールに複数のカテゴリを指定できる
  • aws_url_category / aws_domain_categoryと地理的 IP フィルタリング (geoip) を同じルール内で組み合わせることはできない
    • 両方を使用する場合は別々のルールを作成する必要がある
  • aws_url_category / aws_domain_categoryを使用するとトラフィックの遅延が増加する可能性がある
    • ルールのプロトコルおよび IP 仕様に一致する各接続に対して追加のカテゴリ検索が実行されるため

やってみた

検証環境

実際にやってみます。

検証環境は以下のとおりです。

検証環境構成図.png

今回はドメインフィルタリングを行います。

ルールの設定

ルールグループを作成して、ドメインフィルタリング用のルールを設定します。

一つのルールに詰め込んでしまうとstateful rule is invalidとエラーになったので、5つ程度に分けています。

alert tls any any -> any any (msg:"Domain category check 1"; aws_domain_category:Abortion,Adult and Mature Content,Artificial Intelligence and Machine Learning,Arts and Culture,Business and Economy,Career and Job Search,Child Abuse,Command and Control,Criminal and Illegal Activities,Cryptocurrency; sid:99999901; rev:1;)
alert tls any any -> any any (msg:"Domain category check 2"; aws_domain_category:Dating,Education,Email,Entertainment,Family and Parenting,Fashion,Financial Services,Food and Dining,For Kids,Gambling; sid:99999902; rev:1;)
alert tls any any -> any any (msg:"Domain category check 3"; aws_domain_category:Government and Legal,Hacking,Health,Hobbies and Interest,Home and Garden,Lifestyle,Malicious,Malware,Marijuana,Military; sid:99999903; rev:1;)
alert tls any any -> any any (msg:"Domain category check 4"; aws_domain_category:News,Online Ads,Parked Domains,Pets,Phishing,Private IP Address,Proxy Avoidance,Real Estate,Redirect,Religion; sid:99999904; rev:1;)
alert tls any any -> any any (msg:"Domain category check 5"; aws_domain_category:Search Engines and Portals,Science,Shopping,Social Networking,Spam,Sports and Recreation,Technology and Internet,Translation,Travel,Vehicles,Violence and Hate Speech; sid:99999905; rev:1;)

ファイアウォールポリシー自体は以下のとおりで、ルールの順序は厳格、デフォルトドロップアクションはなしにしているのがポイントだと思います。

> aws network-firewall describe-firewall-policy --firewall-policy-name nfw
{
    "UpdateToken": "23d629f6-4f6c-4eca-89ec-a76cf2e020e8",
    "FirewallPolicyResponse": {
        "FirewallPolicyName": "nfw",
        "FirewallPolicyArn": "arn:aws:network-firewall:us-east-1:<AWSアカウントID>:firewall-policy/nfw",
        "FirewallPolicyId": "7cb036ef-4087-4054-b72b-a59156e7476b",
        "FirewallPolicyStatus": "ACTIVE",
        "Tags": [],
        "ConsumedStatelessRuleCapacity": 0,
        "ConsumedStatefulRuleCapacity": 100,
        "NumberOfAssociations": 1,
        "EncryptionConfiguration": {
            "KeyId": "AWS_OWNED_KMS_KEY",
            "Type": "AWS_OWNED_KMS_KEY"
        },
        "LastModifiedTime": "2026-03-30T19:21:01.981000+09:00"
    },
    "FirewallPolicy": {
        "StatelessDefaultActions": [
            "aws:forward_to_sfe"
        ],
        "StatelessFragmentDefaultActions": [
            "aws:forward_to_sfe"
        ],
        "StatelessCustomActions": [],
        "StatefulRuleGroupReferences": [
            {
                "ResourceArn": "arn:aws:network-firewall:us-east-1:<AWSアカウントID>:stateful-rulegroup/domain-category",
                "Priority": 1
            }
        ],
        "StatefulDefaultActions": [
            "aws:alert_established_app_layer"
        ],
        "StatefulEngineOptions": {
            "RuleOrder": "STRICT_ORDER",
            "StreamExceptionPolicy": "REJECT"
        }
    }
}

ファイアウォールポリシー.png

動作確認

動作確認をします。

EC2インスタンスを起動してしばらくすると、以下のようにec2messages.us-east-1.amazonaws.comssmmessages.us-east-1.amazonaws.comなどAWSのサービスエンドポイントに対するアラートが発生していました。

{
    "firewall_name": "nfw",
    "availability_zone": "us-east-1a",
    "event_timestamp": "1774866209",
    "event": {
        "aws_category": "[\"Technology and Internet\"]",
        "tx_id": 0,
        "app_proto": "tls",
        "src_ip": "10.0.144.118",
        "src_port": 53030,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_established_app_layer action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 490844992185568,
        "dest_ip": "98.87.173.75",
        "proto": "TCP",
        "verdict": {
            "action": "alert"
        },
        "tls": {
            "sni": "ec2messages.us-east-1.amazonaws.com",
            "version": "UNDETERMINED"
        },
        "dest_port": 443,
        "pkt_src": "geneve encapsulation",
        "timestamp": "2026-03-30T10:23:29.249995+0000",
        "direction": "to_server"
    }
}
{
    "firewall_name": "nfw",
    "availability_zone": "us-east-1a",
    "event_timestamp": "1774866217",
    "event": {
        "aws_category": "[\"Technology and Internet\"]",
        "tx_id": 0,
        "app_proto": "tls",
        "src_ip": "10.0.144.118",
        "src_port": 56410,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_established_app_layer action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 381111503837525,
        "dest_ip": "44.216.203.22",
        "proto": "TCP",
        "verdict": {
            "action": "alert"
        },
        "tls": {
            "sni": "ssmmessages.us-east-1.amazonaws.com",
            "version": "UNDETERMINED"
        },
        "dest_port": 443,
        "pkt_src": "geneve encapsulation",
        "timestamp": "2026-03-30T10:23:37.354876+0000",
        "direction": "to_server"
    }
}
{
    "firewall_name": "nfw",
    "availability_zone": "us-east-1a",
    "event_timestamp": "1774866217",
    "event": {
        "aws_category": "[\"Technology and Internet\"]",
        "tx_id": 0,
        "app_proto": "tls",
        "src_ip": "10.0.144.118",
        "src_port": 49646,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_established_app_layer action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 286300343235295,
        "dest_ip": "3.236.94.144",
        "proto": "TCP",
        "verdict": {
            "action": "alert"
        },
        "tls": {
            "sni": "logs.us-east-1.amazonaws.com",
            "version": "UNDETERMINED"
        },
        "dest_port": 443,
        "pkt_src": "geneve encapsulation",
        "timestamp": "2026-03-30T10:23:37.398683+0000",
        "direction": "to_server"
    }
}
{
    "firewall_name": "nfw",
    "availability_zone": "us-east-1a",
    "event_timestamp": "1774866218",
    "event": {
        "aws_category": "[\"Technology and Internet\"]",
        "tx_id": 0,
        "app_proto": "tls",
        "src_ip": "10.0.144.118",
        "src_port": 54486,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 99999905,
            "rev": 1,
            "signature": "Domain category check 5",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 744622004207624,
        "dest_ip": "13.220.36.112",
        "proto": "TCP",
        "verdict": {
            "action": "alert"
        },
        "tls": {
            "sni": "ssm.us-east-1.amazonaws.com",
            "version": "UNDETERMINED"
        },
        "dest_port": 443,
        "pkt_src": "geneve encapsulation",
        "timestamp": "2026-03-30T10:23:38.045992+0000",
        "direction": "to_server"
    }
}
{
    "firewall_name": "nfw",
    "availability_zone": "us-east-1a",
    "event_timestamp": "1774866218",
    "event": {
        "aws_category": "[\"Technology and Internet\"]",
        "tx_id": 0,
        "app_proto": "tls",
        "src_ip": "10.0.144.118",
        "src_port": 54486,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_established_app_layer action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 744622004207624,
        "dest_ip": "13.220.36.112",
        "proto": "TCP",
        "verdict": {
            "action": "alert"
        },
        "tls": {
            "sni": "ssm.us-east-1.amazonaws.com",
            "version": "UNDETERMINED"
        },
        "dest_port": 443,
        "pkt_src": "geneve encapsulation",
        "timestamp": "2026-03-30T10:23:38.045992+0000",
        "direction": "to_server"
    }
}

ということで、Technology and Internetでブロックするルールを追加してしまうと、対応するサービスのVPCエンドポイントがなければ軒並みブロックされてしまいます。そうでなければ、カテゴリベースのフィルタリングの前段でドメインフィルタリングで明示的に許可してあげる必要があると考えます。

続いて、dev.classmethod.jpにアクセスをします。

$ curl https://dev.classmethod.jp/ -I
HTTP/2 200
content-type: text/html; charset=utf-8
date: Mon, 30 Mar 2026 10:29:20 GMT
cache-control: public, max-age=45, stale-if-error=21600
link: <https://devio2025-elb-apn1.developers.io/en/>; rel="alternate"; hreflang="en", <https://devio2025-elb-apn1.developers.io/>; rel="alternate"; hreflang="ja", <https://devio2025-elb-apn1.developers.io/>; rel="alternate"; hreflang="x-default"
x-custom-lang: ja
x-middleware-rewrite: /ja
x-powered-by: Next.js
vary: Accept-Encoding
x-cache: Miss from cloudfront
via: 1.1 da473159f6f131ea8035a6279b0f60aa.cloudfront.net (CloudFront)
x-amz-cf-pop: IAD61-P11
alt-svc: h3=":443"; ma=86400
x-amz-cf-id: jerZ4r-JrTl42eq_giW_6p5hbljGosh1CNkQAfL3tI1fnFU14ZASTg==
server-timing: cdn-upstream-layer;desc="REC",cdn-upstream-dns;dur=0,cdn-upstream-connect;dur=0,cdn-upstream-fbl;dur=174,cdn-cache-miss,cdn-pop;desc="IAD61-P11",cdn-rid;desc="jerZ4r-JrTl42eq_giW_6p5hbljGosh1CNkQAfL3tI1fnFU14ZASTg==",cdn-downstream-fbl;dur=182

このときのログは以下のとおりで、カテゴリはTechnology and Internetでした。

{
    "firewall_name": "nfw",
    "availability_zone": "us-east-1a",
    "event_timestamp": "1774866560",
    "event": {
        "aws_category": "[\"Technology and Internet\"]",
        "tx_id": 0,
        "app_proto": "tls",
        "src_ip": "10.0.144.118",
        "src_port": 52656,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 99999905,
            "rev": 1,
            "signature": "Domain category check 5",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 79365365321249,
        "dest_ip": "13.35.78.60",
        "proto": "TCP",
        "verdict": {
            "action": "alert"
        },
        "tls": {
            "sni": "dev.classmethod.jp",
            "version": "UNDETERMINED"
        },
        "dest_port": 443,
        "pkt_src": "geneve encapsulation",
        "timestamp": "2026-03-30T10:29:20.809583+0000",
        "direction": "to_server"
    }
}
{
    "firewall_name": "nfw",
    "availability_zone": "us-east-1a",
    "event_timestamp": "1774866560",
    "event": {
        "aws_category": "[\"Technology and Internet\"]",
        "tx_id": 0,
        "app_proto": "tls",
        "src_ip": "10.0.144.118",
        "src_port": 52656,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_established_app_layer action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 79365365321249,
        "dest_ip": "13.35.78.60",
        "proto": "TCP",
        "verdict": {
            "action": "alert"
        },
        "tls": {
            "sni": "dev.classmethod.jp",
            "version": "UNDETERMINED"
        },
        "dest_port": 443,
        "pkt_src": "geneve encapsulation",
        "timestamp": "2026-03-30T10:29:20.809583+0000",
        "direction": "to_server"
    }
}

続いて、私が後悔しているWebサイトwww.non-97.netにアクセスします。

$ curl http://www.non-97.net/ -I
HTTP/1.1 301 Moved Permanently
Server: CloudFront
Date: Mon, 30 Mar 2026 10:31:40 GMT
Content-Type: text/html
Content-Length: 167
Connection: keep-alive
Location: https://www.non-97.net/
X-Cache: Redirect from cloudfront
Via: 1.1 2ad6789a221bb559c9b8ce946b65a03a.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: IAD12-P2
X-Amz-Cf-Id: uVaPBSPSd7ezfx0bJgqyHlBFdgsKgO4QCH7FEQVPdwdL0t4BQV9VSA==
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Referrer-Policy: strict-origin-when-cross-origin
X-Content-Type-Options: nosniff

$ curl https://www.non-97.net/ -I
HTTP/2 200
content-type: text/html
content-length: 12
date: Mon, 30 Mar 2026 10:31:47 GMT
last-modified: Tue, 25 Feb 2025 02:38:39 GMT
etag: "56aec8b7843df637b3fb2ec0b027e5b6"
x-amz-server-side-encryption: AES256
accept-ranges: bytes
server: AmazonS3
x-cache: Miss from cloudfront
via: 1.1 d4313104085979d3472fae656cd1ecc2.cloudfront.net (CloudFront)
x-amz-cf-pop: IAD12-P2
x-amz-cf-id: Z9XoxyejKDlV9x9Jg9OnJp2_uN2C1f4evm0qs8_8r7m-vAFQ4dY9NA==
x-xss-protection: 1; mode=block
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
x-content-type-options: nosniff
strict-transport-security: max-age=31536000

このときのログは以下のとおりです。

{
    "firewall_name": "nfw",
    "availability_zone": "us-east-1a",
    "event_timestamp": "1774866700",
    "event": {
        "aws_category": "",
        "tx_id": 0,
        "app_proto": "http",
        "src_ip": "10.0.144.118",
        "src_port": 57116,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 4,
            "rev": 0,
            "signature": "aws:alert_established_app_layer action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 1302647705937450,
        "dest_ip": "108.138.85.82",
        "proto": "TCP",
        "verdict": {
            "action": "alert"
        },
        "http": {
            "hostname": "www.non-97.net",
            "url": "/",
            "http_user_agent": "curl/8.17.0",
            "http_method": "HEAD",
            "protocol": "HTTP/1.1",
            "length": 0
        },
        "dest_port": 80,
        "pkt_src": "geneve encapsulation",
        "timestamp": "2026-03-30T10:31:40.371787+0000",
        "direction": "to_server"
    }
}
{
    "firewall_name": "nfw",
    "availability_zone": "us-east-1a",
    "event_timestamp": "1774866706",
    "event": {
        "aws_category": "",
        "tx_id": 0,
        "app_proto": "tls",
        "src_ip": "10.0.144.118",
        "src_port": 34464,
        "event_type": "alert",
        "alert": {
            "severity": 3,
            "signature_id": 2,
            "rev": 0,
            "signature": "aws:alert_established_app_layer action",
            "action": "allowed",
            "category": ""
        },
        "flow_id": 788394307038501,
        "dest_ip": "108.138.85.20",
        "proto": "TCP",
        "verdict": {
            "action": "alert"
        },
        "tls": {
            "sni": "www.non-97.net",
            "version": "UNDETERMINED"
        },
        "dest_port": 443,
        "pkt_src": "geneve encapsulation",
        "timestamp": "2026-03-30T10:31:46.516139+0000",
        "direction": "to_server"
    }
}

カテゴリフィールドが空になっています。つまりは毎回何かしらのカテゴリに割り当てられるという訳ではないということです。

業務上使用しないカテゴリについてはブロックしても良いかもしれない

AWS Network Firewallのカテゴリベースのフィルタリングをしてみました。

SpamCommand and Controlはもちろん、GamblingCryptocurrencyなど業務上使用しないカテゴリについてはブロックしても良さそうです。

参考までにAWS Network Firewallのベストプラクティスにはカテゴリベースフィルタリングの例として、以下が紹介されていました。

# Block higher risk domain categories
reject tls $HOME_NET any -> any any (msg:"Category:Command and Control"; aws_domain_category:Command and Control; ja4.hash; content:"_"; flow:to_server; sid:202602061;)
reject tls $HOME_NET any -> any any (msg:"Category:Hacking"; aws_domain_category:Hacking; ja4.hash; content:"_"; flow:to_server; sid:202602062;)
reject tls $HOME_NET any -> any any (msg:"Category:Malicious"; aws_domain_category:Malicious; ja4.hash; content:"_"; flow:to_server; sid:202602063;)
reject tls $HOME_NET any -> any any (msg:"Category:Malware"; aws_domain_category:Malware; ja4.hash; content:"_"; flow:to_server; sid:202602064;)
reject tls $HOME_NET any -> any any (msg:"Category:Phishing"; aws_domain_category:Phishing; ja4.hash; content:"_"; flow:to_server; sid:202602065;)
reject tls $HOME_NET any -> any any (msg:"Category:Proxy Avoidance"; aws_domain_category:Proxy Avoidance; ja4.hash; content:"_"; flow:to_server; sid:202602066;)
reject tls $HOME_NET any -> any any (msg:"Category:Spam"; aws_domain_category:Spam; ja4.hash; content:"_"; flow:to_server; sid:202602067;)
reject http $HOME_NET any -> any any (msg:"Category:Command and Control"; aws_url_category:Command and Control; flow:to_server; sid:202602068;)
reject http $HOME_NET any -> any any (msg:"Category:Hacking"; aws_url_category:Hacking; flow:to_server; sid:202602069;)
reject http $HOME_NET any -> any any (msg:"Category:Malicious"; aws_url_category:Malicious; flow:to_server; sid:2026020610;)
reject http $HOME_NET any -> any any (msg:"Category:Malware"; aws_url_category:Malware; flow:to_server; sid:2026020611;)
reject http $HOME_NET any -> any any (msg:"Category:Phishing"; aws_url_category:Phishing; flow:to_server; sid:2026020612;)
reject http $HOME_NET any -> any any (msg:"Category:Proxy Avoidance"; aws_url_category:Proxy Avoidance; flow:to_server; sid:2026020613;)
reject http $HOME_NET any -> any any (msg:"Category:Spam"; aws_url_category:Spam; flow:to_server; sid:2026020614;)

抜粋 : AWS Network Firewall ベストプラクティス - AWS Security Services Best Practices

この記事が誰かの助けになれば幸いです。

以上、クラウド事業本部 コンサルティング部の のんピ(@non____97)でした!

この記事をシェアする

FacebookHatena blogX

関連記事