IMPLEMENTATION NOTES: Banshee implements a simple two-threaded design; in short: * The main thread watches the /var/log/secure file for changes, blocking IP addresses as appropriate * The background thread periodically unbans IPs after a user-definable period OTHER IMPLEMENTATIONS: http://www.cpan.org/authors/id/D/DR/DRAGOS/sshwatch-0.01.pl http://fail2ban.sourceforge.net/ http://denyhosts.sourceforge.net/ IPTABLES NOTES: Based on: http://www.the-art-of-web.com/system/fail2ban/ # (0): Listing # list all rules iptables -L # list rules in the INPUT chain iptables -L INPUT # list rules in the BANSSHEE custom chain iptables -L BANSSHEE # (1): Setup # create a "NEW" chain called "bansshee" iptables -N BANSSHEE # "APPEND" a "RETURN" command to the end of the bansshee chain (returns back to INPUT chain); strictly speaking this line is not necessary iptables -A BANSSHEE -j RETURN # "INSERT" a rule at the start of the built-in "INPUT" chain that redirects all ssh traffic to the bansshee chain iptables -I INPUT -p tcp --dport ssh -j BANSSHEE # same done using an "APPEND" iptables -A INPUT -p tcp --dport ssh -j BANSSHEE # (2): Banning # insert rule at line 1 of bansshee chain causing all packets from IP address to be DROPped iptables -I bansshee -s 192.168.0.10 -j DROP # (3): Unbanning # delete rule for IP address iptables -D bansshee -s 192.168.0.10 -j DROP # (4): Breakdown # remove JUMP command iptables -D INPUT -p tcp --dport ssh -j bansshee # FLUSH (deletes all rules from chain) iptables -F bansshee # DELETE iptables -X bansshee LOG FILE PARSING NOTES: On Red Hat Enterprise Linux ES release 3: In /var/log/messages: Unknown user: Apr 9 05:19:54 s69819 sshd(pam_unix)[11498]: check pass; user unknown Apr 9 05:19:54 s69819 sshd(pam_unix)[11498]: authentication failure; logname= uid=0 euid=0 tty=NODEVssh ruser= rhost=66.90.73.172 Note that it will do a DNS lookup and show the hostname instead if found: Apr 9 23:40:13 s69819 sshd(pam_unix)[4481]: check pass; user unknown Apr 9 23:40:13 s69819 sshd(pam_unix)[4481]: authentication failure; logname= uid=0 euid=0 tty=NODEVssh ruser= rhost=tpxonline.com Known user but invalid password: Apr 9 05:44:01 s69819 sshd(pam_unix)[12862]: authentication failure; logname= uid=0 euid=0 tty=NODEVssh ruser= rhost=66.90.73.172 user=postgres In /var/log/secure: Unknown user: Apr 9 05:19:47 s69819 sshd[11465]: Illegal user amanda from 66.90.73.172 Apr 9 05:19:49 s69819 sshd[11465]: Failed password for illegal user amanda from 66.90.73.172 port 46447 ssh2 Known user, invalid password: Apr 9 05:19:49 s69819 sshd[11467]: Failed password for root from 66.90.73.172 port 46562 ssh2 Note that in this log file no reverse-DNS lookup is done (compare with the tpxonline.com entry above): Apr 9 23:40:13 s69819 sshd[4481]: Illegal user test02 from 66.223.110.96 Apr 9 23:40:15 s69819 sshd[4481]: Failed password for illegal user test02 from 66.223.110.96 port 60458 ssh2 Other possibly problematic attempts: Apr 11 17:59:36 s69819 sshd[5104]: Did not receive identification string from 132.248.80.196 Regular expressions: /sshd\[\d+\]: Failed password for illegal user \S+ from (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) port \d+ ssh/ /sshd\[\d+\]: Failed password for \S+ from (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) port \d+ ssh/ BANSSHEE IN ACTION: Here we see an intrusion attempt beginning at 11:32:28. In the following 39 seconds the attacker tries to break in using 9 different user names. Notice that there is a delay of 34 seconds between the attack starting and Bansshee's initial response. This is because the File::Tail module used by Bansshee to efficiently monitor the log file does not continuously poll the log file looking for changes; rather, it adjusts its rate of checking in accordance with the amount of log file activity. The more often the log file changes, the quicker Bansshee will "see" it. In the log excerpt you can see the messages produced by the sshd process itself during the attack, as well as Bansshee's response. Apr 14 11:32:28 s69819 sshd[19636]: Illegal user staff from 125.7.193.160 Apr 14 11:32:30 s69819 sshd[19636]: Failed password for illegal user staff from 125.7.193.160 port 41866 ssh2 Apr 14 11:32:32 s69819 sshd[19638]: Illegal user sales from 125.7.193.160 Apr 14 11:32:34 s69819 sshd[19638]: Failed password for illegal user sales from 125.7.193.160 port 41977 ssh2 Apr 14 11:32:36 s69819 sshd[19640]: Illegal user recruit from 125.7.193.160 Apr 14 11:32:38 s69819 sshd[19640]: Failed password for illegal user recruit from 125.7.193.160 port 42086 ssh2 Apr 14 11:32:39 s69819 sshd[19642]: Illegal user alias from 125.7.193.160 Apr 14 11:32:42 s69819 sshd[19642]: Failed password for illegal user alias from 125.7.193.160 port 42199 ssh2 Apr 14 11:32:43 s69819 sshd[19644]: Illegal user office from 125.7.193.160 Apr 14 11:32:46 s69819 sshd[19644]: Failed password for illegal user office from 125.7.193.160 port 42308 ssh2 Apr 14 11:32:47 s69819 sshd[19646]: Illegal user samba from 125.7.193.160 Apr 14 11:32:50 s69819 sshd[19646]: Failed password for illegal user samba from 125.7.193.160 port 42413 ssh2 Apr 14 11:32:51 s69819 sshd[19648]: Illegal user tomcat from 125.7.193.160 Apr 14 11:32:54 s69819 sshd[19648]: Failed password for illegal user tomcat from 125.7.193.160 port 42523 ssh2 Apr 14 11:32:55 s69819 sshd[19651]: Illegal user webadmin from 125.7.193.160 Apr 14 11:33:02 s69819 bansshee[1798]: Attempted connection with illegal user (staff) from IP 125.7.193.160 (1 attempt(s) so far). Apr 14 11:33:03 s69819 sshd[19651]: Failed password for illegal user webadmin from 125.7.193.160 port 42629 ssh2 Apr 14 11:33:04 s69819 sshd[19653]: Illegal user spam from 125.7.193.160 Apr 14 11:33:05 s69819 bansshee[1798]: Attempted connection with illegal user (sales) from IP 125.7.193.160 (2 attempt(s) so far). Apr 14 11:33:05 s69819 bansshee[1798]: Attempted connection with illegal user (recruit) from IP 125.7.193.160 (3 attempt(s) so far). Apr 14 11:33:05 s69819 bansshee[1798]: Attempted connection with illegal user (alias) from IP 125.7.193.160 (4 attempt(s) so far). Apr 14 11:33:05 s69819 bansshee[1798]: Attempted connection with illegal user (office) from IP 125.7.193.160 (5 attempt(s) so far). Apr 14 11:33:05 s69819 bansshee[1798]: Adding IP 125.7.193.160 to blocklist. Apr 14 11:33:05 s69819 bansshee[1798]: Attempted connection with illegal user (samba) from IP 125.7.193.160 (6 attempt(s) so far). Apr 14 11:33:05 s69819 bansshee[1798]: Attempted connection with illegal user (tomcat) from IP 125.7.193.160 (7 attempt(s) so far). Apr 14 11:33:06 s69819 bansshee[1798]: Attempted connection with illegal user (webadmin) from IP 125.7.193.160 (8 attempt(s) so far). Apr 14 11:33:07 s69819 sshd[19653]: Failed password for illegal user spam from 125.7.193.160 port 42862 ssh2 Apr 14 11:33:07 s69819 bansshee[1798]: Attempted connection with illegal user (spam) from IP 125.7.193.160 (9 attempt(s) so far). Apr 14 11:33:46 s69819 bansshee[1798]: Performing periodic check of blocked IPs list. 36 seconds after the attack begins Bansshee adds the offending IP to its blocklist and any subsequent attempts are stopped. Checking the iptables from the command line shows the block put in place by Bansshee causing all subsequent packets from the attacker to be silently dropped. The attacker sees no rejected packets but instead wastes time waiting for reply packets that it will never receive. $ sudo iptables -L BANSSHEE Chain BANSSHEE (1 references) target prot opt source destination DROP all -- 125.7.193.160 anywhere Approximately one hour later Bansshee removes the attacker's IP from the blocklist during one of its periodic checks: Apr 14 12:33:46 s69819 bansshee[1798]: Performing periodic check of blocked IPs list. Apr 14 12:33:46 s69819 bansshee[1798]: Removing IP 125.7.193.160 from blocklist. This can be confirmed by checking the iptables from the command line: $ sudo iptables -L BANSSHEE Password: Chain BANSSHEE (1 references) target prot opt source destination Further monitoring of the log files show that the attacker has given up; no more intrusion attempts originate from the attacker's IP. If the attacker were to resume his or her dictionary attack Bansshee would quickly step in and put the IP back on the blocklist thus removing the "force" from the "brute force" attack and rendering it ineffective, as well as minimizing the risk of denial of service problems for legitimate users trying to connect via SSH. The LogWatch report for that day shows this: --------------------- Bansshee (secure-log) Begin ------------------------ Failed password attempts: 7 time(s). Illegal user attempts: 10 time(s). IPs added to blocklist: 125.7.193.160 : 1 time(s). 210.34.88.222.in-addr.arpa [222.88.34.210] : 1 time(s). ---------------------- Bansshee (secure-log) End ------------------------- Here we see that in addition to the attack from 125.7.193.160 an attack from 222.88.34.210 was also stopped.