Scale up as you grow — whether you're running one virtual machine or ten thousand.

From GPU-powered inference and Kubernetes to managed databases and storage, get everything you need to build, scale, and deploy intelligent applications.

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!
I’ve been considering fail2ban but am unsure if I really need it. I have disabled password login and setup my iptable rules which are below:
-P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -d 127.0.0.0/8 ! -i lo -j DROP -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A INPUT -j DROP -A FORWARD -j DROP -A OUTPUT -j ACCEPT
I installed fail2ban, and after it inserted its rules, my iptables now look like this:
-P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT -N fail2ban-nginx-http-auth -N fail2ban-ssh -A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-nginx-http-auth -A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh -A INPUT -i lo -j ACCEPT -A INPUT -d 127.0.0.0/8 ! -i lo -j DROP -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A INPUT -j DROP -A FORWARD -j DROP -A OUTPUT -j ACCEPT -A fail2ban-nginx-http-auth -j RETURN -A fail2ban-ssh -j RETURN
I’m guessing there is some redundancy/overkill now. Thoughts?
Hi brandon:
Looking at your configuration, I would say that fail2ban is still going to be useful for you. Your first configuration that you posted above drops connection attempts that are not directed to port 80, 443, or 22 (as well as allowing local connections).
However, the point of fail2ban is to ban people who repeatedly fail to authenticate. This means that if someone is attempting to log into SSH, they will be banned after a few attempts, causing them to move on. This rule would be added to the fail2ban-ssh chain prior to the -A fail2ban-ssh -j RETURN rule.
While this might not seem like a big deal considering that you have already disabled password logins through the sshd config file, it will help keep your logs clean. This can be incredibly useful when you are trying to analyze your logs in case of a problem by cutting down on the background noise.
Also, with the Nginx, the Auth_Basic module that provides authentication doesn’t have the functionality to limit attempts. If you have sections of your site protected by password authentication, you probably will benefit from a service like fail2ban limiting the number of authentication attempts.
In general though, this is up to you and if you feel that fail2ban is not providing value, you do not have to use it. However, in my testing, it doesn’t use many resources, so it may be worth it to keep it around just as an extra level of protection.
Thank you very much. I’m happy to use fail2ban, but am worried that it might not play nice with my current iptables rules. If the above config (my rules + fail2ban rules) looks good, please let me know. Specifically I was wondering if:
These rules:
-A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-nginx-http-auth -A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh
make these rules irrelevant:
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
By the way, your tutorials have been great and I’ve learn a lot from them!
Hey brandon:
No, those lines will do different things. Hopefully I can explain why that is.
With your original configuration, a packet will be compared to each of the rules in your INPUT chain. At the end of your INPUT chain, you have a rule to drop any traffic that hasn’t matched so far. That’s why before that rule, you needed the original lines that explicitly allow generic traffic aimed at your web server and ssh daemon respectively. These will catch the web and ssh traffic and allow it to pass before it gets dropped.
The fail2ban rules that are added initially simply do one thing: at the very beginning of the INPUT chain, they will temporarily divert generic traffic aimed at those services to a new chain. These new chains are empty at the beginning except for one rule, which just hands control back to the INPUT chain, where it will continue on down the line, just like normal. These packets will still be dropped if they reach the end of the INPUT chain, just like they used to, so your original rules for the web server and ssh daemon are still necessary.
When a client is banned for failing to authenticate, fail2ban adds a new rule to the new fail2ban-* chain. The new rule checks whether the traffic is coming from the banned host. If it matches, the packets are dropped. If the traffic doesn’t match, it reaches the rule that returns the packet to the INPUT chain where it continues as described above.
So all that the initial fail2ban lines do is create an extra loop where additional checks can be made to deny specific clients. The flow is always returned to the main INPUT chain for traffic not matching a banned client. It doesn’t make any decision on the fate of the packet if it doesn’t match the ban list. That is left to the rules in your INPUT chain. The key rule to understand here is the -j RETURN rule at the bottom of the new chains, which tell the packet to continue where it left off in the original INPUT chain.
Great tutorial, as always! But I’m having a problem with fail2ban, when trying to get banned, I don’t see any modification in my iptables rules. I use a non-standard ssh port, let’s say 4422, when I changed that configuration in the jail.local the fail2ban rule no longer has the “-j fail2bah-ssh” at the end, I don’t know if this has anything to do with the issue.
Here are my iptable rules:
-P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT -N fail2ban-ssh -A INPUT -p tcp -m multiport --dports 4422 -A INPUT -i lo -j ACCEPT -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp -m tcp --dport 4422 -j ACCEPT -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT -A INPUT -j DROP -A fail2ban-ssh -j RETURN
Any ideas?
Thanks!
Thanks for the tutorial. I have just joined Digital Ocean and didn’t realise how many useful tutorials it has.
I don’t quite get the mta = sendmail directive. For this to work, evidently you don’t need to install sendmail. I thought that you did, but I didn’t want to use sendmail, so I installed postfix and had fun configuring it. But, fail2ban really didn’t like me using postfix as the mta. I can post the error, but right now, I am just interested in generalisations, and I guess I can just go ahead and uninstall postfix, since fail2ban works without it anyway.
By the way, I configured postfix to only deal with local mail, as in mail originating on my machine only and delivered to root@localhost only.
@dconn6: postfix also installs a sendmail command. Take a look at “man sendmail” On a system using postfix, it will say “sendmail - Postfix to Sendmail compatibility interface” So even if you’re using postfix, just have sendmail for the mta directive.
Thank you!
I follows the tutorial and worked perfectly. However i am not sure what i did but now i try to trigger the rule by attempting failed logins for several times and it is not generating the rule that blocks the ip. Then i notice i got a notification. It mentioned that an ip attempted 37 times. Until then it generated the rule, blocked the ip and sent the notification. Why is it allowing so many attempts when the configuration I set was for 4 retries?
How can i fix this?
Thank you
@garsoltero: Make sure you restart it after making any configuration changes: <code>sudo service fail2ban restart</code> Also make sure <code>findtime</code> isn’t set too low.
@andrewSB: After integrating fail2ban, I can no longer access my site with https, any ideas as to what might be the issue?
‘sudo iptables -S’ returns this:
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N fail2ban-nginx-http-auth
-N fail2ban-ssh
-N udp-flood
-A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-nginx-http-auth
-A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -j DROP
-A OUTPUT -p udp -j udp-flood
-A fail2ban-nginx-http-auth -j RETURN
-A fail2ban-ssh -j RETURN
-A udp-flood -p udp -m limit --limit 50/sec -j RETURN
-A udp-flood -j LOG --log-prefix "UDP-flood attempt: "
-A udp-flood -j DROP