May 092011
 
configuring-ufw-with-fail2ban

Welcome to Part II of the Quick Secure Setup Series.  Be sure to check out Quick, Secure Setup Part I first, although this can be taken on its own if you’d just like to configure UFW with Fail2ban correctly.

At the end of Part I we quickly setup a basic iptables config just to get the firewall up and doing its job.  The problem with iptables, isn’t actually a problem with iptables itself, but rather the administrator running it.  Iptables is a great firewall and like any great firewall there is a lot you can configure it to do.  The more configuration options open to the user, the more complicated a piece of software can get.  What I’ve witnessed is a well intentioned user will configure and run iptables on Day 1 of their server, just as we did in Part 1, but as time moves on and they need to run more applications or find themselves with something not working just right that seems to behave fine once iptables is stopped, then iptables either gets turned off or mis-configured with larger holes than what is needed.  Unless you are a linux administrator of some sort you probably are going to learn just enough of iptables to get it running on that initial setup.  After that you don’t really touch a firewall on a day to day basis so by the time you have this new application installed that isn’t playing nice with your current iptables you don’t want to take the steep learning curve plunge to figure out the correct  configuration you would need.  Therein would lie your chink in the security chain.

Starting with UFW for the first time check the UFW Ubuntu Wiki.  The introduction on this page explains perfectly why one would want to use UFW over iptables.

The Linux kernel in Ubuntu provides a packet filtering system called netfilter, and the traditional interface for manipulating netfilter are the iptables suite of commands. iptables provide a complete firewall solution that is both highly configurable and highly flexible.

Becoming proficient in iptables takes time, and getting started with netfilter firewalling using only iptables can be a daunting task. As a result, many frontends for iptables have been created over the years, each trying to achieve a different result and targeting a different audience.

The Uncomplicated Firewall (ufw) is a frontend for iptables and is particularly well-suited for host-based firewalls. ufw provides a framework for managing netfilter, as well as a command-line interface for manipulating the firewall. ufw aims to provide an easy to use interface for people unfamiliar with firewall concepts, while at the same time simplifies complicated iptables commands to help an adminstrator who knows what he or she is doing.

You may also find useful the Ubuntu Community page on UFW.  There are helpful links at the bottom of that page to continue reading.  Some quick google searches will get you moved to UFW quite easily.  Remember you are using the same backend as iptables just using a less complicated front-end to get the rules going.  So if you flush your current iptables and put in some basic ufw rules for your ssh, apache, and in my case NTP your ufw status output could look like this:


Status:
activeTo      Action   From
--------      ------   ----
OpenSSH       LIMIT    Anywhere
Apache Full   ALLOW    Anywhere
123           ALLOW    Anywhere

Now recall we changed our OpenSSH port in Part I, so to keep UFW simple I’ve edited the openssh-server file in /etc/ufw/applications.d to reflect our custom port. For any custom ports you find yourself opening or blocking consider creating an application profile for it, it’ll be easier to read your rules and if you don’t touch them for months, easier to remember when you have to re-visit them. You can easily see your apps and their configuration with ufw app list and ufw app info OpenSSH. Once you have your basic UFW configuration in place you should install fail2ban: aptitude install fail2ban.

Fail2ban is a very simple yet very useful application that simply looks at the log files you tell it about, parses them for certain errors or failures and then inserts a firewall rule to block the IP that caused that error or failure.  Trust me when I tell you that you want this.  Every server I’ve ever put on the internet gets scanned by scripts looking for open ports, trying ssh or ftp logins, attempting urls for various mysql, php, remote access URL’s, etcetera etcetera etcetera….  Here is a small example of ports that were scanned on my server:

