外部から勝手にリンクされて困ってしまう場合、特に画像や動画ファイルなど比較的重たいファイルを勝手にリンクされてしまうと帯域を無駄に使ってしまい、困ってしまうことがあると思います。
そこでリファラを使って、直リンクされている場合に403を返すようにmod_rewriteを使ってみます。
今回はそれを簡単にするために、直リンクを許可するドメインをリスト化し、RewriteMapを使って処理したいと思います。
RewriteMapについては下記の記事でも取り上げています。
Apacheのmod_rewriteを使ってフェイルオーバー? – フタなしカンヅメ
Apacheの設定ファイルは以下のようにします。
<IfModule mod_rewrite.c> RewriteEngine On # 必ずロックファイルを指定 RewriteLock /tmp/map.lock # RewriteMapで使う外部プログラムを指定 RewriteMap referercheck-map prg:/usr/local/bin/referer_check.rb </IfModule> <Directory /> RewriteEngine On RewriteCond %{REQUEST_FILENAME} \.(gif|png|jpg|jpeg|bmp)$ [NC] RewriteCond ${referercheck-map:%{HTTP_REFERER}|NG} ^NG$ RewriteRule ^.*$ / [L,F] </Directory>
許可ドメインリストを読み取って処理する「referer_check.rb」の中身です。
#!/usr/bin/env ruby $stdin.sync = 1 $stdout.sync = 1 require 'uri' CHECK_OK = 'OK' CHECK_NG = 'NG' list_file = '/usr/local/etc/referer_list' referer_list = [] File::open(list_file) do |f| while line = f.gets referer_list << line.chomp if line.chomp[0, 1] != "#" end end while true flag = nil buffer = $stdin.gets referer = URI.encode(buffer.strip) if referer.empty? flag = true else begin uri = URI.parse(referer) flag = referer_list.any? {|v| uri.host.include?(v)} if uri.host rescue Exception # end end $stdout.puts(flag ? CHECK_OK : CHECK_NG) end
referer_check.rbには実行権限が必要ですので注意してください。リストファイルは、一行ずつ許可ドメイン(ホスト)を記述します。
example.com example.co.jp
許可するドメインが増えたら、リストを更新するだけで対応できるので、ちょっと簡単?になった気がします。今回は許可ドメインということでしたが、同じように拒否ドメインリストで対応ってことも可能だと思います。