Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
autoban:: Simple, efficient Ruby "fail2ban"-like script
# A more efficient and documented autoban.rb
# Jamie - Released under MIT.
# This won't work with binary journal logs - the 'systemd/journal' gem doesn't work universally
$ssh_port = 1234
$network = ["", "", ""]
require "shellwords"
require "etc"
require "ipaddr"
$! { |n| }
def tail(files)
# Iterate through the supplied log files, open a descriptor, seek to the end of the file! { |f|, "r") }.each { |f|, IO::SEEK_END) }
abort "Failed to watch logfiles. Are you running me as root? I need this to run iptables!"
loop do
# Watch FDs for changes, yield with every new line that appears
select(files, nil, nil, 30)[0].each { |f| line = f.gets; yield line if line.to_s.chomp != "" }
tail %w(/var/log/secure /var/log/messages) do | line |
puts line
# Is the error from
if result = /(Failed password for (.*)|Invalid user (.*)) from (.*)/.match(line)
ip = result[4]; message = "Possible break-in attempt from #{ip} (#{result[3]}#{result[2]})"
next unless $network.none? { |i| i == ip }
send "system", *%W(ip route add blackhole #{ip}/32) # Get lost
if result = /([0-9a-f\.]*) to ([0-9a-f\.]*) ports/i.match(line)
ip = result[1]; message = "Potential port map from IP #{ip}"
next unless $network.none? { |i| i == ip }
send "system", *%W(/sbin/iptables -I INPUT -s #{ip} -p tcp --dport #{$ssh_port} -j REJECT --reject-with tcp-reset)
system "send_alert", message if message
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment