WAF Web ACLのルールグループを自作して地理制限する
WAF Web ACLでは様々な条件でルールを設定することができます。
今回は地理制限に関するルールグループを自作して、特定の地域からのアクセスをブロックします。
なお今回はWAF Web ACLを使って地理制限を行う方法をご紹介しますが、CloudFrontでも同様のことができます。
詳細は以下のページをご確認ください。
構築する環境
WAF Web ACLを作成します。
地理制限を行います。
具体的にはルールグループを自作し、その中に日本(JP)からのアクセスをブロックするルールを設定します。
作成したWeb ACLをALBに適用します。
ALBはプライベートサブネット内のEC2インスタンスをアタッチします。
EC2インスタンスは最新版のAmazon Linux 2とします。
EC2インスタンスにApacheをインストールし、Webサーバとして動作させ、自身のインスタンスIDを返すように設定します。
ApacheはS3上に構築されたyumリポジトリからインストールします。
CloudFormationテンプレートファイル
上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。
https://github.com/awstut-an-r/awstut-fa/tree/main/046
テンプレートファイルのポイント解説
本ページでは、WAF Web ACLでルールグループを自作する方法と、地理制限を行う方法を中心に取り上げます。
WAF Web ACLの基本的な事項については、以下のページをご確認ください。
プライベートサブネット内のEC2をALBにアタッチする方法は、以下のページをご確認ください。
プライベートサブネット内のEC2でyumを実行する方法については、以下のページをご確認ください。
自作ルールグループに地理制限ルールを設定する
Resources:
RuleGroup:
Type: AWS::WAFv2::RuleGroup
Properties:
Capacity: 10
Name: !Sub "${Prefix}-GeoRestrictionRuleGroup"
Rules:
- Action:
Block: {}
Name: !Sub "${Prefix}-GeoRestrictionRule"
Priority: 0
Statement:
GeoMatchStatement:
CountryCodes:
- JP
VisibilityConfig:
CloudWatchMetricsEnabled: true
MetricName: !Sub "${Prefix}-GeoRestrictionRule"
SampledRequestsEnabled: true
Scope: REGIONAL
VisibilityConfig:
CloudWatchMetricsEnabled: true
MetricName: !Sub "${Prefix}-GeoRestrictionRuleGroup"
SampledRequestsEnabled: true
Code language: YAML (yaml)
AWS::WAFv2::RuleGroupタイプでルールグループを定義できます。
ポイントとなるプロパティを取り上げます。
Capacityプロパティでルールグループ全体のウェブACLキャパシティーユニット(WCU)を設定します。
WCUの仕様は以下の公式ページに詳しいです。
https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/how-aws-waf-works.html
ルールグループにおけるCapacityプロパティのポイントは、一度設定してしまうと、後から修正不可という点です。
When you create your own rule group, you define this, and you cannot change it after creation.
AWS::WAFv2::RuleGroup
ですから余裕を持ったキャパシティ設計を心がけるべきです。
今回ですと、「10」に設定しました。
本来、地理制限に関するステートメントのWCUは「1」なのですが、今後の拡張性を考慮し、余裕を持たせました。
Rulesプロパティでグループ内に定義するルールを設定します。
Actionプロパティでルールの条件を満たしたトラフィックへの対応を定義します。
「Allow」または「Block」が設定可能です。
今回は日本からのアクセスを制限しますので、Blockを設定します。
Statementプロパティでルールの内容を定義します。
地理制限を行う場合はGeoMatchStatementプロパティを使用します。
CountryCodesプロパティで対象となる国コードを指定します。
今回は日本が対象ですので、「JP」を指定します。
なお以下のページによりますと、地理制限に関するWCUは「1」とされています。
https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/waf-rule-statements-list.html
Scopeプロパティは、本ルールグループを含むWeb ACLが、どのリソースに適用されるかによって定まります。
Web ACLをCloudFrontに適用する場合は「CLOUDFRONT」、それ以外のリソースの場合は「REGIONAL」となります。
今回はALBですから後者となります。
WAF Web ACLで自作ルールグループを指定する
Resources:
WebACL:
Type: AWS::WAFv2::WebACL
Properties:
DefaultAction:
Allow: {}
Name: !Sub "${Prefix}-WebACL"
Rules:
- Name: !Sub "${Prefix}-WebACL-GeoRestriction"
OverrideAction:
None: {}
Priority: 0
Statement:
RuleGroupReferenceStatement:
Arn: !GetAtt RuleGroup.Arn
VisibilityConfig:
CloudWatchMetricsEnabled: true
MetricName: !Sub "${Prefix}-WebACL-GeoRestriction"
SampledRequestsEnabled: true
Scope: REGIONAL
VisibilityConfig:
CloudWatchMetricsEnabled: true
MetricName: !Ref Prefix
SampledRequestsEnabled: true
Code language: YAML (yaml)
自作したルールグループをWeb ACLに適用する場合は、Statementプロパティ内のRuleGroupReferenceStatementプロパティを使用します。
ルールグループのARNを指定して、Web ACLを関係付けます。
環境構築
CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。
CloudFormationスタックを作成し、スタック内のリソースを確認する
CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。
各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。
- EC2インスタンスのID:i-060ce9534adc3fa3d
- ALB名:fa-046-ALB
- ALBのURL:http://fa-046-alb-926330093.ap-northeast-1.elb.amazonaws.com/
AWS Management Consoleから、WAFを確認します。
まず自作したルールグループです。
ルールグループに設定したキャパシティが「10」で、実際に消費しているキャパシティが「1」だということがわかります。
またグループ内に設定されているルールが1つだということもわかります。
続いてそのルールの中身を確認します。
日本からのアクセスを拒否する内容が設定されています。
動作確認
準備が整いましたので、日本からALBにアクセスします。
アクセスが拒否されました。
日本からアクセスしたため、ALBに到達する前に、WAF Web ACLによってフィルタリングされたということです。
確認のために、地理制限のアクションを変更します。
ルールのアクションをブロックからカウント、つまりルールは生かしつつ、ルールに該当するトラフィック数を数えるだけに変更しました。
改めてALBにアクセスします。
ALBにアクセスできるようになりました。
ルールのアクションがブロックからカウントだけになったため、アクセスが可能になったためです。
最後にサンプリングされたリクエストを確認します。
ブロックされたリクエストとカウントされたリクエストが1つずつ存在します。
最初のアクセスとルール変更後のアクセスです。
まとめ
ルールグループを自作して、WAF Web ACLを使った地理制限の方法を確認しました。