12
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

スクレイピングしてくる不届きものを、AWS WAFを使ってブロックする話

Posted at

概要

Webの集客をGAで監視していたところ、異様なトラフィックの増加が見られたので、スクレイピングされてるのでは…?と、対策することになったお話です。

Headless Chromeだけ弾く、とかいろいろ考えましたが、調べると現実的ではなさそうで、まずは、WAFで止めましょうという流れになりました。

結果

いくつかスクレイピングしてるだろう不届き者のIPを発見し、ブロックしてさしあげました。

やった処理は以下の通りです。

  1. 一定時間のアクセスが多すぎるIPを一時的に弾く
  2. BlackリストにいれたIPを弾く
  3. Whiteリストに入れたIPはBlackリストに引っかからないようにする

以下の図は、PV数を時間毎に表示したものですが、対策後の山が僅かに小さくなっていること、気づけますでしょうか?
(分母がそれなりに大きいので差分が分かりづらいですが)

image.png

WAF(Web Application Firewall)

WAF(ワフ)は、Webアプリケーションの脆弱性を狙った攻撃からWebサイトを保護するセキュリティ対策です。
Webサーバーの前段に設置して通信を解析し、不正なアクセスを弾きます。

AWS WAF

設置の仕方としては以下の設置方法があります。
①Cloud Frontの前段に設置して、Cloud Frontへのアクセスを監視する
image.png

②Cloud FrontとELB(ALB)の間に設置して、Cloud FrontからELBのアクセスを監視する
image.png

③Route53とELB(ALB)の間に設置して、Route53からELBのアクセスを監視する
image.png

ELBと同様にAPI Gatewayにも適用できます。

構成

今回のざっくりした構成はこんな感じです。
image.png

実装① 一定時間のアクセスが多すぎるIPをブロックする

AWSのコンソールを開いて、WAFと検索すると、「WAF & Shield」というページが見つかるはずです。
image.png

まず、最初にやることなのですが…
今回弾きたい対象に、cssやjsなど、Asset周りを含めるつもりはありません。
なので、その設定をおこなえるように、正規表現をあらかじめ作成しておきます。

正規表現のページから新規作成を行って行きます。
image.png

名前は分かりやすいものをつけて、弾きたかった/image/``/fonts/ /assets/を含めてくれるような正規表現を記載すれば完了です。
image.png

Web ACLsページからACLの新規作成に進みます。
※ACL: Access Control List --> IPに対してのルールをまとめたグループみたいなものです。

image.png

名前を入力します。名前を入れると自動的にCloudWatchのメトリクス名が入力されます。
※メトリクスも説明しておくと、CloudWatchはいくつもの情報の点を集積させてログを残していく仕組みなのですが、その点情報のグループにあたるものがメトリクスだと考えてもらえばいいかと。

リソースタイプの項目でCloudFrontに対して設置するのか、ELBまたはAPIGatewayに対して設置するのかを選択できます。
image.png

下段で、WAFに紐付けたいリソースを紐付けします。
image.png

次のページでルールを設定できます。
image.png

最初に実装したいのは、「一定時間のアクセスの多いIPを弾く」処理です。
「Add my own rules and rule goups」をまずクリックします。
image.png

IPListを使う処理ではないので「Rule builder」を選択します。

「Type」は「Rate-based rule」にします。
こうすることで、5分間のアクセスの数を設定することができます。
下段の詳細設定に許可するアクセス数を入力するだけです。
※100から設定できます。

詳細設定にあるラジオボックス。
これが以外と重要なのですが、「Consider all request」を選択してしまうと、すべてのIPに対してこのルールを適用してしまうことになります。
冒頭にも書きましたが、Asset周りのアクセスを同時にカウントして欲しくはないですよね。
ですので、「Only consider requests」を選択します。
image.png

そして、その次の段にでてくる設定で、正規表現に一致しないという条件を入れ、作った正規表現のパターンセットを選択します。
image.png

最後に、この条件に合う(五分間に指定した回数以上のアクセスがあった)場合にブロックするのか、またはカウントするだけなのかを選択すれば設定完了です。
image.png

実装の結果

でてくるでてくる。不届き者達。
最初びっくりさせられたのは5分間どころか10秒で500アクセスぐらいしてきてたIPがあったり。
(逆によく耐えてたな…サーバー)

↓WAFのACLsのダッシュボードです。
image.png

ブロックしたメトリックス(こちらもWAFのACLsのダッシュボード)を確認すると、どうやら同じIPが、順番にページを叩いていっているのが見える状況……
image.png

上手くいってるようにみえますが、ここで、もう一つ課題があります。

会社によっては同じルーターから外部にアクセスする場合が多いため、同じ場所の複数の人間が同時間にアクセスしてもこのルールに引っかかってしまう場合があるのです。
なので、あまり厳しい回数制限はできません。

そんなこんなで新たに以下の実装を加えるわけです。

  1. あからさまなクローラーはBlackリストへ
  2. 顧客になりそうなIPはWhiteリストへ
  3. 検索エンジン関連のクローラーはWhiteリストへ

実装② Blackリスト/Whiteリストの作成

まずは、IPがどこのものか調べます。
BlockされたIPを見て、これはAWSのサーバーだとか、これは某企業のサーバーだとか、仕分けします。

ページを順番に叩いていっている、サーバーっぽいIPは、Blackへ登録します。
image.png

名前をつけて、対象としたいIPを改行しながら追加していけばリスト完成です。
image.png
Whiteリストも同様の方法で作成します。

再度、Web ACLsのページに入り、Rulesからルールの追加をします。
image.png

今回は、IPリストを使うので、IPsetを選択します。

Blackリストであれば、IP setに先ほど作ったBlackリストのセットを選択し、Blockに。
Whiteリストであれば、Whiteリストのセットを選択し、Allowを選択します。
image.png

そして、ルールの優先度を
Whiteリスト → Blackリスト → 一定時間ルール
にすれば完成です。

image.png

実装の結果

Blackリストに入れたIPがしつこくアタックしてくるのが良くみえ、とても愉快な気分になりました。

実装してみて

たまに人力でIPを確認してやらないといけないので(ルールに引っかかってブロックされたものがあればメールで飛ばすようにしてますが)運用に少しだけ負荷がかかりますが、大事なデータを簡単にとられないようにするという目的はある程度達せられたのではないかなという感じです。

12
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?