Fail2Ban is a very efficient daemon that scans log files for malicious activity, and offers several options to ban offending IPs and hostnames. Although it is highly configurable, it requires a depth of knowledge beyond that required for GUI-accessible firewalls such as ConfigServer Security & Firewall.
Harden the Kernel
Before do anything further, it is necessary to harden the server at the kernel level. Doing so will prevent the majority of attacks that Fail2Ban config will have to deal with. Do this: Linux kernel sysctl hardening. Prior to learning those trix, I had solely relied upon ConfigServer Security and Firewall (CSF) to block malicious attacks. Heading those off at the kernel level is much more efficient.
I’m a huge fan of CSF, having used it with cPanel, Webmin and Virtualmin for many years. Moving to Amazon Web Services presented a challenge, however. I’ve yet to figure out how to use CSF on AWS, so I’ve backtracked to my old standby, Fail2Ban.
“Out of the box,” Fail2Ban for CentOS & other RedHat downstream distros only provides protection against SASL login failures. But with a little work and research, one can successfully configure many more “jails” for the malicious traffic. To take full advantage of Fail2Ban, the admin will need to become familiar with RegEx: regular expressions.
Amazon Web Services Security Groups
AWS provides several levels of firewall protection for EC2 instances; I mainly utilize EC2 security groups and VPC security groups. These firewalls serve to allow traffic to an instance based on IP address, IP block, port, etc. VPC will gateway traffic to and within a virtual cloud; one can create a security group for a cohort of replicated database servers to only allow traffic from within the virtual cloud. Likewise, one could create a cloud group with public facing, load-balanced Varnish reverse proxies that interact with an Apache or NginX app server, and that app server connects to the database cohort. The only publicly-accessible servers would be the web proxies. This is similar to what one might expect in a traditional network operations center.
Learn some RegEx
Learning a bit about RegEx will benefit the admin in virtually every programming endeavor: PHP, Perl, C, SQL etc. all make use of RegEx to match strings of text. Matching a variable string of text in a log file, for example, allows Fail2Ban to act upon that string, sending an email, looking up a hostname, and/or invoking a firewall rule to block traffic from the offending origin for a designated amount of time.
As stated earlier, plain vanilla Fail2Ban regex from EPEL is functional only to block SASL authentication errors. Most of the filters in the package are, at best, examples of what can be done, and will not function as written. Why? Because Fail2Ban has to deal with the particular implementations of log files in various GNU/Linux distributions, and the peculiarities of the reporting structure in those logs, no single RegEx, nor log file location, is going to work for every distribution. Neither can Fail2Ban account for every change in log file location or structure from version to version. What worked for Centos 5.x may not work for CentOS 6.x; what worked in kernel 2.8 may be invalid in kernel 3.4.
Also stated earlier, it is well worth the time to learn a little about RegEx. One vehicle to propel the admin far along the path is RegExr. Author Greg Skinner provides an online version as well as Adobe AIR standalone app. RegExr is an invaluable tool for writing and proofing regular expressions.
Write the RegEx
OK, here’s the payoff for reading so far: a regex filter that will squelch Dovecot brute force attacks on CentOS 6, Amazon Linux 2013 and other kernel 3.4 RedHat downstream distros such as Fedora and Arch. This would, of course go in /etc/fail2ban/filter.d/dovecot.conf:
Here’s the original, commented out via #:
#failregex = .*(?:pop3-login|dovecot):.*(?:Authentication failure|Aborted login \(auth failed|Aborted login \(tried to use disabled|Disconnected \(auth failed).*rip=(?P<host>\S*),.*
…and here’s a substitute, created via experimentation with RegExr:
failregex = .*auth.*pam.*dovecot.*(?:authentication failure).*rhost=<HOST>.*
How to create a valid RegEx to match the failures to ban? For that, one must monitor log files. In the case of Dovecot on Amazon Linux 2013, that would be /var/log/secure — same as it has ever been with RedHat downstreams. However, the logging is different than it may have been in CentOS 5.8.
Have a look at the log files: use grep to filter the secure log on “authentication failure”
tail -f -n 20000 /var/log/secure | grep "authentication failure"
There will likely be log entries similar to the following:
Apr 19 05:22:19 vm5 auth: pam_unix(dovecot:auth): authentication failure; logname= uid=0 euid=0 tty=dovecot ruser=oracle rhost=220.127.116.11 Apr 19 05:22:20 vm5 auth: pam_unix(dovecot:auth): authentication failure; logname= uid=0 euid=0 tty=dovecot ruser=sybase rhost=18.104.22.168 Apr 19 05:22:20 vm5 auth: pam_unix(dovecot:auth): authentication failure; logname= uid=0 euid=0 tty=dovecot ruser=informix rhost=22.214.171.124
RegEx mentioned previously will match those entries, and via Fail2Ban: BAN the offending IPs.
So, you think you’re ready with RegEx fu to tackle the Local Jail (jail.local)? Not so fast. Don’t use regex in jail.local. This file takes wild cards, not regex… so if you want to monitor all users’ /home/user/logs/access_log — you must wildcard /home/*/logs/access_log . NOT /home/.*/logs !
… more to come: follow this post for more details!