人力検索に応えてみた。
question:1136813234の質問に答えてみた。
class Observation def Observation.start(arg) Observation.new.start(arg) end def initialize @blacklist = Hash.new{|hash,key| hash[key] = 0} @judgement = 10 end def start(target) pipe = IO.popen(”tail -f #{target}”,’r’) loop do if (input = pipe.gets) result = analyze(input) if result[’protocol’] =~ /ssh/ && result[’success?’] == false add_black(result[’ip’]) end add_deny(result[’ip’]) if @blacklist[result[’ip’]] > @judgement end end end def analyze(str) flag = true ary = str.split date = ary.slice!(0..2).join(’ ’) host = ary.shift protocol = ary.shift if pos = ary.index(’from’) ip = ary.slice!(pos + 1) end flag = false if ary.include?(’not’||’invalid’) return {’date’ => ”#{date}”, ’host’ => ”#{host}”, ’protocol’ => ”#{protocol}”, ’ip’ => ”#{ip}”, ’success?’ => ”#{flag}”} end def add_black(ip) @blacklist[ip] += 1 end def add_deny(ip) file = File.open(”/etc/hosts.deny”,’a+’) file.flock(File::LOCK_EX) file.puts(ip) file.flock(File::LOCK_UN) file.close end end if $0 == __FILE__ Observation.start(’/var/log/messages’) end
こんな感じ。
analyzeメソッドで解析してハッシュを返すってやり方はけっこう気に入ってるけど今になって思えばstartメソッドで判定するんじゃなくてjudgeメソッドを作ればよかったかなぁと思ったり思わなかったり。動かしてないけどこれちゃんと動くのかなぁ?