Automatically blacklist SSH hackers

Configuring and Customizing sshblack


I have gone to the effort of packaging the script up with a README file and an INSTALL file. Please humor me and read them! The README file also has some release notes so you can make sense of the different versions. I have left some of the older versions up here but Version 2.8.1 is the latest.

Due to popular demand, I have made some scripts that can be used to manually blacklist and un-blacklist an IP address while at the same time modifying the $CACHE file used by sshblack. These are called list and unlist. IMPORTANT: These scripts (and sshblack) use no file locking mechanisms. This means there could be a collision between the utilities and sshblack if they try to access the cache file at the same time. I consider this a relatively remote possibility, but you may want to consider it when using them. If necessary, I will try to add file locking in the next version.

Please note that in versions after 2.5 the complete, actual commands used to block and un-block an attacker are available for configuration at the top of the code along with the other custom parameters. Previously only portions of the command were available in the "user configurable parameters". Now, the actual commands are entered as $ADDRULE and $DELRULE. All the administrator needs to do is substitute the literal 'ipaddress' in place of the actual IP address in the command. The script will replace this string with the actual address of the attacker each time it needs to run the command.
For example, if you were manually going to blacklists the host 192.168.1.123 you would normally enter the following at a command prompt:
        iptables -I BLACKLIST -s 192.168.1.123 -j DROP
So at the top of the sshblack script (in the $ADDRULE definition), this command becomes:
        iptables -I BLACKLIST -s ipaddress -j DROP

Below are some examples of $ADDRULE and $DELRULE for various applications.

	my($ADDRULE) = '/sbin/iptables -I INPUT -s ipaddress -p tcp --dport 22 -j DROP';
	my($DELRULE) = '/sbin/iptables -D INPUT -s ipaddress -p tcp --dport 22 -j DROP'; 
	

	my($ADDRULE) = '/sbin/iptables -I BLACKLIST -s ipaddress -j DROP';
	my($DELRULE) = '/sbin/iptables -D BLACKLIST -s ipaddress -j DROP'; 
	

	my($ADDRULE) = '/sbin/ipchains -I input -p tcp -s ipaddress --destination-port 22 -j DENY';
	my($DELRULE) = '/sbin/ipchains -D input -p tcp -s ipaddress --destination-port 22 -j DENY'; 
	

	## For Redhat/Fedora
	my($ADDRULE) = '/sbin/route add -host ipaddress gw 127.0.0.1';
	my($DELRULE) = '/sbin/route del -host ipaddress gw 127.0.0.1';
	#
	## For Solaris (?? this has not been tested by me!)
	my($ADDRULE) = 'route add ipaddress 127.0.0.1';
	my($DELRULE) = 'route delete ipaddress 127.0.0.1'; 
	

	##  In pf.conf
	block in quick on $ext_if proto tcp from <ssh-block> to $ext_if port ssh
	
	##  In sshblack
	my($ADDRULE) = '/sbin/pfctl -t ssh-block -T add ipaddress';
	my($DELRULE) = '/sbin/pfctl -t ssh-block -T delete ipaddress';
	

	##  In /etc/shorewall/shorewall.conf
	BLACKLISTNEWONLY=Yes
	BLACKLIST_DISPOSITION=DROP
	
	##  In sshblack
	my($ADDRULE) = '/usr/sbin/shorewall drop ipaddress';
	my($DELRULE) = '/usr/sbin/shorewall allow ipaddress';
	

	my($ADDRULE) = 'echo "block return-rst in log quick on dmfe0 proto tcp from ipaddress to any port = 22" | /usr/sbin/ipf -f -';
	my($DELRULE) = 'echo "block return-rst in log quick on dmfe0 proto tcp from ipaddress to any port = 22" | /usr/sbin/ipf -rf -';
	


Several of these options are explained and highlighted in the code comments. Please make sure that you use a mating $ADDRULE and $DELRULE. That is, don't use iptables for the $ADDRULE and route for the $DELRULE. Doing so will cause problems!

Please check out the README.TXT and INSTALL.TXT files as there are many other variables you can tweak.

I have also added some utility scripts because people were asking me about these. I suggest you figure out what these do (and tweak them to meet your needs) before blindly executing them.


Fine Tuning and Internal Configuration

Several variables are available for tuning the script. Default values are already entered in the script and will run fine for most applications right out of the box. These variables are detailed below.

$DAEMONIZE will allow the script to run in the background (via fork) and will essentially create a daemon out of the script. If this is set to '1' it will place the executing script in the background. If set to '0' it will run from the command prompt and log all output to the terminal (useful for debugging, not much else).

$LOG is the log file to monitor, commonly set to '/var/log/secure' but might be '/var/log/messages' or '/var/log/syslog' and should include a complete path.

