AWS WAFを実際に使ってみた

記事タイトルとURLをコピーする
サーバーワークスの三井です。アメリカはラスベガス、re:Invent 2015の会場よりお届けしております!
 
さて、弊社ブログでもすでにアナウンスしておりますが、AWS WAFがリリースされました。
私の手元でもさっそく試してみました。

試してみる、ということで

 
実用性はひとまず置いておいて、
「コンテンツはCloudFrontで配信するが、弊社VPN拠点から、Chromeブラウザを使ってのアクセスのみ許可する」という良く分からない設定をしてみます。

前段として、今回はOregonリージョンで作成したElastic BeanstalkのSample Applicationのエンドポイントを、CloudFrontのOriginとして指定しました。ここの詳細は割愛します。
すでにCloudFrontのテスト用Distributionを持っている方は、それをそのまま使ってもらえればと思います。

AWS WAFは正式なサービスとしてローンチされていますので、Management Console画面上部のServicesから"Web Application Firewall"を選択して、すぐに利用を始めることができます。

mi-awswaf-services
 

Get Started!

 
ウィザードに従って作成を進めます。

Step 1: Name web ACL
適当なACL名を入力します。

mi-awswaf1

Step 2: Create conditions 
アクセスを許可/拒否するための条件を作成します。
まずはIPアドレスでのアクセス制限をかけたいので、弊社VPN拠点のIPアドレスを入力してみます。セキュリティグループの設定などと同様に、IPレンジでの指定なので、単一のIPアドレスからのアクセスだけを許可したい場合には末尾に/32を付けます。

 
mi-awswaf2

 
これだけだと面白くないので、「Chromeブラウザを使ってのアクセスのみ許可する」という要件を満たすためのString Matchの機能も試してみます。
これ、任意のリクエストヘッダを読み取って挙動を設定することが出来る(!)のですが、なんか面白いヘッダを考えてると次のセッションに間に合わないので、とりあえずこんな感じで「HeaderのUser-Agentに"Chrome"と含まれていた場合」というconditionを作成してみました。
 

mi-awswaf3
 


Step 3: Create rules 上記Step 2で作成したconditionに対する挙動を設定します。
まだこの時点では、conditonにマッチした場合に"許可する"のか、"拒否する"のかを指定していません。
今回は、conditionにマッチした場合のみアクセスを許可する、という実装がしたいので、
Default actionは"Block all requests that don't match any rules"にチェックします。
 

mi-awswaf4

 
ここまで行ったらReviewしてCreateします。このとき、ConditionやRule、Action等は表示されません。
 
作成したweb ACL一覧を見ると、"This web ACL doesn't contain any rules." と表示されています。
 
 
mi-awswaf5
どうやらウィザードに従って作成しただけだとダメで、型を作ってからEditしてあげる必要があるようです。
 

気を取り直してRule作成

WAF Management ConsoleのトップからRulesを選択すると、作成済のRuleの一覧が表示されます。

mi-awswaf6


 
ということで、まだ何もないのでCreate ruleをします。
 

mi-awswaf7

 
ここで条件(IPか文字列かSQLインジェクションか)を選択すると、先のウィザードで作成したconditionがプルダウンで選択できます。"Add another condition"で必要な数だけ条件を追加し、Createボタンを押してRuleを作成します。
 

web ACLとRuleの関連付け

WAF Management Consoleのトップに戻り、web ACLを選んでEdit web ACL -> Add rule to web ACLと進むと以下のような画面になります。
mi-awswaf8

  1. 先ほど作成したRuleの名前が選択できるようになっています。
  2. "Add rule to web ACL"を押すと、Ruleが追加されます。
  3. そのRuleに対するアクションを指定します。今回は、このRuleで指定したConditonにマッチした場合にのみアクセスを許可するので"Allow"を選択します。
  4. Save Changeすると準備完了です。

​いざ適用

 
WAF側の準備が完了したら、CloudFrontのDistributionと関連付けます。
CloudFront Management Console側のEdit Distribution画面で、作成したWeb ACLを指定して"Yes, Edit"を押下するだけで設定完了です。すると間もなくDistribution StatusがInProgressになります。
 

mi-awswaf10
 
すべてのEdge Locationに設定が伝播するまでには少し時間がかかるので、ここで私はモンスターエナジーを買いにホテルを出たところのWalgreensに行ってきます。(15分後、710ml缶のメガモンスター片手に帰ってくると、DistributionのStatusがDeployedに変わっていました)
 

試してみる

 
VPN接続を有効にしてアクセス元IPはマッチするようにしましたが、Safariからはアクセスできないはずです。
 
mi-awswaf-result1

 
Request blocked.と表示されていて、WAFのヘッダ識別機能が働いていることが分かります。
 
で、次です。Chromeからはアクセスできるはずです。
 
mi-awswaf-result2
 
Congraturations! ちゃんとSample Applicationにアクセスできています。

気になるパフォーマンス

 
オマケですが、WAFを有効化したときのパフォーマンスが少し気になったのでabでざっくり測定してみました。
以下はabでシンプルに100リクエスト投げて、処理完了までに掛かった時間です。
 
t2.microのBeanstalk単体 8.910 seconds
CloudFront 2.423 seconds
CloudFront + WAF 2.367 seconds
 
こうして見るとWAFを有効化すると若干早くなっていますが、恐らく誤差だと思います。数十回のオーダーで試行して平均を取れば同じぐらいになりそうです。

最後に

非常にお手軽にWAFの設定が完了しました。「CloudFrontを検証してみたいけど社外からはアクセスされたくない」といった比較的カジュアルなユースケースにはぴったりのサービスだと思います。料金は非常に安いのも魅力ですね。



re:Invent 2015もまだまだ2日目、これからどんな発表があるのか楽しみです。時間の許す範囲でブログ更新するつもりですので、ご期待頂ければ幸いです!