New AWS WAFによる直リンク対策

WEBサイトを運営していると常につきまとう「直リンク」問題。これまで放置していましたが、ちょっと対策してみました。

備忘録兼ねて記事にします。

同じ環境で同じ悩みをお持ちの方、ちょっと長いですが、この通りにやれば目的は達成できると思います。

本記事のスクリーンショットは【AWS公式】クラウドならアマゾンウェブサービス からの引用です。

 

 

経緯

今回、フリー張り紙素材 はりがみやへの直リンクに対応することになった経緯ですが、

  • これまでもリンクされまくっていた
  • でも数がそれほどでもなかった
  • 最近、数が激増
  • 総リクエスト数の5%を占めるほどに!
  • そろそろ対策するか・・・

という流れです。
5%とはいえ、画像なので転送量に対する割合はこの数倍の%になるはず。

これは・・・無視できない。

素材が使われるのは嬉しいんですけれども、ちょっと、うん。

 

直リンクとは

別名、ホットリンクとも。
WEBサイトの画像などに対し、無関係のサイトから「無断で」「画像だけ」を呼び出す行為です。

直リンされた側のメリット

何もありません。

直リンされた側のデメリット

転送量が増えます、アクセス回数によってはサーバに負荷もかかります。
ブログサービスなどであれば実害がないかもしれませんが、転送量が従量課金のAWSやAzureなどを使っていると請求額が増えてしまいます。

直リンする側のメリット

自分のサーバに一切負荷をかけずに画像を利用することが出来ます。
アップロードの手間もかかりません。
自サイトのコンテンツに見せかけられます。

直リンする側のデメリット

何もありません。違法行為にも当たらないそうです。

 

ということで、呼び出される側としては辛いだけ。
代わりに宣伝でもしてくれれば黙認するのですけども、そんなことも無いですし。

 

環境

AWS S3 + Cloudfront で配信しているサイトが前提です。

いわゆる静的サイトですね。
近年流行ってるみたいです。動的サイトは便利なんですけどもスケールアップ、スケールアウトのキリがないし、セキュリティも気になって夜しか眠れません。

素材配布サイトなら静的サイト一択ではないでしょうか。

WordPressでもStaticPressという静的なコードを出力してくれるプラグインがありますので、敷居は低いと思います。

ja.staticpress.net

 

直リンクしているサイトの調査

画像への直リンクはGoogle Analyticsなどのアクセス解析には乗ってきませんので、Cloudfrontの「Top referrers」から確認してみます。

f:id:trial-and-error:20210504120346p:plain

リファラーに自サイト以外のURLが出ている場合は直リンクの「疑い」があります。

ですが、googleやyahoo、t.co など「好ましい」リンクもあります。それ以外の怪しいURLをリストアップします。

注意点としては「リファラスパムが含まれているかもしれない」ということです。
リファラスパムとはあえて参照元のURLをわかるように残し、有害なサイトへのアクセスを誘うものです。

URLをGoogle検索するだけでもなんとなく判別できますので、むやみにアクセスすることは避けたいところ。

 

AWS WAFの設定

WAFは使ったことがないので わかりにくそうな公式ドキュメントは避けつつ 先人の知恵を探したのですが、「WAF Classic」に関する記事しか見当たらず。

現在は「New AWS WAF」と、新しくなっています。差がよくわかりませんが、新しいものは良いものということで試行錯誤した結果、この記事を書くに至ります。

全体の流れは以下の通り。

  1. 正規表現パターンを作成
  2. Web ACLに適用
  3. 動作確認

 

条件の確認

直リンクを排除する条件を整理しておきます。

  • HTTP ヘッダーのRefererに
  • さきほどリストアップしたFQDN(URL)が含まれ、
  • さらに
  • リクエストURIに
  • jpg / png / pdfが含まれる

この2つの条件を満たすものを排除します。

画像やPDF等のメディアファイルに限定するのは、通常のページ(.html)へのアクセスは大歓迎なので。

 

正規表現でURLと画像を指定する

「Regex pattern sets」メニューから、リストアップしたURL全てと、拡張子全てを含む正規表現を作成します。

