Bruteblock - protection against bruteforce attacks in SSH

Bruteblock allows system administrators blocking various bruteforce attacks on FreeBSD services. This program analyzes system logs and adds attacker's IP into IPFW firewall table which can be used in different combinations of rules in IPFW.
The Bruteblock uses a list of rules which are regular expression. It provides very big flexibility and can be used for different types of system logs.
In this article the Bruteblock will be used to analyze SSH logs in FreeBSD.
Install Bruteblock in FreeBSD
cd /usr/ports/security/bruteblock/ make install clean
Configure Bruteblock
Add the following row before default configuration in /etc/syslog.conf file, like it is shown below:
auth.info;authpriv.info |exec /usr/local/sbin/bruteblock -f /usr/local/etc/bruteblock/ssh.conf auth.info;authpriv.info /var/log/auth.log
So, the first row was added and the second has already been there.
Now, configure Bruteblock to start automatically at system startup. Add these lines at the end of file /etc/rc.conf file:
syslogd_flags="-c" bruteblockd_enable="YES" bruteblockd_table="1" bruteblockd_flags="-s 5"
Where:
- "bruteblockd_table" is a number of the table in IPFW for blocked IPs;
- "bruteblockd_flags" is a delay between the cycles of the work, in current case it is 5 seconds.
The next step is the configuration file editing of Bruteblock /usr/local/etc/bruteblock/ssh.conf:
regexp = sshd.*Illegal user \S+ from (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) regexp1 = sshd.*Failed password for (?:illegal user )?\S+ from (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) regexp2 = sshd.*error: PAM: authentication error for illegal user \S+ from (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) regexp3 = "sshd.*Failed keyboard-interactive\/pam for \S+ from (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})" regexp4 = sshd.*Invalid user \S+ from (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) regexp5 = sshd.*error: PAM: authentication error for \S+ from (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) regexp6 = sshd.*Did not receive identification string from (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) regexp7 = sshd.*User \S+ from (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) not allowed because not listed in AllowUsers max_count = 4 within_time = 240 reset_ip = 600 ipfw2_table_no = 1
Where:
- "max_count" is the number of unsuccessful login attempts over time "within_time", after which bruteblock adds IP in table " ipfw2_table_no";
- "within_time" is the time in seconds during which must happen the "max_count" failed login attempts;
- "reset_ip" is the lifetime of the blocking rules, after which Bruteblock removes IP from the table;
- "ipfw2_table_no" is number of table in IPFW where is stored blocked IPs.
These rules will protect from the most cases, like:
- password guessing;
- user name guessing.
Also additional rules are needed if SSH uses RSA or DSA key for authentication.
In /etc/ssh/sshd_config file the option "LogLevel" needs to be replaced:
LogLevel VERBOSE
In /usr/local/etc/bruteblock/ssh.conf file needs to be added one more rule:
regexp8 = sshd.*Failed publickey for \S+ from (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})
Now, IPWF firewall must be turned on and starts automatically at system startup with the defined rules in file. The following lines have to be added in /etc/rc.conf file:
firewall_enable="YES" firewall_script="/etc/firewall.conf"
To create file run this:
cd /etc touch firewall.conf echo "#\!/bin/sh" > firewall.conf
The IP blocking won't work until IPFW does not have rules for blocking. Here is the example how to block 22 port, so to deny SSH access for blocked IPs. Add the following row to /etc/firewall.conf file:
ipfw add 5 deny ip from table\(1\) to me 22
Or if blocked IPs must not have an access to any ports. Add the following row to /etc/firewall.conf file:
ipfw add 5 deny ip from table\(1\) to me
But, there are some cases when system administrator didn't type the correct password few times then Bruteblock will block even its IP. To prevent this, IPWF firewall should have a rule which contains static IP addresses of system administartors. Add the following row to /etc/firewall.conf file:
ipfw add 4 allow ip from 192.168.1.67,192.168.1.130 to me
But "192.168.1.67,192.168.1.130" IPs should be replaced by real system administrator IPs.
This rule must have higher priority than the blocking rule because it won't work then.
By default IPFW firewall should have the last rule which blocks everything and it needs to be replaced by a rule which allows everything (in /etc/firewall.conf):
ipfw add 65500 allow ip from any to any
Reboot the system:
reboot
To check if rules were applied by IPFW, run the following command:
ipfw list
The output should be like this:
00004 allow ip from 192.168.1.67,192.168.1.130 to me 00005 deny ip from table(1) to me dst-port 22 65500 allow ip from any to any 65535 deny ip from any to any
The final steps are the restarting Syslog, SSH daemons and launching Bruteblock:
/etc/rc.d/sshd restart /etc/rc.d/syslogd restart /usr/local/etc/rc.d/bruteblockd start