1, Instal Ruby
see: http://www.my-whiteboard.com/linux-admin/how-to-install-ruby-on-rails-on-centos.html
gem install mysql
2, Create a table hosts_ban in a MySQL database, e.g.,badip.
CREATE TABLE `hosts_ban` (
`id` int(11) NOT NULL auto_increment,
`ip` varchar(19) NOT NULL,
`power` int(11) NOT NULL default '1',
`ban_time` int(11) NOT NULL default '5',
`expiry` datetime NOT NULL,
`last_access` datetime NOT NULL,
`reason` varchar(200) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ip` (`ip`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
3, create two php files, password.php and badrobot.php
/* File: password.php */
<?php
$username="xx";
$password="sec";
?>
/* File: badrobot.php */
<?php
include "/home/marketing/password.php";
echo "Bad Robot! You fell into a honey pot.";
exec("/bin/touch /tmp/badrobot");
# Change this line to match your MySQL configuration
$db = mysql_connect(“localhost”, “username”, “password”);
mysql_select_db(“badip”, $db);
$ip = $_SERVER['REMOTE_ADDR'];
# How long should the IP be banned?
$ban_time = 600; // seconds = 10 minutes
# Describe the reason for ban
$reason = “Fell in Honeypot: “.$_SERVER['HTTP_USER_AGENT'];
$sql = “INSERT INTO hosts_ban (ip, reason, ban_time, expiry, last_access) VALUES(‘$ip’,'$reason’, ‘$ban_time’, NOW() + INTERVAL ‘$ban_time’ SECOND, NOW()) ON DUPLICATE KEY UPDATE power = power + 1, expiry = NOW() + INTERVAL (POWER(2,(power-1))*ban_time) SECOND, last_access = NOW();”;
mysql_query($sql);
?>
4, create a robots.txt to lure spambots
# File: robots.txt
# Some honeypots to trap bad robots
User-agent: *
Disallow: /guestbook-emails/
Disallow: /top-secret/
5, create a security.inc file
# File: security.inc
# Allow web access to the security directory
<Directory /home/security/webapps>
Order deny,allow
Deny from all
Allow from all
</Directory>
Alias /robots.txt /home/marketing/webapps/robots.txt
RewriteEngine On
# Honeypot for bad robots
RewriteCond %{REQUEST_URI} ^/(guestbook-emails|top-secret)(/)?$
RewriteRule ^.* /security/badrobot.php [PT,L]
# Uncomment the following lines to permit IP access via WWW. Create ‘badrobot_ipaccess.php’ first
# RewriteCond %{SERVER_NAME} 123.123.123.123 # Your server’s IP address here.
# RewriteCond %{REQUEST_URI} !favicon.ico
# RewriteRule ^.* /security/badrobot_ipaccess.php [PT,L]
# Uncomment to ban by user agent. Create ‘badrobot_useragent.php’ first.
# RewriteCond %{HTTP_USER_AGENT} ^EmailCollector [OR]
# RewriteCond %{HTTP_USER_AGENT} ^EmailSiphon
# RewriteRule ^.* /security/badrobot_useragent.php [PT,L]
# Place your own bad robot directives here…
# This must follow your last bad robot directive
Alias /security /home/security/webapps/
6, create directories
mkdir /home/security
mkdir /home/security/webapps
7, edit virtual_host file to include the following:
Include "/etc/httpd/conf/security.inc"
8, Create a ruby file:
#!/usr/bin/env ruby
# This is the Badrobot daemon.
# Version 1.1
# Released under the Public Domain
require 'rubygems'
require 'mysql'
# -- Configuration -- #
# MySQL database:
@db_host = "localhost"
@db_name = "badrobot"
@db_user = "badrobot"
@db_password = ""
# The user your web server runs under:
www_user = "apache"
# Your iptables firewall startup script: (Empty string for none)
firewall_script = ""
# Location of touchfile that gets notified when the database changes:
ban_touchfile = "/tmp/badrobot"
# Check touchfile every n seconds:
loop_time = 1
# -- Don't change below this line unless you know what you are doing -- #
# Initial values
last_ban = 0
@current_chain = 0
@next_expiry = nil
# Restart Firewall to clean up the mess me may have made
system(firewall_script) if firewall_script
# Create touch file, if necessary
system("touch #{ban_touchfile} && chown #{www_user}.root #{ban_touchfile}")
# The IP blocking method
def ipblock
# Alternate chains
@old_chain = @current_chain
@current_chain = (@current_chain == 1) ? 0 : 1
# Flush chain
system("iptables -N banned_ips#{@current_chain} 2>/dev/null")
system("iptables -F banned_ips#{@current_chain}")
dbh = Mysql.real_connect(@db_host, @db_user, @db_password, @db_name)
# Get all banned IPs
result = dbh.query("SELECT ip, expiry FROM hosts_ban WHERE expiry > NOW()")
while row = result.fetch_hash do
# Add IP to chain
system("iptables -A banned_ips#{@current_chain} -s #{row["ip"]} -j DROP")
end
result.free if result
# Get next expiry date
result = dbh.query("SELECT MIN(expiry) AS next_expiry FROM hosts_ban WHERE expiry > NOW()")
if row = result.fetch_hash and row["next_expiry"]
t = row["next_expiry"].split(/-|:|\s/)
@next_expiry = Time.mktime(t[0], t[1], t[2], t[3], t[4], t[5])
else
@next_expiry = nil
end
dbh.close if dbh
# Insert chain in INPUT
system("iptables -I INPUT -j banned_ips#{@current_chain}")
# Delete old chain
system("iptables -D INPUT -j banned_ips#{@old_chain} 2>/dev/null")
system("iptables -F banned_ips#{@old_chain}")
system("iptables -X banned_ips#{@old_chain}")
end
# Main loop
loop do
# IP block
if File.mtime(ban_touchfile) != last_ban or (@next_expiry and Time.now > @next_expiry)
ipblock
last_ban = File.mtime(ban_touchfile)
end
# Wait loop_time seconds
sleep(loop_time)
end
Ref:
http://www.rubyrobot.org/article/protect-your-web-server-from-spambots
http://forum.mamboserver.com/showthread.php?t=26406
http://michael.langley.id.au/blog/posts/28
http://kevin.vanzonneveld.net/techblog/article/block_brute_force_attacks_with_iptables/
http://howtoforge.com/fail2ban_debian_etch
Tags:
Linux