この正規表現に対してWeb ACLを適用します。

いきなりWeb ACLsで作成に進んでもよいのですが、条件(ルール)の指定が1個ずつになってしまうはず。

そうなるとルール数が増えて、コストも余計にかかってしまいます。ちなみに1ルールにつき1ドル/月。

さて、それでは作っていきます。

Create regex pattern setを押して、設定画面へ。

f:id:trial-and-error:20210504125525p:plain

肝心の正規表現ですが、適当に以下のように書いてみました。

URL(FQDN)の場合

^.*(example\.jp|example\.com|example\.net).*$

https://example.com/index.html のような文字列にマッチさせたいので、FQDNの前後に任意の文字列を指定しました。

「|」で区切ることでFQDNを増やすことが出来ます。上限はどのぐらいなのでしょうか・・・。

「Macでバックスラッシュが打てないぞ!?」となった方へ、「option + ¥」で打てます。

画像を指定する場合

^.*(jpg|png|pdf)$

拡張子は最後に出現するはずなので、任意の文字列の後に、jpgなどの文字列で終了するという表現にしました。

この2種類のパターンを別々のRegex Patternとして作成します。

  • FQDNのマッチング用で1つ
  • 画像のマッチング用で1つ

2つのパターンを作成しました。

 

Web ACLsの作成

Web ACL details

スクショを参考にしてください。ここは大した内容ではありません。

f:id:trial-and-error:20210504130908p:plain

 

Rules

マネージドルールにすると各ベンダーが提供しているルールセットを適用することが出来ます(別料金)。
今回はリファラチェックだけなので、自分でルールを作成します。

f:id:trial-and-error:20210504131148p:plain

 

Rule type

レイヤ3(IPアドレス)でチェックするのか、レイヤ7を見るかを選択します。

f:id:trial-and-error:20210504131445p:plain

 

マッチング条件の入力

ここから大事な所。

f:id:trial-and-error:20210504132254p:plain

直リンク元のURLを判定するルールはこちら(スクショの内容)

  • Inspect: Header
  • Header field name: Referer
  • Match type: Matches pattern from regex pattern set
  • Regex pattern set: 作成した正規表現パターン(URLリスト)

アクセス先URLが画像かどうか判定するルールはこちら

  • Inspect: URI path
  • Match type: Matches pattern from regex pattern set
  • Regex pattern set: 作成した正規表現パターン(拡張子リスト)

 

Then

f:id:trial-and-error:20210504132646p:plain

マッチしたらどうするかを決めます。

最終的には「Block」したいのですが、ルールに間違いがあって全断でもされたら困ります。
まずは「Count」でルールがマッチするかどうか様子を見ます。

 

動作確認

自分でアクセスしたり、直リンクされているページを知っていればそこにアクセスしてみます。

Web ACL作成後、5分もすればログが確認できるはずです。 

Web ACLsの一覧から作成したACLを選択すると「Overview」という画面でグラフが確認できます。

f:id:trial-and-error:20210504133612p:plain

 

  • 緑の線: ブロックされなかったリクエスト数
  • オレンジの線: ブロック対象のリクエスト数

となっています。 

ほぼ全てが許可されて、ごく一部がブロック対象となっています。問題なさそうです。
ここまで確認できたら、Web ACLsをEditして、「Count」を「Block」に変更して完了です。

 

ブロックした時の動き

ブロックされる条件でアクセスしたときにChrome デベロッパーツールを見ると、ステータスコード404が返っています。

当サイトではCloudfrontの「Error Pages」で、403を404に変えて応答するように設定しているので、本来であれば403が返ってくる、はず。

たぶん。

 

料金

  • ACL 1個につき 5ドル/月
  • ルール1個につき 1ドル/月
  • 100万リクエストあたり 0.6ドル

このような価格体系になっています。

今回はACL1個と、ルール1個を追加したので6ドル/月が固定で追加され、さらにリクエスト数が従量課金ですね。

今のWEBサイトの規模からすると、正直割高に感じますが必要経費といったところでしょうか。

それにしてもAWSはすごいですね。WAFが簡単に導入できるなんて。