Created
September 1, 2013 22:05
-
-
Save elektret/6407615 to your computer and use it in GitHub Desktop.
Parse Fail2ban output
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# ruby fail2ban.rb logfile | sort -rn | head -25 | |
# ruby fail2ban.rb logfile | awk '{print $2}' | sort | uniq -c | sort -rn | head -15 | |
require 'time' | |
networks = {} | |
module MBox | |
class Mail | |
def self.begin?(line) | |
if line.unpack('C*').pack("U*") =~ /\AFrom\s([^\s]+)\s(.+)\n/ | |
yield $1, DateTime.parse($2) | |
return true | |
end | |
end | |
attr_reader :header, :body | |
def initialize(from, time) | |
@meta, @header, @body = true, {}, String.new | |
end | |
def <<(line) | |
@meta = false if @meta and line.unpack('C*').pack("U*") =~ /\A\n/ | |
if @meta | |
case line.unpack('C*').pack("U*") | |
when /\A([^\s:]+):(.*)\n/ then @queue = @header[$1] = $2.strip | |
when /\A\s+(.+)\n/ then @queue << ' ' + $1.strip | |
else raise ArgumentError, 'Header contains inappropriate line' | |
end | |
else @body << line.unpack('C*').pack("U*") | |
end | |
end | |
end | |
extend self | |
def parse(file, mails = []) | |
File.open file do |fd| | |
raise ArgumentError, 'Not a valid mbox format' unless Mail.begin? fd.readline do |from, time| | |
mails << Mail.new(from, time) | |
end | |
fd.each do |line| | |
case | |
when Mail.begin?(line) { |from, time| mails << Mail.new(from, time) } | |
else mails.last << line | |
end | |
end | |
end; mails | |
end | |
end | |
unless !ARGV[0].nil? and File.readable? ARGV[0] | |
puts 'Usage: fail2ban.rb file' | |
exit | |
end | |
MBox.parse(ARGV[0]).each do |mail| | |
name = String.new | |
mail.body.upcase.match /^NETNAME:\s+(.+)\n/ do | |
if networks[$1].nil? then networks[name = $1] = { count: 0 } | |
else networks[$1][:count] += 1 | |
end | |
end | |
unless name.empty? | |
mail.body.upcase.scan /^(.+):\s+(.+)\n/ do |key, value| | |
networks[name][:country] = value if key == 'COUNTRY' | |
end | |
end | |
end | |
networks.each do |key, value| | |
puts value[:count].to_s + "\t" + | |
value[:country] + "\t" + | |
key | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment