{"id":401,"date":"2020-10-14T15:00:45","date_gmt":"2020-10-14T15:00:45","guid":{"rendered":"https:\/\/dft.wiki\/?p=401"},"modified":"2026-04-21T13:35:56","modified_gmt":"2026-04-21T17:35:56","slug":"increase-security-with-fail2ban-on-ubuntu-20-4","status":"publish","type":"post","link":"https:\/\/dft.wiki\/?p=401","title":{"rendered":"Increasing Security with Fail2Ban on Ubuntu"},"content":{"rendered":"<p><strong>Fail2Ban<\/strong> is a service that watches the log files of your services, such as SSH, HTTP, and FTP, looking for consecutive authentication fails that may indicate an unauthorized person trying to get in.<\/p>\n<p>When detecting a possible intruder that fails to log in X attempts in Y length of time, it bans the origin IP address for Z time. It creates a rule in your firewall to ban and automatically removes it after the ban time expires.<\/p>\n<pre>sudo apt update\r\nsudo apt install fail2ban\r\nsudo systemctl status fail2ban<\/pre>\n<p>You might see the service active (running).<\/p>\n<pre>sudo cp \/etc\/fail2ban\/jail.{conf,local}\r\nsudo nano \/etc\/fail2ban\/jail.local<\/pre>\n<p>Inform your white list. Uncomment this line and fill it with the &#8220;safe&#8221; IP addresses. Usually, I would put the loopback interfaces (127.0.0.1\/8 and ::1), and if you access your network remotely via VPN for example, I would also include the VPN network IP (10.8.0.0\/24) in this list.<\/p>\n<pre>ignoreip = 127.0.0.1\/8 ::1 10.8.0.0\/24<\/pre>\n<p>Before you leave the file, you have to define X, Y, and Z:<\/p>\n<pre>bantime = <strong>1d<\/strong>\r\nfindtime = <strong>60m<\/strong>\r\nmaxretry = <strong>5<\/strong>\r\nbackend = <strong>systemd<\/strong><\/pre>\n<p>In my case, if someone fails 5 times 60 minutes will be banned for 1 day. Change also the backend to &#8220;systems&#8221; because it comes by default as &#8220;auto&#8221; but for some reason, the filter was not catching anything.<\/p>\n<p>Configure the e-mail alert notification when someone is banned (you need an SMTP server installed and running):<\/p>\n<pre>destemail = admin@yourdomain.com\r\nsender = root@yourdomain.com\r\naction = %(action_mw)s<\/pre>\n<p>Now you can go down and look for the service you want to protect. You should only enable the ones that you need, not just everything without criteria.<\/p>\n<pre>[sshd]\r\n<strong>enabled = true<\/strong>\r\n#mode = normal\r\nport = ssh\r\nlogpath = %(sshd_log)s\r\nbackend = %(sshd_backend)s<\/pre>\n<p>Insert the <strong>enabled = true<\/strong> at the &#8220;Jail&#8221; you are creating.<\/p>\n<p>In the example above, I activated on my SSH server, and I would do the same with HTTP, FTP, and any other service that is exposed to the internet and requires authentication.<\/p>\n<p>Note that I left one commented line on the last example. You can uncomment the <strong>mode = normal<\/strong> and change it to a more aggressive approach, like <strong>DDoS<\/strong>, <strong>extra,<\/strong> or <strong>aggressive<\/strong>. See &#8220;filter.d\/sshd.conf&#8221; for usage example and details.<\/p>\n<p>Save the configuration file, restart your service, and check if it is running or has failed due to any configuration issue:<\/p>\n<pre>sudo systemctl restart fail2ban\r\nsudo systemctl status fail2ban<\/pre>\n<p>Fail2Ban offers a CLI that makes it possible for you to interact with the service called <strong>fail2ban-client<\/strong>. See examples of usage:<\/p>\n<pre>sudo fail2ban-client status sshd\r\nsudo fail2ban-client set sshd unbanip 1.1.1.1\r\nsudo fail2ban-client set sshd banip 1.1.1.1\r\nsudo fail2ban-client -h<\/pre>\n<p>Right after setting up this service, I just received 46 new emails of banned IPs trying to enter my SSHD as root (I omitted the last number):<\/p>\n<pre>Total failed: <strong>1106<\/strong>\r\nTotal banned: <strong>38<\/strong>\r\nBanned <strong>IP list<\/strong>: 93.39.184.1X 95.78.251.11X 208.109.11.3X 167.71.237.7X 162.243.130.8X 82.65.23.6X 100.26.163.9X (...)<\/pre>\n<p>Checking the origin of the IP addresses, I can only say that they come from anywhere: USA, CH, IND, SG, RU, IT, FR, UK, GER, VN, NL, HK, etc. Most of them are from OVH SAS and DigitalOcean (private cloud services).<\/p>\n<p>Consequently, from the large number of &#8220;hackers&#8221;, I had to disable the email notification (more than 10 emails per hour).<\/p>\n<p>A week after setting up this safety tool, the number of bans on my SSH fell from 200 a day to 4. The only reason I see for it is that by being banned, many might get discouraged to keep trying. So, for the same reason, I will disable ping responses to not advertise that my server is live and see if I get any improvement.<\/p>\n<p>If you want to get all the status at the same time (it is one big line):<\/p>\n<pre>fail2ban-client status | sed -n 's\/,\/\/g;s\/.*Jail list:\/\/p' | xargs -n1 fail2ban-client status<\/pre>\n<hr \/>\n<p><strong>BONUS<\/strong><\/p>\n<p>Did you know you can use Fail2Ban also to protect your <strong>WordPress<\/strong> website? See more in WordPress Configuration Tips and Tricks [<a href=\"https:\/\/dft.wiki\/?p=405\">Link<\/a>].<\/p>\n<p>As an alternative to Fail2Ban, the open source <strong>SSHGuard<\/strong> aims to accomplish the same goal [<a href=\"https:\/\/bitbucket.org\/sshguard\/sshguard\/\">Link<\/a>].<\/p>\n<pre>sudo apt update &amp;&amp; sudo apt install sshguard -y\r\necho '192.168.1.0\/24' &gt;&gt; \/etc\/sshguard\/whitelist\r\nsudo nano \/etc\/sshguard\/sshguard.conf<\/pre>\n<p>Configure accordingly.<\/p>\n<pre># For IPTABLES\r\nBACKEND=\"\/usr\/lib\/sshguard\/sshg-fw-iptables\"\r\n# For NFTABLES\r\n#BACKEND=\"\/usr\/lib\/sshguard\/sshg-fw-nft-sets\"\r\nWHITELIST_FILE=\"\/etc\/sshguard\/whitelist\"\r\nBLOCK_TIME=1200\r\nDETECTION_TIME=1800\r\nTHRESHOLD=30<\/pre>\n<p>Start and check the activity in the logs.<\/p>\n<pre>sudo systemctl enable sshguard --now\r\nsudo journalctl -u sshguard -f<\/pre>\n<p>List the banned IPs and unban by line number.<\/p>\n<pre>sudo iptables --list sshguard --line-numbers --numeric\r\nsudo iptables --delete sshguard &lt;line-number&gt;<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Fail2Ban is a service that watches the log files of your services, such as SSH, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,6],"tags":[],"class_list":["post-401","post","type-post","status-publish","format-standard","hentry","category-linux","category-raspberry-pi"],"_links":{"self":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts\/401","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=401"}],"version-history":[{"count":17,"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts\/401\/revisions"}],"predecessor-version":[{"id":5498,"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts\/401\/revisions\/5498"}],"wp:attachment":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=401"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=401"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=401"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}