はじめに
WAFを触ってみたかったので検証しました。
構成
前提
ユーザーデータでEC2にApachをインストールしてHello Worldしています。
UserData:
Fn::Base64: |
#! /bin/bash
yum update -y
yum install -y httpd
echo "<html><body><h1>Hello World</h1></body></html>" > /var/www/html/index.html
touch /var/www/html/.check_alive
chown apache:apache -R /var/www/html
systemctl start httpd.service
systemctl enable
WAFルール
- リソースはCloudFrontを選択する
IPset
作成した web ACL にアクセスを許可するIPアドレスを追加し、優先度で許可したIPリストを最後に評価するように設定します。今回は自宅のIPを許可リストに入れています。
下記のIPsetを作成し、上のルールに追加します。
CloudFront
CFnテンプレート(WebACL適用)
AWSTemplateFormatVersion: "2010-09-09"
Resources:
CloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Origins:
- DomainName: example.com ## 独自ドメイン
Id: example.com
CustomOriginConfig:
HTTPPort: 80
HTTPSPort: 443
OriginProtocolPolicy: match-viewer
Enabled: true
DefaultCacheBehavior:
TargetOriginId: example.com
ViewerProtocolPolicy: allow-all
AllowedMethods:
- GET
- HEAD
- OPTIONS
- PUT
- POST
- PATCH
- DELETE
CachedMethods:
- GET
- HEAD
- OPTIONS
CachePolicyId: "4135ea2d-6df8-44a3-9df3-4b5a84be39ad" # CatchingDisabled
OriginRequestPolicyId: "b689b0a8-53d0-40ab-baf2-68738e2966ac" # AllViewerExceptHostHeader
ForwardedValues:
QueryString: false
Cookies:
Forward: none
WebACLId: arn:aws:wafv2:us-east-1:<アカウントID>:global/webacl/<WebACLの名前>/<WebACLのID> # WebACL
PriceClass: PriceClass_All
Restrictions:
GeoRestriction:
RestrictionType: none
IPV6Enabled: false
Outputs:
CloudFrontURL:
Description: "CloudFront URL"
Value: !Sub "https://${CloudFrontDistribution.DomainName}"
テスト
$ curl https://d3i6dnmf977sr1.cloudfront.net
<html><body><h1>Hello World</h1></body></html>
- SQLインジェクション
- 以下のクエリが実行されるような引数をつけてアクセスしてみる
SELECT * FROM users WHERE key='10' or '1'='1';
$ curl https://d3i6dnmf977sr1.cloudfront.net/?key=%2710%27%20or%20%271%27%3d%271%27
<!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: tIeDx_hISel3C-3VvUikIPnRCBON0H2kJkRHquvfWCyLu1pE53Vj_A==
</PRE>
<ADDRESS>
</ADDRESS>
</BODY></HTML>
ステータスコードは403エラーでリクエストがWAFによってブロックされていることがわかります。
最後に
今回は簡単なルールでの検証だったが、理解度を高めて要件に合わせたチューニングができるようになりたい