「AWS Black Belt Tech Webinar 2015 ‐ AWS WAF」レポート
こんにちは、虎塚です。
12月9日(水)のAWS Black Belt Tech Webinarを聴講したので、レポートします。テーマは、re:Invent 2015でリリースされた新サービスのAWS WAFです。講師は、アマゾン ウェブ サービスの荒木さんでした。
AWS Black Belt Tech Webinarは、オンラインで受講できる無償のセミナーです。今後の予定は、国内のクラウドセミナー・イベントのスケジュール | アマゾン ウェブ サービス(AWS 日本語)のオンラインセミナーの項で確認できます。
AWS WAFとは
なぜAWS WAFを導入するか
まず、そもそもAWS WAFは何に対応してくれるのか、なぜAWS WAFを導入するかについて。
- アプリケーション脆弱性への対応
- システムがExploit Code(問題のあるコード)を含んでいるときに、問題が顕在化しないようにするため
- 悪用 (Abuse) への対応
- Webサーバに置かれたファイルやデータを正当でない方法で取り出そうとする行為を防ぐため
- (例) ECサイトのの商品データを、私的な目的で使うために取り出そうとする行為を防ぐ。ECサイトの運営者からすると、サイトを訪問して、売り上げにつながるアクションを取ってほしいのであって、商品データだけ抜き出されることは避けたい
- Application DDoSへの対応
- アプリケーションの実装の弱点を突くような高度な攻撃に対応するため
AWS WAFとはなにか
- AWS WAFは、Amazon CloudFrontに着目して実装された
- Webサーバに到達する前の段階のエッジロケーションで、悪意のあるリクエストを防ぐ
- あらかじめAWS WAF ルールを書いておくことで、あとから効果を得る
- 良いユーザからのトラフィックを許可し、悪いユーザからのトラフィックを拒否する
- 動作結果をCloudWatchを通じてnearリアルタイムでモニタリングできる
WAF (Web Application Firewall) とは
- HTTPトラフィックを制御するルールセットのこと
- WAFの提供方法は主に次の4種類
- Pure Play (スタンドアロン)
- CDNにバンドル
- Load Balancerにバンドル
- UTM製品の一機能として
なぜWAFを使うのか
WAFは、Webサイトやアプリケーションが攻撃されて、外部にデータが漏洩しないようにする手助けをするために使う。よくあるのが次のユースケース。
- SQLインジェクションやクロスサイトスクリプティングへの対策
- アプリケーション開発者には必須の知識だが、場当たり的に実装したコードが残るシステムや、危険なコードが故意に混入されたシステムも存在する。そういったシステムを安全に保つためには必要
- Webクローラやスクレイピングなどのbot対策
- βテスターだけにシステムを使わせたい場合にも
- DDoS緩和
- コンプライアンス対応
- ガートナーのレポートによると、WAF導入理由の25-30%がPCI-DSS対応とのこと。多くの企業が、クレジットカード情報を扱うための対応の一環でWAFを導入している
- 参考: Magic Quadrant for Web Application Firewalls
AWS WAFでできること
AWS WAFでできることは、大きく3つある。
- ルールによるトラフィックのフィルタ
- SQLインジェクションやXSSのようなよくある攻撃への対策
- Amazon作成のルールを適用
- 対策結果のモニタリング@AWS CloudWatch
これまでのWAF
AWSおよびAWSユーザが、これまでのWAF製品に不満をもっていたため、AWS WAFが開発された。たとえば、次のような点に不満があった。
- 設定が複雑で時間がかかる
- 機能が多くなり、ルールが増えるにつれ、誤検知 (false positive) が増えて悩むことになった
- APIが提供されないケースが多い
- APIによる使い勝手の向上よりも、機能の増強に製品開発の主眼が置かれてきたのかもしれない
- 導入費用、維持費用が高い
- 高度な機能を使いこなせなくてプロフェッショナルサービスの購入が必要になりがち
- 見積りが過大になりがち
- ライセンスが年額設定であることや、購入時に最大トラフィックの見積りが必要で、購入ライセンス数を超えたアクセスがきたら503エラーを返す設定や、逆にすべてパススルーする設定が強制されることなど
お客様の要望に応じて実現したAWS WAF
AWS WAFには、次のような特長がある。
- 簡単に使いはじめられる
- ルールを柔軟にカスタマイズできる
- DevOpsと統合できる
上記を従量課金で利用できて、スモールスタートができる。
AWS WAFとMarketplaceで扱われているWAFの違い
AWSがこれまでAWS Marketplaceで提供してきた他社のWAF製品と、AWS WAFとの違いは何かについて。
まず、当然ながら両者は異なる製品なので、実現できることが違う。次に、MarketplaceのWAFはEC2上で動くため、いろいろ設定できる反面、スケールさせるためには設定の作り込みが必要だったり、スケーリング時のライセンス条項をクリアする必要があったりした。AWS WAFはそのあたりを気にしなくてよい。
WAFとCloudFront
AWS WAFが登場する前のCloudFront構成
CloudFrontを構成すると、Webアプリケーションを高速に配信できるようになる利点がある反面、悪意をもったトラフィックをも通してしまう弱点があった。クラッカーや悪意のあるbotからの攻撃であっても、HTTP/HTTPSであればエッジロケーションを通してしまっていた。
これまでのWAF構成
上記の状況に対処するため、これまでは顧客のオンプレミス環境にWAFを置く構成や、ELBでWAF層をサンドイッチする構成を推奨してきた。
WAF層のサンドイッチ構成とは、最前面のELB -> Auto Scaling Group配下のWAF層 -> 背面のELB -> Webサーバ群という構成のこと。これでは構成が複雑になり、レイテンシも増加してしまう。
CloudFrontと統合したAWS WAF
世界に50数カ所あるエッジロケーションにあるWAFで、悪意のあるトラフィックがブロックされるため、バックエンドサーバの負荷が下がり、利用費も下げられる可能性がある。
CloudFrontをEC2以外と組み合わせて利用している場合もあると思うが、バックエンドはHTTP/HTTPSでさえあればどこにあってもよい(AWS外でもよい)。また、静的コンテンツでも動的コンテンツでもOK。
CloudFrontとの組み合わせにはこういった利点があることから、AWSはまずCloudFrontと組み合わせてAWS WAFをリリースした。
AWS WAFコンポーネント
AWS WAFは、次のコンポーネントから構成されている。
- WebACL (Web Access Control Lists) : ルールセット
- 条件 : IPアドレス、文字列、SQLインジェクション
- ルール : 順番、アクション
- AWSリソースとの紐付け(現時点ではCloudFrontをサポート)
- 動作レポート
AWS WAF: WebACL
- WebACLは、condition, rules, actionから構成される
- WebACLは、1つ以上のCloudFrontディストリビューションに適用できる
- たとえば、ブランドサイトを複数持っていて、CloudFrontディストリビューションが10個ある場合、1つのWebACLルールセットを10個に適用できる。ルールセット1つだけをメンテナンスすればよい
AWS WAF: Conditions
conditionsは、Webリクエストに対して、次のような内容で一致判定をおこなう。各conditionsはORで結ばれて評価される。
- IPアドレス (CIDR形式)
- 文字列 (URI、クエリ文字列、ヘッダ)
- SQLインジェクション
IPSets
- 1つのIPアドレスだけに一致させるには、末尾に/32をつける
- IPSetは1000個まで
- WebACLあたり合計1万個まで書ける
- 超えないように、CIDRにある程度まとめて書く
文字列とバイト
Webリクエストの内容と照合する。照合可能なのは、HTTPのヘッダだけであることに注意。HTTPのボディの中身に対するWAF機能は、現時点では提供されていない。
HTTPのヘッダを参照してできることとして、たとえば、User-Agentに含まれる文字列を判定してアクションを定義できる。
文字列にちょっとひねりを入れられても、ルールのtransform設定で対応できる。たとえば、transform設定を「To lower」とすることで、文字列に大文字小文字が混入していても大丈夫。次のようなtransform設定が可能。
- 小文字変換
- HTMLデコード
- 空白除去
- コロンを入れる(simplify command line)
- URLデコード
完全一致、先頭一致、末尾一致などをサポートしている。
また、バイナリに対しては、base64エンコードを利用する。
SQLインジェクション
URLデコード後、クエリ文字列にSQLインジェクションがないかをチェックする。一般的なSQLインジェクションの例は、OWASPなどで公開されている。
AWS WAFで利用できるのは、あらかじめ定義されたコードのみとなる。ユーザは、完全一致や空白除去などの設定の工夫はできる。
AWS WAF: Rules
ルールとは、あらかじめ決めた条件とアクションのセットを指す。利用可能なアクションは次の3つ。ルール同士は論理的にANDで結合している。
- Block
- Allow
- Count
AWS WAFを本番導入した直後にはマッチした条件のカウントだけをおこない、マッチする数が多い場合にそのルールを有効化する、といったこともできる。
conditionsの再利用
ルールは、複数のWebACLに適用できる。ブラックリストを複数のWebACLで再利用できる。
たとえば、1人のサイト管理者が複数のブランドサイトを運用している場合に、本番導入前には共通ルールを使う、といったことができる。
AWS WAF: Resource
WebACLの適用対象は、現時点ではCloudFrontだけ。
ルールは再利用可能で、1つのWebACLを複数のCloudFrontディストリビューションに対して使える。もちろん個別に設定することもできる。
AWS WAF: レポートとログ
リアルタイムメトリックスとして、AWS WAFの動作をCloudWatchで見ることができる。時系列で見たり、特定の時間帯にドリルダウンしたりすることができる。条件での絞り込みもできる。
AWS WAFのログは、CloudFrontと統合されている。AWS WAFだけの独立したログを出力する仕組みはない。そのため、15分ほどの遅延が必要となる。もっと早く見たい場合は、レポート機能を使う。
AWS WAFのリクエストプロセス
- ユーザからCloudFrontにHTTP/HTTPSのリクエストがくる
- CloudFrontがAWS WAFの対象かどうかを判定する
- AWS WAFがリクエストをレビューして、CloudFrontにallowかdenyかを伝える
- allowならCloudFront経由でユーザにコンテンツが配信される
- AWS WAFはメトリクスをCloudWatchに流しつづけているので、管理者はいつでも確認したり、ルールを変更したり、アラートを設定したりできる
費用例
- テスト使用として1ルール: $6/月
- 小さいサイトで6ルール、5800万view: $46/月
- 中くらいのサイトで6ルール、2億6000万view: $167/月
試しに使いやすい価格設定とのこと。すでに他のWAF製品をシステムに導入している場合も、AWS WAFを有効化することで、オリジンにより近いWAFの負荷を下げる効果が期待できるかもしれない。
AWS WAFの利用戦略
ルール戦略
WAFのルール戦略には、ポジティブとネガティブがある。
多くのサイトではネガティブ戦略を採用している。これは、デフォルトがallowで、悪意のあるリクエストをblockする方針のこと。国別にGeoIPの情報と組み合わせたり、マルウェア配布実績のあるレンジを丸ごとブロックしたりする。
一方、ポジティブ戦略は、テスト目的でよく使われるデフォルトがblockの方針のこと。ゲーム会社がベータテストユーザからのアクセスだけを許可するために使ったり、自社オフィスからのアクセスだけに制限したりするために使う。
緩和戦略
- Static policies
- よく知られた脅威向け
- 例: ModSecurityのルール
- Reactive policies
- 手法が変化する脅威向け
誰がルールを作るかが大事。Alert Logic、Imperva、Trend MicroなどのAWS WAFパートナー企業がルールを提供(予定)なので、使用するとよい。
カウント機能で脅威発見
AWS WAFをカウントモードで利用し、ルールマッチが一定数を超えたらCloudWatchのアラートが上がるようにしておく。アラートが上がったら、サンプルリクエストを取得して、ブラックIPアドレスリストに追加する。
1秒ごとにアクセスがきたり、接続元IPアドレスを分散したりしない場合などは、簡単に見ることができる。99%のよくある攻撃への備えは簡単。残りには、脅威発見の方法を使う。
典型的な使い方
- IPアドレスのホワイトリスト: ALLOW
- IPアドレスのブラックリスト: BLOCK
- ブラックリストシグネチャ: BLOCK
- SQLインジェクション: COUNT
- 疑わしい振る舞い: COUNT
デフォルトはALLOWにしておく。上記のように4と5でカウントした結果、攻撃の恐れがあるものを2のブラックリストに追加する。
レポート自動化の流れ
- SQLインジェクションや疑わしい振る舞いをAWS WAFがカウントして、CloudWatchに投げる
- 一定数を超えるとSNSでアラートを上げる
- AWS LambdaでAWS WAFからサンプルリクエストを取得する
- AWS Lambdaでサンプルリクエストをルールとして整形して、AWS WAFに設定する
- Eメールでオペレータにルール更新を通知する
たとえば、普段は秒間100アクセスも来ないサイトに、それを超えるアクセスがあれば、アラームを上げるようにしておく。サンプルリクエストを確認して、AWS WAFに自動的に反映させる。
AWS WAFウォークスルー
AWS WAFのEnd to Endの流れを見るデモ。
- WebACLを作る
- conditionsを作る
- rulesとactionsを作る
- WebACLをCloudFrontに適用する
- レビュー
APIを利用してWAFリソースを更新する
- AWS WAFリソースを変更するためのワンタイムトークンを取得する
- 変更にトークンを使用する
- ステータス確認のためにトークンを使用する
トークンベースの操作になる。トークンを使ってアクセスし、どこまで反映されたかを確認する。
GetChangeToken APIでトークンが返ってくる。リージョン指定は不要。AWS CLIでは次のようになる。
$ aws waf get-change-token
Create* APIでWebACLを作成する。
$ aws waf create-web-acl \ --name Test \ --metric-name Test \ --default-action Type=ALLOW \ -- change-token <先ほど取得したトークン>
AWS WAFへの反映状態は、GetChangeTokenStatus APIで確認できる。PROVISIONED、PENDING、INSYNCの3種類の状態がある。INSYNCは変更中を意味する。
$ aws waf get-change-token-status \ -- change-token <先ほど取得したトークン>
PENDINGやINSYNCが戻ってきたら、この呼び出しを繰り返す。ただし、繰り返しすぎないように気をつける。AWSのSDKからAPIサーバへ送信するときは、失敗したら次回リクエストまでの間隔を徐々に開けるようにする。通常は1分くらいで反映される。
IPSetsの更新は、Update*Set APIを利用する。更新内容をJSON形式で渡す。(ActionはINSERT)
$ aws waf update-ip-set \ --ip-set-id \ -- change-token <先ほど取得したトークン> \ --updates \ [{ "Action" : "INSERT", "IPSetDescriptor" : { "Type" : "IPV4", "Value" : "192.168.0.0/16" } }, [...] ]
GetSampledRequests APIを呼び出して、サンプルリクエストを取得する。最大3時間前までにおこなわれた最大500リクエストを取得できる。
これまでのリクエスト数が500に満たない場合は、ほとんどすべてのリクエストを取得できると思われるが、必ず100%取得できることは保証していない。とはい え、同じような攻撃パターンを把握するには十分使える。
APIを利用したウォークスルーはここまで。
悪いロボットを動的に退治する方法
最後に、悪意のあるロボットを動的にブロックする例を紹介する。
- IPSet:ブロックするIPアドレスのリスト
- Rule: 上記のIPSetにマッチしたらブロックするという内容
- WebACL: デフォルト許可
悪いボットの検出方法
世の中に出回っているリストを使う以外に、Webサイトに置いたrobots.txtにスクレイピング禁止条項を書いておく方法がある。
robots.txtで禁止したコンテンツへのリンクを、隠しリンクとしてページに記述する。そして、robots.txtの禁止条項を無視して隠しリンクへアクセスするものがあれば、弾く。
悪いボットのIPアドレスをIPSetに追加する方法
隠しリンクをリクエストされたら、トリガースクリプトが動くようにする。スクリプトでは、次のことをおこなう。
- ソースIPアドレスの検出
- トークン変更
- ソースIPアドレスをIPSetのブラックリストに追加
こうすることで、WebACLが、悪いボットから引き続きおこなわれるリクエストをブロックできる。コマンドを整形するメタなシェルスクリプトを作って、その中でAWS CLIを呼びだそう。
Q&A
- Q. CloudFrontを使ってもAWS WAFを使っても、直接オリジンサーバやELBにアクセスされたら意味がないのではないでしょうか?
- A. はい、そうですね。そこで、CloudFrontを介したリクエストには、CloudFrontからアクセスしたことを示すHTTPヘッダ情報を入れています。そのヘッダを持つリクエストに対してだけ200 OKを返して、そうでないリクエストは本来のトップページにリダイレクトするなどしてください。リダイレクトした結果、AWS WAFを通すようにしてください。
- Q. conditionsのヘッダに対する指定の書き方は?
- A. 文字列の条件指定で書けばOKです。バイナリは、URLエンコード、デコードを使ってください。
- Q. HTTPヘッダだけを条件として動くそうですが、ボディも対象にしてください。
- A. Webアプリケーションには通常GETだけでなくPUTもあるので、そういった要望は多いです。詳細な計画はいえませんが、将来的に対応予定です。
- Q. WebACLの最大数は1万個のCIDRブロックまでとのことですが、上限緩和できますか?
- A. できません。1万個を超えるCIDRが必要なくらい大きなお話がありましたら、個別に相談してください。インターネットにおける経路集約の話と一緒で、まとめて書くことができるIPアドレスなどありますので、AWSのSAがコンサルティングします。GeoIPも使えます。CloudFrontのロケーションでアクセス制限もできるので、それと合わせて使ってみてください。
- Q. 文字列の判定方法は、完全一致、前方一致、後方一致などとのことですが、他はないのでしょうか?
- A. 正規表現対応のリクエストが多くありますが、提供していません。いずれあるかもしれませんが。
- Q. AWS WAFのパフォーマンスはいかがでしょうか?
- A. 自信があります。導入してお試しください。そもそもCloudFrontの導入による遅延がほぼありませんが、そこに対するオーバーヘッドは数パーセントのはずです。もし実際にすごく遅くなってしまった場合は、サポートケースを上げてください。
- Q. allow/denyの結果に関係なく、発生した通信量によって費用がかかるのですか?
- A. はい。まず、AWSではインバウンドのトラフィックは無料ですが、アウトバウンドは有料です。CloudFrontやAWS WAFで処理したリクエスト数に対しては、利用費がかかります。
- Q. (CIDRブロックの書き方の話)
- A. 0.0.0.0/1など大きな範囲のdenyをして、54.XX.XX.XXなど小さな範囲をallowと書きたくなるかもしれませんが、逆です。より広い判定条件を後ろにまわしてdenyにしてください。
おわりに
AWS WAFがCloudFrontと組み合わせて使えることの利点がよく理解できるウェビナーでした。
具体的なウォークスルーも、実際に設定をおこなう上で参考になりますね。カウントモードからルールへの反映までの自動化や、誘い込んだbotをブラックリストに追加する作業の自動化などは、AWS Lambdaと組み合わせることでとても便利に使えそうです。
それでは、また。