securing-api-gateway-with-aws-waf について
公開された AWS API Gateway エンドポイントに AWS WAF の保護を設定するセキュリティスキルです。マネージドルール、レート制限、ボット制御、カスタムルール、ログ、監視を扱います。
主な機能
- 01マネージドルールグループの設定
- 02IP ごとのレート制限
- 03ボットトラフィックの制御
- 04API 固有ルールの作成
- 05ログとメトリクスの監視
活用シーン
- 01公開 API を一般的な Web 攻撃から保護
- 02過剰なリクエストや API の不正利用を抑制
- 03自動化されたボットトラフィックの検出と管理
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill securing-api-gateway-with-aws-wafインストール後、Claude Code で/securing-api-gateway-with-aws-wafを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEreferences/api-reference.mdscripts/agent.py詳細
AWS WAF による API Gateway の保護
使用する場面
- 一般的なウェブ攻撃から保護する必要がある API Gateway エンドポイントをデプロイする場合
- API の悪用や DDoS 攻撃を防ぐために、レート制限とスロットリングを実装する場合
- インターネットに公開されている API エンドポイントに対して、ボットの検出と軽減を構築する場合
- コンプライアンス要件により、すべてのパブリック向け API エンドポイントに WAF による保護が必要な場合
- IP レピュテーション、地理的位置情報、またはリクエストパターンに基づいてアクセス制御をカスタマイズする場合
ネットワークレベルの DDoS 保護には使用しないでください(AWS Shield を使用してください)。アプリケーションロジックの脆弱性への対策には使用しないでください(SAST/DAST ツールを使用してください)。また、マイクロサービス間の内部 API セキュリティには使用しないでください(サービスメッシュの認証と認可を使用してください)。
前提条件
- パブリックエンドポイントを備えた AWS API Gateway(REST または HTTP API)がデプロイされていること
wafv2:*およびapigateway:*オペレーションを実行する IAM 権限- WAF ログ用の CloudWatch と S3 または Kinesis Firehose が設定されていること
- レート制限の設定に必要な、API の想定トラフィックパターンに関する理解
- カスタム IP ブロックに使用する IP レピュテーションリストまたは脅威インテリジェンスフィード
ワークフロー
ステップ 1:マネージドルールグループを使用して WAF Web ACL を作成する
OWASP Top 10 攻撃に対する基本的な保護として、AWS マネージドルールを使用した Web ACL を作成します。
# Create a WAF Web ACL with managed rule groups
aws wafv2 create-web-acl \
--name api-gateway-waf \
--scope REGIONAL \
--default-action '{"Allow":{}}' \
--visibility-config '{
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "api-gateway-waf"
}' \
--rules '[
{
"Name": "AWSManagedRulesCommonRuleSet",
"Priority": 1,
"Statement": {
"ManagedRuleGroupStatement": {
"VendorName": "AWS",
"Name": "AWSManagedRulesCommonRuleSet"
}
},
"OverrideAction": {"None": {}},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "CommonRuleSet"
}
},
{
"Name": "AWSManagedRulesKnownBadInputsRuleSet",
"Priority": 2,
"Statement": {
"ManagedRuleGroupStatement": {
"VendorName": "AWS",
"Name": "AWSManagedRulesKnownBadInputsRuleSet"
}
},
"OverrideAction": {"None": {}},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "KnownBadInputs"
}
},
{
"Name": "AWSManagedRulesSQLiRuleSet",
"Priority": 3,
"Statement": {
"ManagedRuleGroupStatement": {
"VendorName": "AWS",
"Name": "AWSManagedRulesSQLiRuleSet"
}
},
"OverrideAction": {"None": {}},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "SQLiRuleSet"
}
},
{
"Name": "AWSManagedRulesAmazonIpReputationList",
"Priority": 4,
"Statement": {
"ManagedRuleGroupStatement": {
"VendorName": "AWS",
"Name": "AWSManagedRulesAmazonIpReputationList"
}
},
"OverrideAction": {"None": {}},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "IPReputationList"
}
}
]'
ステップ 2:レート制限ルールを追加する
IP アドレスごとの過剰な API リクエストをスロットリングするために、レートベースのルールを設定します。
# Get the Web ACL ARN and lock token
WEB_ACL_ARN=$(aws wafv2 list-web-acls --scope REGIONAL \
--query "WebACLs[?Name=='api-gateway-waf'].ARN" --output text)
# Update Web ACL to add rate limiting rule
aws wafv2 update-web-acl \
--name api-gateway-waf \
--scope REGIONAL \
--id $(aws wafv2 list-web-acls --scope REGIONAL --query "WebACLs[?Name=='api-gateway-waf'].Id" --output text) \
--lock-token $(aws wafv2 get-web-acl --name api-gateway-waf --scope REGIONAL --id WEB_ACL_ID --query 'LockToken' --output text) \
--default-action '{"Allow":{}}' \
--visibility-config '{
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "api-gateway-waf"
}' \
--rules '[
{
"Name": "RateLimitPerIP",
"Priority": 0,
"Statement": {
"RateBasedStatement": {
"Limit": 2000,
"AggregateKeyType": "IP"
}
},
"Action": {"Block": {}},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "RateLimitPerIP"
}
},
{
"Name": "RateLimitLoginEndpoint",
"Priority": 5,
"Statement": {
"RateBasedStatement": {
"Limit": 100,
"AggregateKeyType": "IP",
"ScopeDownStatement": {
"ByteMatchStatement": {
"FieldToMatch": {"UriPath": {}},
"PositionalConstraint": "STARTS_WITH",
"SearchString": "/api/auth/login",
"TextTransformations": [{"Priority": 0, "Type": "LOWERCASE"}]
}
}
}
},
"Action": {"Block": {}},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "RateLimitLogin"
}
}
]'
ステップ 3:ボット制御を実装する
AWS WAF Bot Control を追加して、自動化されたトラフィックを検出および管理します。
# Add Bot Control managed rule group
# (Add to the rules array when updating the Web ACL)
{
"Name": "AWSManagedRulesBotControlRuleSet",
"Priority": 6,
"Statement": {
"ManagedRuleGroupStatement": {
"VendorName": "AWS",
"Name": "AWSManagedRulesBotControlRuleSet",
"ManagedRuleGroupConfigs": [{
"AWSManagedRulesBotControlRuleSet": {
"InspectionLevel": "COMMON"
}
}],
"ExcludedRules": [
{"Name": "CategoryHttpLibrary"},
{"Name": "SignalNonBrowserUserAgent"}
]
}
},
"OverrideAction": {"None": {}},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "BotControl"
}
}
ステップ 4:API 固有の保護にカスタムルールを作成する
API 固有のセキュリティ要件に対応するカスタム WAF ルールを作成します。
# Block requests without required API key header
{
"Name": "RequireAPIKey",
"Priority": 7,
"Statement": {
"NotStatement": {
"Statement": {
"ByteMatchStatement": {
"FieldToMatch": {
"SingleHeader": {"Name": "x-api-key"}
},
"PositionalConstraint": "EXACTLY",
"SearchString": "",
"TextTransformations": [{"Priority": 0, "Type": "NONE"}]
}
}
}
},
"Action": {"Block": {"CustomResponse": {"ResponseCode": 403}}},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "RequireAPIKey"
}
}
# Geo-restrict to allowed countries
{
"Name": "GeoRestriction",
"Priority": 8,
"Statement": {
"NotStatement": {
"Statement": {
"GeoMatchStatement": {
"CountryCodes": ["US", "CA", "GB", "DE", "FR", "AU"]
}
}
}
},
"Action": {"Block": {}},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "GeoRestriction"
}
}
# Block oversized request bodies (prevent payload attacks)
{
"Name": "MaxBodySize",
"Priority": 9,
"Statement": {
"SizeConstraintStatement": {
"FieldToMatch": {"Body": {"OversizeHandling": "MATCH"}},
"ComparisonOperator": "GT",
"Size": 10240,
"TextTransformations": [{"Priority": 0, "Type": "NONE"}]
}
},
"Action": {"Block": {}},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "MaxBodySize"
}
}
ステップ 5:WAF を API Gateway に関連付け、ログ記録を有効にする
Web ACL を API Gateway ステージに関連付け、包括的なログ記録を設定します。
# Associate Web ACL with API Gateway
aws wafv2 associate-web-acl \
--web-acl-arn $WEB_ACL_ARN \
--resource-arn arn:aws:apigateway:us-east-1::/restapis/API_ID/stages/prod
# Enable WAF logging to S3 via Kinesis Firehose
aws wafv2 put-logging-configuration \
--logging-configuration '{
"ResourceArn": "'$WEB_ACL_ARN'",
"LogDestinationConfigs": [
"arn:aws:firehose:us-east-1:ACCOUNT:deliverystream/aws-waf-logs-api-gateway"
],
"RedactedFields": [
{"SingleHeader": {"Name": "authorization"}},
{"SingleHeader": {"Name": "cookie"}}
]
}'
# Verify association
aws wafv2 get-web-acl-for-resource \
--resource-arn arn:aws:apigateway:us-east-1::/restapis/API_ID/stages/prod
ステップ 6:WAF のメトリクスを監視し、ルールを調整する
WAF の有効性を監視し、誤検知を減らすためにルールを調整します。
# Get WAF metrics from CloudWatch
aws cloudwatch get-metric-statistics \
--namespace AWS/WAFV2 \
--metric-name BlockedRequests \
--dimensions Name=WebACL,Value=api-gateway-waf Name=Rule,Value=ALL \
--start-time 2026-02-22T00:00:00Z \
--end-time 2026-02-23T00:00:00Z \
--period 3600 \
--statistics Sum
# Get sampled requests for a specific rule
aws wafv2 get-sampled-requests \
--web-acl-arn $WEB_ACL_ARN \
--rule-metric-name RateLimitPerIP \
--scope REGIONAL \
--time-window '{"StartTime":"2026-02-22T00:00:00Z","EndTime":"2026-02-23T00:00:00Z"}' \
--max-items 50
# Check rate-limited IPs
aws wafv2 get-rate-based-statement-managed-keys \
--web-acl-name api-gateway-waf \
--scope REGIONAL \
--web-acl-id WEB_ACL_ID \
--rule-name RateLimitPerIP
# Create CloudWatch alarm for high block rate
aws cloudwatch put-metric-alarm \
--alarm-name waf-high-block-rate \
--namespace AWS/WAFV2 \
--metric-name BlockedRequests \
--dimensions Name=WebACL,Value=api-gateway-waf Name=Rule,Value=ALL \
--statistic Sum --period 300 --threshold 1000 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 2 \
--alarm-actions arn:aws:sns:us-east-1:ACCOUNT:security-alerts
主要な概念
| 用語 | 定義 |
|---|---|
| Web ACL | 関連付けられたリソースに適用されるルールとそのアクション(許可、ブロック、カウント)の集合を定義する AWS WAF のアクセス制御リスト |
| マネージドルールグループ | OWASP Top 10 などの一般的な攻撃パターンに対応するため、AWS またはサードパーティベンダーが管理する、事前設定済みの WAF ルールセット |
| レートベースのルール | IP アドレスごとのリクエスト率を追跡し、5 分間のウィンドウ内に定められたしきい値を超えたトラフィックをブロックする WAF ルール |
| ボット制御 | スクレイパー、クローラー、攻撃ボットを含む自動化されたトラフィックを識別および管理する AWS WAF のマネージドルールグループ |
| IP レピュテーションリスト | ボットネット、スキャナー、既知の攻撃者など、悪意のある活動に関連付けられた IP アドレスの AWS 管理リスト |
| カスタムレスポンス | リクエストをブロックする際に、特定の HTTP ステータスコードとカスタムレスポンス本文を返す WAF の機能 |
ツールとシステム
- AWS WAF:API Gateway、ALB、CloudFront、AppSync のエンドポイントを保護するウェブアプリケーションファイアウォールサービス
- AWS Managed Rules:一般的な攻撃パターンに対応する、AWS セキュリティチームが管理する事前構築済みのルールグループ
- AWS Firewall Manager:AWS Organizations 内の複数のアカウントにわたる WAF ポリシーの一元管理
- Kinesis Firehose:WAF ログを S3、Elasticsearch、またはサードパーティの分析サービスにストリーミング配信するサービス
- CloudWatch:許可、ブロック、カウントされたリクエストなど、WAF のメトリクスを監視するサービス
よくあるシナリオ
シナリオ:クレデンシャルスタッフィング攻撃やボット攻撃からパブリック API を保護する
コンテキスト:公開 REST API では、自動化されたボットが /api/auth/login エンドポイントに対してクレデンシャルスタッフィング攻撃を試み、1 時間あたり数千件の認証試行が発生しています。
アプローチ:
- ベースライン保護のため、AWS Managed Rules Common Rule Set を使用して Web ACL を作成します
- レートベースのルールを追加し、ログインエンドポイントへのリクエストを IP あたり 5 分間に 100 件までに制限します
- Bot Control マネージドルールを有効にして、自動化されたトラフィックを検出してブロックします
- IP Reputation List を追加し、既知の悪意のある IP を事前にブロックします
- 適切な User-Agent ヘッダーがないリクエストをブロックするカスタムルールを作成します
- WAF のログ記録を有効にし、ブロック率が高い場合に通知する CloudWatch アラームを作成します
- ルールを調整して誤検出を減らすため、サンプリングされたブロック対象のリクエストを毎週確認します
注意点:IP によるレート制限では、共有 NAT ゲートウェイや企業プロキシを経由する正当なユーザーまでブロックする可能性があります。より細かな制御が必要な場合は、API キーまたは認証済みセッションに基づくレート制限を検討してください。COMMON 検査レベルの Bot Control ルールは、正当な API クライアントをブロックする場合があります。まず Count モードで開始し、Block に切り替える前に確認してください。
出力形式
AWS WAF API Gateway Security Report
======================================
Web ACL: api-gateway-waf
Associated Resource: API Gateway - production-api (prod stage)
Report Period: 2026-02-16 to 2026-02-23
TRAFFIC SUMMARY:
Total requests: 2,450,000
Allowed requests: 2,380,000 (97.1%)
Blocked requests: 70,000 (2.9%)
BLOCKS BY RULE:
RateLimitPerIP: 28,000 (40%)
AWSManagedRulesCommonRuleSet: 18,000 (25.7%)
BotControl: 12,000 (17.1%)
SQLiRuleSet: 5,000 (7.1%)
IPReputationList: 4,000 (5.7%)
RateLimitLogin: 2,000 (2.9%)
GeoRestriction: 1,000 (1.4%)
TOP BLOCKED IPs:
185.x.x.x: 8,400 requests (rate limited)
45.x.x.x: 5,200 requests (bot detected)
198.x.x.x: 3,100 requests (SQLi attempts)
ATTACK TYPES BLOCKED:
Credential stuffing (login endpoint): 2,000
SQL injection attempts: 5,000
Cross-site scripting: 3,200
Known bad bot traffic: 12,000
Rate limit violations: 28,000
WAF RULE HEALTH:
Rules in Block mode: 8 / 10
Rules in Count mode: 2 / 10 (under evaluation)
False positive rate: < 0.1%