$OUTPUTLOG is the log file for output from the sshblack script. It will log everything from STDOUT and STDERR. You can certainly send this to /dev/null if you don't want to see this output. Default is '/var/log/sshblacklisting'.

$CACHE is the file used to store the working database of IP addresses. This includes both addresses that are already blacklisted and those that are "addresses of interest" that have done something suspicious but have not yet crossed the threshold to be blacklisted. The database is composed of one line per address, three comma-separated elements per line. The form is:

   ip_address,epoch_time,attack_count

  IP address is the dotted notation for the "attacking" host. The time is epoch time (seconds since Jan 01, 1970). The attack count is an integer representing of the number of distinct attack patterns seen from the respective host since it was first "observed".

$LOCALNET is a whitelist of hosts and/or networks. This is recorded in REGEX notation and can include any hosts and networks that should NOT be blacklisted, regardless of activity. A good tutorial on REGEX should be consulted for help on this if needed. There is also a little tutorial on the sshblack homepage.

$ADDRULE is the command line option used to ADD things to the blacklist. You can use route commands, iptables commands, ipchains commands.... Whatever command you use, the sshblack script will execute this command when it is triggered. Some example commands are on the sshblack homepage. The only special thing you need to do is substitute the literal character string 'ipaddress' in the location where you would normally put the actual IP address. The script will search for this string and replace it with the attacker's address as needed.

$DELRULE is the command line option used to DELETE things from the blacklist. You can use route commands, iptables commands, ipchains commands.... Whatever command you use, the sshblack script will execute this command when it removes addresses from the blacklist. Some example commands are on the sshblack homepage. The only special thing you need to do is substitute the literal character string 'ipaddress' in the location where you would normally put the actual IP address. The script will search for this string and replace it with the attacker's address as needed.

$REASONS is the exact, case sensitive REGEX of items that should be considered "attacks". For most modern versions of sshd, the common setting of '(Failed password|Failed none)' works well. It is usually best to NOT use both 'Failed password' and 'Illegal user' as some ssh daemons record both of those for a single failure and it could produce duplicate counts.

$AGEOUT is a timing variable expressed IN SECONDS. This is the amount of time before a suspect IP is removed from the database unless it is already blacklisted. That is, if an attacker has not reached $MAXHITS (see below) attacks by the time $AGEOUT has expired, he will be removed from the database and NOT be blacklisted. Commonly set to 600 seconds (10 minutes).

$RELEASEDAYS is a timing variable expressed IN DAYS. This is the amount of time before a blacklisted host is removed from the blacklist. Commonly set to 3 but can be anything deemed reasonable.

$CHECK is a timing variable expressed IN SECONDS. This is an internal timer used as an interval for parsing the database. Every $CHECK seconds, the script will open the database, see a) if anyone who is already blacklisted should be released from the blacklist, b) if any suspicious IPs should be dropped from the database because they have reached $AGEOUT seconds and are not currently blacklisted. Commonly set to 300 seconds (5 minutes) and should not be set too low (not less than 60 seconds) or too high (not more than 3600 seconds).

$MAXHITS is the number of "attacks" allowed before the IP will be blacklisted. This is commonly set to 4 or 5. This should not be set extremely low so as to allow for legitimate users to mistype their password. It should also not be set extremely high (e.g. 100) as it would reduce the effectiveness of the script. Any legitimate user is going to be well below three or four attempts and any trojan/hacker is going to be above five or six attempts so it is best to keep it in this range.

$DOSBAIL is a denial-of-service counter. If the script detects that more than $DOSBAIL IPs are listed in the database, it will hibernate for one day and do nothing. This is done in an attempt to keep an attacker from spoofing source addresses and loading up the iptables chain with an enormous number of addresses (if this is even possible). It is assumed an administrator would notice the huge number of attack attempts and do something to obviate the problem. This is commonly set to 200 but can be adjusted to whatever the administrator feels is reasonable. Obviously setting the number too low could cause premature hibernation.

$CHATTY determines the amount of logging output produced. 0 and 1 are the only options. A setting of 0 will produce limited output. A message will be produced when the script starts and each time a host is blacklisted or released. A setting of 1 will produce more output in the form of notices each time a host trips a single $REASON even if it hasn't reached $MAXHITS to be blacklisted yet. It defaults to 1 which is usually acceptable for most applications and makes testing a bit easier.

$EMAILME is used to decide if the script will E-mail the administrator when certain events occur. 0 and 1 are the only options. A setting of 1 will cause E-mails to be generated only when an address is added to or released from the blacklist.

$NOTIFY is the E-mail address of the administrator monitoring sshblack activity. The can be left as 'root' or it can be set to any local user such as 'webmaster' or it can be set to a valid SMTP address such as 'bubba@example.com'. Obviously E-mail is sent to this address only if $EMAILME is enabled.

mail
Copyright 2007 Pettingers.org

Vectors at

pettingers.org