Service: ms-sql-s (tcp/1433) ([UFW BLOCK])
Service: ssh (tcp/22) ([UFW BLOCK])
Service: sip (udp/5060) ([UFW BLOCK])
Service: 3389 (tcp/3389) ([UFW BLOCK])
Service: 27977 (tcp/27977) ([UFW BLOCK])
Service: radmin-port (tcp/4899) ([UFW BLOCK])
Service: 5900 (tcp/5900) ([UFW BLOCK])
Service: http-alt (tcp/8080) ([UFW BLOCK])
Service: loc-srv (tcp/135) ([UFW BLOCK])
Service: mysql (tcp/3306) ([UFW BLOCK])
Service: ms-sql-m (udp/1434) ([UFW BLOCK])
Service: 49153 (udp/49153) ([UFW BLOCK])
Service: 1022 (tcp/1022) ([UFW BLOCK])
Service: socks (tcp/1080) ([UFW BLOCK])

On the web server side various URL’s for web administration are always attempted like: /phpMyAdmin, /myadmin, /mysql, etcetera. Without Fail2ban in place these scripts can run until they’ve exhausted every login attempt they want, or every URL in their list. WITH Fail2ban we can give them 3-5 attempts and then realize they are a script kiddie and ban their IP from the server for X amount of time.

Out of the box Fail2ban works with iptables rules, however these don’t play nice with our simpler UFW commands so we need to make a couple edits to have Fail2ban block the IP’s with UFW.

First lets go into /etc/fail2ban/jail.conf and change a few default ban actions for ssh and apache to use ufw actions we will create:

[ssh]
enabled = true
banaction = ufw-ssh
port = 2992
filter = sshd
logpath = /var/log/auth.log
maxretry = 3


[apache]
enabled = true
port = http,https
banaction = ufw-apache
filter = apache-auth
logpath = /var/log/apache*/error*.log
maxretry = 4


[apache-filenotfound]
enabled = true
port = http,https
banaction = ufw-apache
filter = apache-nohome
logpath = /var/log/apache*/error*.log
maxretry = 3


[apache-noscript]
enabled = true
port = http,https
banaction = ufw-apache
filter = apache-noscript
logpath = /var/log/apache*/error*.log
maxretry = 6


[apache-overflows]
enabled = true
port = http,https
banaction = ufw-apache
filter = apache-overflows
logpath = /var/log/apache*/error*.log
maxretry = 2

In this file we are enabling the sections we want fail2ban to monitor and take action on. You’ll want to make sure your logpath points to your apache error logs and take note of the filter names as each of those corresponds to a file within the filter.d directory. All the filters are simply a regular expression to pattern match some error condition in the logfile, once matched fail2ban will execute the banaction. So if you look at the apache-auth filter, it will match for any user authentication failures to your websites. The only filter I’ve modified is the apache-nohome I’ve edited to match for any file not found error, not just checking for home directory attacks as the default.
The original regex was:
failregex = [[]client []] File does not exist: .*/~.*
and my modified version for any file not found errors is:
failregex = [[]client []] File does not exist: *
BE CAREFUL if you chose to also make this change. There are many things that will cause file not found errors that may not be attacks at all. Search bots looking for robots.txt, normal users can trigger on favicon.ico if you don’t have, etc. So if you make that change check your logs frequently and fix any valid file not found errors. The reason I turned this on is the constant attempts at bogus URL’s as I mentioned above where the scripts look for web GUI admin pages.

Now we simply need to create the valid banaction files we specified in our jail.conf. First is /etc/fail2ban/action.d/ufw-ssh.conf:

[Definition]
actionstart =
actionstop =
actioncheck =
actionban = ufw insert 1 deny from <ip> to any app OpenSSH
actionunban = ufw delete deny from <ip> to any app OpenSSH

and /etc/fail2ban/action.d/ufw-apache.conf:

[Definition]
actionstart =
actionstop =
actioncheck =
actionban = ufw insert 2 deny from <ip> to any app "Apache Full"
actionunban = ufw delete deny from <ip> to any app "Apache Full"

