[Dr.WEB][Ruby] Racl を使った国内限定コンテンツ

以前に Dr.WEB CureIt! を国外から連続してダウンロードする輩がいて Apache が悲鳴を上げたことがあり、IP アドレスを調べてある程度の範囲をブロックしていました。が、誤爆してしまうケースが多々あってどうしようかなぁ、と思っていたところ、id:y-kawaz さんの mod_rewrite で RBL を使ったアクセス制御を行う という記事を見つけました。


よっしゃ! ということで単なる真似ですが、Ruby と Racl を使って CureIt! の配信対象を制限してみました。まず apache の設定はこんな感じです。

# People outside Japan gets CureIt! from ftp.drweb.com
RewriteMap  racl-map prg:/path/to/bin/raclmap.rb
RewriteCond %{REQUEST_URI} ^/path/to/cureit.exe$
RewriteCond ${racl-map:%{REMOTE_ADDR}} NOT_REGISTERED
RewriteRule (.*) ftp://ftp.drweb.com/pub/drweb/cureit/cureit.exe [R]

Ruby スクリプトはこんな感じです*1

#!/usr/local/bin/ruby
require 'resolv'

$stdin.sync = true
$stdout.sync = true

RACLSERVERS = %w(rbl.example.jp)
while ipaddr = $stdin.gets
  ipaddr.chomp! 
  RACLSERVERS.each do |rbl|
    revip = ipaddr.split(/\./).reverse.join('.')
    begin
      Resolv.getaddress "#{revip}.#{rbl}"
      $stdout.puts "REGISTERED"
    rescue Resolv::ResolvError
      $stdout.puts "NOT_REGISTERED"
    rescue
      $stdout.puts "REGISTERED"
    end
  end
end

exit 0

ちなみに RBL 形式なので登録されていないと Resolv::ResolvError が上がってきますが、本当はこのエラーでまとめてハンドリングするのは良くない気がします。もっと良い書き方があればご教授ください m(__)m。

*1:Racl を使うには無償ユーザ登録が必要だそうなので、スクリプト中では RBLDNS サーバを伏せてます。