Created
August 30, 2008 13:18
-
-
Save jblanche/8109 to your computer and use it in GitHub Desktop.
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 | |
# Petit script permettant de regarder quel login s'est récemment connecté au | |
# serveur FTP et combien d'IP différentes ont été utilisé afin de détecter | |
# les personnes ayant fait un peu trop tourner leurs logins. | |
# Le format d'une ligne de log est le suivant : | |
# Sun Aug 24 10:08:52 2008 [pid 2949] [jblanche] OK LOGIN: Client "88.99.11.22" | |
require 'date' | |
require 'net/smtp' | |
class LogParser | |
attr_accessor :login_lines, :download_lines | |
def initialize(file) | |
@login_lines, @download_lines = [], [] | |
lines = IO.read(file) + IO.read(file+'.1') | |
lines.each do |line| | |
@login_lines << LoginItem.new(line) if line.include? 'OK LOGIN' | |
@download_lines << DownloadItem.new(line) if line.include? 'DOWNLOAD' | |
end | |
end | |
def last_week_logins | |
@login_lines.select {|item| item.date > Date.today-7} | |
end | |
def last_day_downloads | |
@download_lines.select {|item| item.date > Date.today-1} | |
end | |
end | |
class LogItem | |
@@items = [] | |
attr_accessor :date, :owner, :ip, :line_items | |
def initialize(line) | |
@line_items = line.split | |
@owner = @line_items[7].gsub(/[\[\]]/,'') | |
@date = Date.parse(@line_items[0..2].join(' ')) | |
end | |
end | |
class LoginItem < LogItem | |
def initialize(line) | |
super | |
@ip = @line_items.last.gsub('"','') | |
@@items << self | |
end | |
end | |
class DownloadItem < LogItem | |
attr_accessor :size | |
def initialize(line) | |
super | |
@ip = @line_items[11].gsub(/[",]/,'') | |
@size = line_items[13] | |
@@items << self | |
end | |
end | |
class User | |
include Enumerable | |
IPS_LIMIT = 2 | |
@@users = [] | |
attr_accessor :login, :ips, :download_size | |
def initialize(login) | |
@login, @ips, @download_size = login, [], 0 | |
@@users << self | |
end | |
def add(ip) | |
@ips << ip unless @ips.include? ip | |
end | |
def self.find_or_create_by_login(login) | |
self.find(login) || new(login) | |
end | |
def cheater? | |
@ips.size > IPS_LIMIT | |
end | |
def <=>(user) | |
download_size <=> user.download_size | |
end | |
def self.cheaters | |
@@users.select {|p| p.cheater? } | |
end | |
def self.all | |
@@users.sort.reverse | |
end | |
private | |
def self.find(login) | |
@@users.find{|p| p.login == login} | |
end | |
end | |
class SizeFormater | |
def self.number_to_human_size(size, precision=1) | |
size = Kernel.Float(size) | |
case | |
when size.to_i == 1; "1 Byte" | |
when size < 1024; "%d Bytes" % size | |
when size < 1024**2; "%.#{precision}f KB" % (size / 1024) | |
when size < 1024**3; "%.#{precision}f MB" % (size / 1024**2) | |
when size < 1024**4; "%.#{precision}f GB" % (size / 1024**3) | |
else "%.#{precision}f TB" % (size / 1024**4) | |
end.sub(/([0-9]\.\d*?)0+ /, '\1 ' ).sub(/\. /,' ') | |
end | |
end | |
class Mailer | |
def self.send(from, to, subject, message) | |
msg = <<END_OF_MESSAGE | |
From: #{from} | |
To: #{to} | |
Subject: #{subject} | |
#{message} | |
END_OF_MESSAGE | |
Net::SMTP.start('localhost') do |smtp| | |
smtp.send_message msg, from, to | |
end | |
end | |
end | |
LOG_FILE = '/var/log/vsftpd.log' | |
mail = "" | |
parser = LogParser.new(LOG_FILE) | |
parser.last_week_logins.each do |item| | |
user = User.find_or_create_by_login(item.owner) | |
user.add(item.ip) | |
end | |
User.cheaters.each do |user| | |
mail << "#{user.login} a utilise #{user.ips.size} adresses ip differentes pour se connecter \n" | |
end | |
mail << "===========================================================================================\n" | |
parser.last_day_downloads.each do |item| | |
user = User.find_or_create_by_login(item.owner) | |
user.download_size = user.download_size+item.size.to_i | |
end | |
User.all.each do |user| | |
mail << "#{user.login} a downloade #{SizeFormater.number_to_human_size(user.download_size.to_s)} bytes today \n" | |
end | |
Mailer.send('from@host.com', 'to@admin.com','reporting vsftp', mail) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment