Some examples of firewall scripts used to thwart dictionary attacks
Warning: | WORK IN PROGRESS - Please bear with me while I reacquaint myself with the syntax of this wiki! |
Please note that these examples are primarily concerned with countermeasures against dictionary attacks against SSH services. They are not to be confused with a more comprehensive firewall.
An example of a script used to counter IPv6-based dictionary attacks against the SSH service
The following assumes that you have ip6tables installed.
#!/bin/sh
#------------------------
# define paths/interfaces
#------------------------
IP6TABLES="/sbin/ip6tables"
EXTERNAL="eth0"
#-------------
# flush chains
#-------------
$IP6TABLES -F
$IP6TABLES -F INPUT
$IP6TABLES -F FORWARD
$IP6TABLES -F OUTPUT
#-----------------------
# setup default policies
#-----------------------
$IP6TABLES -P INPUT DROP
$IP6TABLES -P FORWARD DROP
$IP6TABLES -P OUTPUT ACCEPT
#-------------------
# setup input chains
#-------------------
# create SSH brute force chain
$IP6TABLES -X SSH_BRUTE_FORCE6
$IP6TABLES -N SSH_BRUTE_FORCE6
# if 4+ attempts in 30 mins from the same source, then drop any more connections.
$IP6TABLES -A SSH_BRUTE_FORCE6 -m recent ! --rcheck --seconds 1800 --hitcount 4 --rttl --name SSH --rsource -j RETURN
$IP6TABLES -A SSH_BRUTE_FORCE6 -j LOG --log-level debug --log-prefix "SSH Brute Force Attempt: "
$IP6TABLES -A SSH_BRUTE_FORCE6 -p tcp -j DROP
# allow internally generated traffic
$IP6TABLES -A INPUT -i $EXTERNAL -m state --state ESTABLISHED,RELATED -j ACCEPT
# allow icmp
$IP6TABLES -A INPUT -i $EXTERNAL -p ipv6-icmp --icmpv6-type neighbor-advertisement -j ACCEPT
$IP6TABLES -A INPUT -i $EXTERNAL -p ipv6-icmp --icmpv6-type neighbor-solicitation -j ACCEPT
# SSH brute force protection routine
$IP6TABLES -A INPUT -i $EXTERNAL -p tcp --dport 22 -m state --state NEW -m recent --name SSH --set --rsource -j SSH_BRUTE_FORCE6
# allow SSH
$IP6TABLES -A INPUT -i $EXTERNAL -p tcp --dport 22 -j ACCEPT
I thoroughly recommend installing logcheck and then you can have information on attacks emailed to you. Personally, I find this quite interesting and a real eye-opener.
Below is an example of an IPv6-based attempt with the hostname, MAC address, source and destination addresses removed. The comment "SSH Brute Force Attempt:" has been inserted into the logfile from the firewall script.
This email is sent by logcheck. If you no longer wish to receive
such mails, you can either deinstall the logcheck package or modify
its configuration file (/etc/logcheck/logcheck.conf).
System Events
=-=-=-=-=-=-=
Dec 13 20:06:10 $hostname kernel: [17001577.689365] SSH Brute Force Attempt: IN=eth0 OUT= MAC=xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
SRC=xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx DST=xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
LEN=80 TC=0 HOPLIMIT=58 FLOWLBL=0 PROTO=TCP SPT=58364 DPT=22 WINDOW=5760 RES=0x00 SYN URGP=0
How to launch a firewall script
This example applies specifically to the Debian-based distribution, but I have applied the same scripts to other distributions.
Place a firewall script, such as above, in the following directory:
$ /etc/network/if-pre-up.d
You may need to check permissions on the script (read, write, executable, ownership, etc).
Finally, I tend to launch firewalls from the 'interfaces' file:
/etc/network$ pwd
/etc/network
/etc/network$ cat interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
auto lo eth0
iface lo inet loopback
iface eth0 inet dhcp
pre-up /sbin/ifconfig eth0
pre-up /etc/network/if-pre-up.d/firewall.sh
Allow specific hosts to bypass the SSH brute force protection chain
The section below that was used in our earlier IPv6 firewall script above does not discriminate; whether your connection is a success or failure, if you repeatedly probe the SSH service it will block you if you meet it's criteria.
# if 4+ attempts in 30 mins from the same source, then drop any more connections.
$IP6TABLES -A SSH_BRUTE_FORCE6 -m recent ! --rcheck --seconds 1800 --hitcount 4 --rttl --name SSH --rsource -j RETURN
$IP6TABLES -A SSH_BRUTE_FORCE6 -j LOG --log-level debug --log-prefix "SSH Brute Force Attempt: "
$IP6TABLES -A SSH_BRUTE_FORCE6 -p tcp -j DROP
However, you can also use iptables/ip6tables to allow specific or known hosts to bypass the 'SSH brute force chain', therefore, you are not bound by a number of attempts before you are locked out of the box.
Typically, at the start of a firewall script, you should decide on what IP and MAC addresses you want to allow to bypass the SSH brute force chain. Make sure that you have the correct details and are not confused by other IP and MAC addresses on kit inbetween.
The follow examples are based around IPv4; the concepts of iptables/ip6tables SSH brute force countermeasures are pretty much the same on IPv4 and IPv6.
#------------------------------
# define machines to allow/deny
#------------------------------
# IPv4 Addresses
User1_IP="xx:xx:xx:xx:xx:xx"
User1_MAC="xx:xx:xx:xx:xx:xx"
User2_IP="xx:xx:xx:xx:xx:xx"
User3_MAC="xx:xx:xx:xx:xx:xx"
Then, straight after the lines that create the 'ssh brute force' chain, you specify what hosts are allowed to bypass the SSH chain entirely.
# create SSH brute force chain
$IPTABLES -X SSH_BRUTE_FORCE
$IPTABLES -N SSH_BRUTE_FORCE
# allow certain machines to bypass this
$IPTABLES -A SSH_BRUTE_FORCE -s $USER1_IP -m mac --mac-source $USER1_MAC -j RETURN
$IPTABLES -A SSH_BRUTE_FORCE -s $USER2_IP -j RETURN
$IPTABLES -A SSH_BRUTE_FORCE -m mac --mac-source $USER3_MAC -j RETURN
...
Final thoughts
I do not consider this approach to be a replacement for Fail2ban. Instead, I currently use it alongside Fail2ban because, at the time when I first looked at IPv6, there was no IPv6 support in Fail2ban. I believe that some security is better than none.
Gerald Davies 01:11, 18 December 2012 (UTC)