As you may see the ufw command here is quite simple. The actionban says to deny the offending IP for the specified application. The only gotcha here is we have to specify the line the rule is being inserted into as the order matters. Our original rules allow these apps so we must ensure that any denies to these apps come BEFORE the allow rule. As rules are processed in order if we have the allow first the offender will continue to hit our server as it will never hit the deny rule. So we make sure the denies get inserted before the allow lines and all is well. The great thing about UFW rules is that you can almost read them and understand what they are doing, as opposed to the standard iptables banaction which could look like this:

actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
actionunban = iptables -D fail2ban-<name> -s <ip> -j DROP

As you can see UFW provides for much more readability without that learning curve hit you’d have to go through to get a good grip on the iptables rules.

If you have logwatch configured as in Part I then you’ll see the bans that took place in the logwatch email for the day prior. For example the fail2ban section in one of my logwatch emails had this:

--------------------- fail2ban-messages Begin ------------------------
Banned services with Fail2Ban:                 Bans:Unbans
apache-filenotfound:                            [ 3:3 ]
90.80.141.37 (37-141.80-90.static-ip.oleane.fr)   1:1
92.82.225.197 (adsl92-82-225-197.romtelecom.net)  1:1
120.70.227.130                                    1:1
---------------------- fail2ban-messages End -------------------------

As I mentioned earlier, for the first week with this configuration you should check your apache error log and make sure those file not found errors were scripts looking for /phpmyadmin or some other page that truly doesn’t exist and not a normal user getting file not found errors because of favicon.ico or something else.

That’s it! ufw status will show you any of the rules in effect on your system. After these first two parts are executed you’ll have a server configured securely with nothing unnecessary open to the internet, and those ports that are open now are blocking some bad guys from messing with them too much. For Quick Secure Setup Part III, the last in the series, we’ll tighten everything up even more and end up with server security that is second to none.

  6 Responses to “UFW with Fail2ban – Quick Secure Setup Part II”

  1. Great lesson/tutorial or how should I call it…

    Great style of writing, I love it!

    Hope, that part III will be out soon… 😉

    P.s.: What about forum on: http://forum.vigilcode.com/ … Is it under construction?

    • Indeed, Part III should hit early June.
      Yes forum is a work in progress… I’m still debating various things regarding its construction and use.
      Any suggestions for articles let me know!

  2. Looks good, I have been looking for a way to secure a server with fail2ban and UFW. This article helped out a lot! I tried denyhosts, but it kept locking me out, and I couldn’t figure out why. This seems to be an easier solution, and to unblock, just delete the firewall rule from UFW.
    Does fail2ban permanently leave those rules enabled? If not, is there a way to set this?

    • No it does not permanently leave the rules enabled and I don’t recommend doing that. It is very rare I’ll see the same IP more than 6 hours apart. You’ll notice in /etc/fail2ban/action.d where we setup the action there is an actionunban. This is what is runs to remove the rule so you don’t have to delete them from UFW yourself. Now when does it do this? That is defined in your jail in /etc/fail2ban/jail.conf. You’ll notice in the [Default] section a bantime = value. This is the bantime in seconds before the actionunban is run. You can override the default value by specifying a bantime in each section you enable. So in our [SSH] section you can add bantime = 21600 to ban them for 6 hours. I see little need to ban longer than that in most cases.

      Finally if you are testing and find you can easily lock yourself out also in the [Default] section take note of the ignoreip = line. Go to http://whatismyip.org and get your IP and add it there, separate multiple IP’s you add there by spaces. Hope this helps you out.

      • Yes that helps out a lot! Thank you for this write up and your quick reply. I ended up just setting mine to ban for an hour since the server is hosting ssh on another port anyways.
        Thanks again!

  3. […] to me and I’ve been running VSFTPD for the past 10 years.  If you supplement it with a nice fail2ban configuration and further secure it with apparmor you’ll be in incredible […]

 Leave a Reply

(required)

(required)