Fail2ban + UFW not blocking IPs on ubuntu 15.04

Hi, I’ve got a few Ubuntu 15.04 droplets running Fail2ban + UFW (+ IPtables fwiw). I’ve set the servers up according to the various 14.04 tutorials on DO: initial server setup steps setting up ufw setting up fail2ban I even followed the directions to setup repeat offender from wireflare as well as recidive (a bit of paranoia admittedly).

I should probably note that these droplets were originally 14.10 that was upgraded to 15.04 in Aug but all of them are running the same kernel 3.19.0-30-generic per DO dashboard. I made sure that each of them were running the right kernel version since iptables wasn’t working on some because of kernel mismatching.

My droplets running 14.04 my setup works great AFAIK…

I’ve set up my UFW rules to REJECT certain annoying IP addresses (e.g. and sudo iptables -S and -L both reflect these particular addresses as being blocked/rejected. I also have UFW reject all incoming requests except to certain ports (http, etc). And I’ve got PermitRootLogin off as well. The only way to log into our servers are via key access (on port 22, but that isn’t the issue).

However, I’ve noticed that f2b continually sends out emails saying those particular IP addresses are still attempting to SSH in. My jail.local has the default SSH jail settings, but that points to port=ssh (which is 22). The brute force attempts from these IPs hit various other ports, like port 23825.

Here’s my current setup. Snippet of UFW

Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
Anywhere                   REJECT IN
Anywhere                   REJECT IN
Anywhere                   REJECT IN
Anywhere                   REJECT IN

Snippet of corresponding IPtables

-A f2b-recidive -s -j REJECT --reject-with icmp-port-unreachable
-A f2b-recidive -s -j REJECT --reject-with icmp-port-unreachable
-A ufw-user-input -s -j REJECT --reject-with icmp-port-unreachable
-A ufw-user-input -s -j REJECT --reject-with icmp-port-unreachable

And my jail.local


enabled  = true
port     = ssh
filter   = sshd
logpath  = /var/log/auth.log
maxretry = 3

(Tho I tried to change the SSH jail to this, unsure if it’s properly configured or working or whatnot – I assume it’s not because I still get the emails re: these particular IPs)


enabled  = true
filter   = sshd
action   = iptables-allports[name=ssh,protocol=tcp]
           sendmail-whois-lines[name=SSH, logpath=/var/log/fail2ban.log]
logpath  = /var/log/auth.log
maxretry = 3

I’ve a few questions regarding all of this. 1 – Why isn’t UFW / IPTables blocking these IP addresses? (Seriously, this is the biggest Q) 2 – How do I set up fail2ban’s SSH jail to also dismiss all SSH attempts thru other ports? 3 – I’m no sysadmin but isn’t UFW/iptables supposed to be blocking those IP addresses even prior to f2b reporting and banning? After all, the packets need to hit the server, go thru the firewall, then get an entry logged into the system for f2b to read and action against.

Any help would be greatly appreciated.

Show comments

Submit an answer

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in Q&A, subscribe to topics of interest, and get courses and tools that will help you grow as a developer and scale your project or business.


The issue is that Fail2Ban uses iptables, not ufw (even if ufw is a wrapper for iptables). The order by which the rules are implemented is key as that’s the order they’ll be executed in. Any allow rule set by iptables that get’s executed before your ufw rules means that your ufw deny won’t do anything as the allow is already allowing the connection. If a block follows on down the list, that doesn’t matter either; the allow is still there before the deny or block.

To get around this, you can setup customized definitions for Fail2Ban. This is a more restrictive setup. It will ban any IP that is tagged with UFW BLOCK in the ufw log.

You can do this by creating a file:


and to it add:

actionstart =
actionstop =
actioncheck =
actionban = ufw insert 1 deny in from <ip>
actionunban = ufw delete deny in from <ip>

What the insert 1 does is ensure that this rule is added to the top.

Now we need to create a filter file to tell fail2ban when to ban a user. We can create a file named:


and to it add:

failregex = UFW BLOCK.* SRC=<HOST>
ignoreregex =

If you look at /var/log/ufw.log, you’ll see where this regex comes in to play. If you do not have a log file, try running ufw logging low or ufw logging medium. It seems in many cases, logging is either turned off by default or it’s on and the log file is never created. Running either of those commands will create that file.

Finally, we need to modify the jail.conf file and add:

enabled  = true
filter   = ufwscanban
logpath  = /var/log/ufw.log
action   = ufw
maxretry = 5

This limits the maxrety attempts to 5. If this limit is exceeded, the actionban action is taken. You’ll notice that the filter is simply set to the name of the filter file we created, without the .conf extension and that we’re using /var/log/ufw.log as the logpath, which in this case, is the file we’ll be scanning (which is why it’s important to run the commands mentioned above to ensure that this file is created).

Of course, this is just an example. And as above, it’s not port specific. This will block any IP on any port that exceeds the maximums.

As a side note, if you’re having complications with ufw + fail2ban beyond the above, you may want to look at Config Server Firewall (CSF) which has it’s own Login Failure Detection (LFD). It’s commonly used on cPanel/WHM servers, though it can be used effectively as a standalone (with options available from the CLI).

…of course, you’d want to make sure that Fail2Ban & UFW are disabled fully before enabling this. I can say, from experience, that it works and in most cases, it works without any issues (and it bans!). Just make sure you whitelist your IP('s).

The answer by @jtittle1 above is great! Here are the last details you should know:

  • UFW might even still register the blocked attempts in /var/log/ufw.log after all of this setup. The trick is to take a look at your rules with iptables -L -n and see where the ufw and fail2ban chains exist (also the DOCKER chains if you are using swarm). If you want to block absolutely everything you need to add rules to your first CHAIN. Here is an example stopping attacks from hitting the UFW logs after they have been banned. Notice the match-set badbots src rule… which is explained below.
Chain INPUT (policy DROP)
target     prot opt source               destination
DROP       all  --              match-set badbots src
ufw-before-logging-input  all  --  
ufw-before-input  all  --  
ufw-after-input  all  --  
ufw-after-logging-input  all  --  
ufw-reject-input  all  --  
ufw-track-input  all  --  
  • IPTABLES will start to slow down after many thousands of rules are added to the chains, and it will fall off a cliff (in terms of performance) at some point after that. There is a simple solution called IPSET that is a plugin to IPTABLES. Instead of pushing thousands of IP addresses into the IPTABLES chain, you can just add them to an IPSET ip hash, which uses a bintree lookup mechanism with average O(log n) search/insert/delete time complexity (Excellent!) , vs the IPTABLES O(n) time complexity (Fair). Take a look at the Big-O Complexity Chart to understand the performance difference. Here’s a quick-start guide to add IPSET to the setup that @jtittle1 gave above while being 100% certain the IPs are blocked from your entire server:
  1. apt-get install ipset
  2. ipset -exist create badbots iphash
  3. iptables -I INPUT 1 -m set --match-set badbots src -j DROP

Then change /etc/fail2ban/action.d/ufw.conf to this:


actionstart =
actionstop =
actioncheck =
actionban = ipset -exist add badbots <ip>
actionunban = ipset -exist del badbots <ip>

NOTICE: one IPSET hash can hold up to 65536 IPv4 addresses. You can check how many IPs have been added to your hash with ipset list badbots | wc -l. If you start to approach 65k at some point just create a second IPSET hash and begin using it:

  1. ipset -exist create badbots2 iphash
  2. iptables -I INPUT 1 -m set --match-set badbots2 src -j DROP

Then edit ufw.conf

actionban = ipset -exist add badbots2 <ip>
actionunban = ipset -exist del badbots2 <ip>