WEBサイトを運営していると常につきまとう「直リンク」問題。これまで放置していましたが、ちょっと対策してみました。
備忘録兼ねて記事にします。
同じ環境で同じ悩みをお持ちの方、ちょっと長いですが、この通りにやれば目的は達成できると思います。
本記事のスクリーンショットは【AWS公式】クラウドならアマゾンウェブサービス からの引用です。
経緯
今回、フリー張り紙素材 はりがみやへの直リンクに対応することになった経緯ですが、
- これまでもリンクされまくっていた
- でも数がそれほどでもなかった
- 最近、数が激増
- 総リクエスト数の5%を占めるほどに!
- そろそろ対策するか・・・
という流れです。
5%とはいえ、画像なので転送量に対する割合はこの数倍の%になるはず。
これは・・・無視できない。
素材が使われるのは嬉しいんですけれども、ちょっと、うん。
直リンクとは
別名、ホットリンクとも。
WEBサイトの画像などに対し、無関係のサイトから「無断で」「画像だけ」を呼び出す行為です。
直リンされた側のメリット
何もありません。
直リンされた側のデメリット
転送量が増えます、アクセス回数によってはサーバに負荷もかかります。
ブログサービスなどであれば実害がないかもしれませんが、転送量が従量課金のAWSやAzureなどを使っていると請求額が増えてしまいます。
直リンする側のメリット
自分のサーバに一切負荷をかけずに画像を利用することが出来ます。
アップロードの手間もかかりません。
自サイトのコンテンツに見せかけられます。
直リンする側のデメリット
何もありません。違法行為にも当たらないそうです。
ということで、呼び出される側としては辛いだけ。
代わりに宣伝でもしてくれれば黙認するのですけども、そんなことも無いですし。
環境
AWS S3 + Cloudfront で配信しているサイトが前提です。
いわゆる静的サイトですね。
近年流行ってるみたいです。動的サイトは便利なんですけどもスケールアップ、スケールアウトのキリがないし、セキュリティも気になって夜しか眠れません。
素材配布サイトなら静的サイト一択ではないでしょうか。
WordPressでもStaticPressという静的なコードを出力してくれるプラグインがありますので、敷居は低いと思います。
直リンクしているサイトの調査
画像への直リンクはGoogle Analyticsなどのアクセス解析には乗ってきませんので、Cloudfrontの「Top referrers」から確認してみます。
リファラーに自サイト以外のURLが出ている場合は直リンクの「疑い」があります。
ですが、googleやyahoo、t.co など「好ましい」リンクもあります。それ以外の怪しいURLをリストアップします。
注意点としては「リファラスパムが含まれているかもしれない」ということです。
リファラスパムとはあえて参照元のURLをわかるように残し、有害なサイトへのアクセスを誘うものです。
URLをGoogle検索するだけでもなんとなく判別できますので、むやみにアクセスすることは避けたいところ。
AWS WAFの設定
WAFは使ったことがないので わかりにくそうな公式ドキュメントは避けつつ 先人の知恵を探したのですが、「WAF Classic」に関する記事しか見当たらず。
現在は「New AWS WAF」と、新しくなっています。差がよくわかりませんが、新しいものは良いものということで試行錯誤した結果、この記事を書くに至ります。
全体の流れは以下の通り。
- 正規表現パターンを作成
- Web ACLに適用
- 動作確認
条件の確認
直リンクを排除する条件を整理しておきます。
- 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を押して、設定画面へ。
肝心の正規表現ですが、適当に以下のように書いてみました。
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
スクショを参考にしてください。ここは大した内容ではありません。
Rules
マネージドルールにすると各ベンダーが提供しているルールセットを適用することが出来ます(別料金)。
今回はリファラチェックだけなので、自分でルールを作成します。
Rule type
レイヤ3(IPアドレス)でチェックするのか、レイヤ7を見るかを選択します。
マッチング条件の入力
ここから大事な所。
直リンク元の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
マッチしたらどうするかを決めます。
最終的には「Block」したいのですが、ルールに間違いがあって全断でもされたら困ります。
まずは「Count」でルールがマッチするかどうか様子を見ます。
動作確認
自分でアクセスしたり、直リンクされているページを知っていればそこにアクセスしてみます。
Web ACL作成後、5分もすればログが確認できるはずです。
Web ACLsの一覧から作成したACLを選択すると「Overview」という画面でグラフが確認できます。
- 緑の線: ブロックされなかったリクエスト数
- オレンジの線: ブロック対象のリクエスト数
となっています。
ほぼ全てが許可されて、ごく一部がブロック対象となっています。問題なさそうです。
ここまで確認できたら、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が簡単に導入できるなんて。