AWS WAF Rate-based ルールを使用して DDoS 攻撃を軽減する方法
AWS WAF は、 SQL インジェクションや XSS などのレイヤー7攻撃に対する保護を提供します。 Rate-based ルールを使用して DDoS 攻撃を軽減することもできます。 これにより、各 IP アドレスからの HTTP リクエストに対するしきい値を設定できます。
この投稿では、使用方法について説明します。
概要
以下にご注意ください。
- The minimum rate that you can set is 100. 1
- AWS WAF checks the rate of requests every 30 seconds, and counts requests for the prior 5 minutes each time. Because of this, it’s possible for an aggregation instance to have requests coming in at too high a rate for up to 30 seconds before AWS WAF detects and rate limits the requests for the instance. 2
- The maximum number of IP addresses that AWS WAF can rate limit using a single rate-based rule instance is 10,000. If more than 10,000 addresses exceed the rate limit, AWS WAF limits those with the highest rates. 3
AWS リソース作成
以下の内容を含む CloudFormation テンプレートを作成してください。
重要なポイントは Limit
と AggregateKeyType
(53-54行目) です。
この投稿では、100
をレート制限として使用しています。
AWSTemplateFormatVersion: 2010-09-09
Description: AWS WAF Rate-based rule sample
Resources:
S3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub aws-waf-rate-based-rule-sample-${AWS::AccountId}-${AWS::Region}
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
PublicAccessBlockConfiguration:
BlockPublicAcls: TRUE
BlockPublicPolicy: TRUE
IgnorePublicAcls: TRUE
RestrictPublicBuckets: TRUE
S3BucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref S3Bucket
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: cloudfront.amazonaws.com
Action: s3:GetObject
Resource: !Sub arn:aws:s3:::${S3Bucket}/*
Condition:
StringEquals:
"AWS:SourceArn": !Sub arn:aws:cloudfront::${AWS::AccountId}:distribution/${CloudFrontDistribution}
# AWS::WAFv2::WebACL must be deployed in us-east-1.
WAFv2WebACL:
Type: AWS::WAFv2::WebACL
Properties:
Name: aws-waf-rate-based-rule-sample
DefaultAction:
Allow: { }
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName: aws-waf-rate-based-rule-sample
Scope: CLOUDFRONT
Rules:
- Name: rate-based-rule
Priority: 0
Action:
Block: { }
Statement:
RateBasedStatement:
Limit: 100
AggregateKeyType: IP
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName: rate-based-rule
CloudFrontOriginAccessControl:
Type: AWS::CloudFront::OriginAccessControl
Properties:
OriginAccessControlConfig:
Name: aws-waf-rate-based-rule-sample
OriginAccessControlOriginType: s3
SigningBehavior: always
SigningProtocol: sigv4
CloudFrontDistribution:
Type: AWS::CloudFront::Distribution
DependsOn: CloudFrontOriginAccessControl
Properties:
DistributionConfig:
Origins:
- Id: !GetAtt S3Bucket.DomainName
DomainName: !GetAtt S3Bucket.DomainName
OriginAccessControlId: !Ref CloudFrontOriginAccessControl
S3OriginConfig:
OriginAccessIdentity: ''
DefaultCacheBehavior:
CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6
TargetOriginId: !GetAtt S3Bucket.DomainName
ViewerProtocolPolicy: allow-all
Enabled: true
ViewerCertificate:
CloudFrontDefaultCertificate: true
MinimumProtocolVersion: TLSv1
WebACLId: !GetAtt WAFv2WebACL.Arn
DefaultRootObject: index.html
以下のコマンドを使用して CloudFormation スタックをデプロイしてください。
Scope: CLOUDFRONT
を含む AWS WAFv2 Web ACL ルールは、 us-east-1
リージョンでデプロイする必要があります。 aws cloudformation deploy \
--region us-east-1 \
--stack-name aws-waf-rate-based-rule-sample \
--template-file template.yaml
以下のコマンドを使用して、サンプルの index.html
を S3 バケットにアップロードしてください。
echo '<html><body>Hello World!</body></html>' > index.html
aws s3 cp index.html s3://aws-waf-rate-based-rule-sample-<ACCOUNT_ID>-us-east-1
テスト
AWS WAF のレートチェック間隔は30秒なので、130秒以上、毎秒リクエストを送信してください。
AWS WAF ルールによってブロックされたリクエストが 403 Forbidden
のレスポンスを返すはずです。
AWS WAF checks the rate of requests every 30 seconds, and counts requests for the prior five minutes each time.
$ for i in `seq 1 130`; do echo "Request: $i"; curl https://<CLOUDFRONT_DOMAIN>/; echo "\n"; sleep 1; done
Request: 1
<html><body>Hello World!</body></html>
Request: 2
<html><body>Hello World!</body></html>
Request: 3
<html><body>Hello World!</body></html>
...
Request: 126
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE>ERROR: The request could not be satisfied</TITLE>
</HEAD><BODY>
<H1>403 ERROR</H1>
<H2>The request could not be satisfied.</H2>
<HR noshade size="1px">
Request blocked.
We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
<BR clear="all">
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
<BR clear="all">
<HR noshade size="1px">
<PRE>
Generated by cloudfront (CloudFront)
Request ID: xxxxxxxxxxxxxxxxxxxx
</PRE>
<ADDRESS>
</ADDRESS>
</BODY></HTML>
...
クリーンアップ
以下のコマンドを使用して、プロビジョニングされた AWS リソースを削除してください。
aws s3 rm --recursive s3://aws-waf-rate-based-rule-sample-<ACCOUNT_ID>-us-east-1
aws cloudformation delete-stack \
--region us-east-1 \
--stack-name aws-waf-rate-based-rule-sample
まとめ
Rate-based ルールを利用することで、 DDoS 攻撃を一定程度防げます。
この投稿が、お役に立てば幸いです。
Footnotes
-
https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-type-rate-based-high-level-settings.html ↩
-
https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-type-rate-based-request-limiting.html ↩
-
https://docs.aws.amazon.com/waf/latest/developerguide/listing-managed-ips.html ↩