In this blog, we are going to discuss how to protect an
Odoo server with Fail2Ban configuration with Nginx on Ubuntu and learn how to install fail2ban on your Ubuntu 20.04 server. We will also discuss how to configure it to monitor Nginx logs for intrusion attempts.
Step 1 ā Installing and Configuring Fail2ban
Fail2ban is available in the Ubuntu software repositories. Run the following commands as a non-root user to update the list of packages and install Fail2ban.
$ sudo apt update
$ sudo apt install fail2ban
Fail2ban automatically configures the background service after installation. However, it is disabled by default because some settings may cause unwanted effects. You can check it with the systemctl command.
$ systemctl status fail2ban.service
Output :-
fail2ban.service - Fail2Ban Service
Loaded: loaded (/lib/systemd/system/fail2ban.service; disabled; vendor preset: enabled
Active: inactive (dead)
Docs: man:fail2ban(1)
You can activate Fail2ban right away, but first get to know a few features.
The fail2ban service stores configuration files in the /etc/fail2ban directory. There is a default configuration file called jail.conf. Change to this directory and print the first 20 lines of this file with a -20 header.
$ cd /etc/fail2ban
$ head -20 jail.conf
Output :-
#
# WARNING: heavily refactored in 0.9.0 release. Please review and
# customize settings for your setup.
#
# Changes: in most of the cases you should not modify this
# file, but provide customizations in jail.local file,
# or separate .conf files under jail.d/ directory, e.g.:
#
# HOW TO ACTIVATE JAILS:
#
# YOU SHOULD NOT MODIFY THIS FILE.
#
# It will probably be overwritten or improved in a distribution update.
#
# Provide customizations in a jail.local file or a jail.d/customisation.local.
# For example to change the default bantime for all jails and to enable the
# ssh-iptables jail the following (uncommented) would appear in the .local file.
# See man 5 jail.conf for details.
#
# [DEFAULT]
As you can see, the first few lines of this file are commented out. Beginning with a # character indicates that it should be read as a document, not as a setting. As you can see, this comment instructs us not to directly modify this file. Instead, you have two options. It is to create a separate profile for Fail2ban in several files in the jail.d/ directory, or to create and collect all local settings in the jail.local file.
The jail.conf file is updated periodically when Fail2ban itself is updated and is used as a source for default settings with no overrides created.
Here, create jail.local. You can do this by copying jail.conf.
$ sudo cp jail.conf jail.local
You can now start making configuration changes. Open the file in nano or your favorite text editor.
$ sudo nano jail.local
# Changing Defaults :
It starts by evaluating the default values ??set in the file. It's in the [DEFAULT] section of the file. These elements define general policy and can be overridden per application. If you are using nano, you can search for files by pressing Ctrl+W, typing a search string, and pressing Enter.
One of the first things to look at is the list of clients that are not covered by the fail2ban policy. This is set by the ignoreip directive. In some cases, it's a good idea to add your own IP address or network to the exclusion list so that you don't get blocked. Logging in to a web server is less of an issue than SSH. Because you can always bypass the ban as long as you can keep shell access. You can uncomment this line and add additional IP addresses or networks separated by spaces to the existing list.
[DEFAULT]
. . .
#ignoreip = 127.0.0.1/8 your_home_IP
Another customizable item is the Ban Time, which determines how many seconds violators will be banned. Ideally, this time should be long enough to prevent malicious automation actions but short enough to allow users to fix bugs. Default is 10 minutes. You can increase or decrease this value.
[DEFAULT]
. . .
bantime = 10m
The next two factors determine the amount of log lines used to determine bad clients. findtime specifies a time in seconds, and the maxretry directive specifies the number of attempts allowed within that time period. If a client makes more attempts than maxretry within the time set by findtime, it is forbidden.
[DEFAULT]
. . .
findtime = 10m
maxretry = 5
In the next step we will move on to setting up Nginx.
Step 2 ā Configuring Fail2Ban to Monitor Nginx Logs
Now that there are some common fail2ban settings, you can enable some Nginx-specific jails that monitor your web server logs for specific patterns.
Each prison in the configuration file is represented by a header containing the prison name in square brackets. Except for the [DEFAULT] section, each section specifies a specific jail configuration. By default, only the [ssh] jail is enabled.
Enable jail[nginx-http-auth] to enable log monitoring for Nginx login attempts. Add the enable=true directive to this section.
...
[nginx-http-auth]
enabled = true
port = http,https
logpath = %(nginx_error_log)s
. . .
When you're done making changes, save and close the file. If you are using nano, press Ctrl+X, then Y when prompted and press Enter. Next, review the filter configuration for nginx-http-auth.
Step 3 ā Reviewing Filters for Nginx Jails
You may have noticed that the [nginx-http-auth] block in jail.local doesn't contain any Nginx-specific rules. These rules are not hardcoded inside Fail2ban. In fact, the [nginx-http-auth] header directly matches the file name inside the Fail2ban filter.d directory of the prepackaged filter. By listing the contents of this directory, you will see other prepackaged filters that you can use when needed.
$ ls /etc/fail2ban/filter.d
Output :-
3proxy.conf freeswitch.conf proftpd.conf
apache-auth.conf froxlor-auth.conf pure-ftpd.conf
apache-badbots.conf gitlab.conf qmail.conf
apache-botsearch.conf grafana.conf recidive.conf
apache-common.conf groupoffice.conf roundcube-auth.conf
apache-fakegooglebot.conf gssftpd.conf scanlogd.conf
apache-modsecurity.conf guacamole.conf screensharingd.conf
apache-nohome.conf haproxy-http-auth.conf selinux-common.conf
apache-noscript.conf horde.conf selinux-ssh.conf
apache-overflows.conf ignorecommands sendmail-auth.conf
apache-pass.conf kerio.conf sendmail-reject.conf
apache-shellshock.conf lighttpd-auth.conf sieve.conf
assp.conf mongodb-auth.conf slapd.conf
asterisk.conf monit.conf softethervpn.conf
bitwarden.conf murmur.conf sogo-auth.conf
In the meantime take a look at nginx-http-auth.conf.
$ cat /etc/fail2ban/filter.d/nginx-http-auth.conf
Output :-
[Definition]
failregex = ^ \[error\] \d+#\d+: \*\d+ user "(?:[^"]+|.*?)":? (?:password mismatch|was not found in "[^\"]*"), client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(?:, referrer: "\S+")?\s*$
ignoreregex =
datepattern = {^LN-BEG}
In the next steps, youāll enable and test Fail2ban.
Step 4 ā Activating your Nginx Jails
At this point, you can enable the Fail2ban service to work automatically from now on. First, run systemctl enable.
$ sudo systemctl enable fail2ban
Then run systemctl to run it manually for the first time.
$ sudo systemctl start fail2ban
You can verify that itās running with systemctl status:
$ sudo systemctl status fail2ban
Output : -
fail2ban.service - Fail2Ban Service
Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: enabled
Active: active (running) since Fri 2022-07-08 17:19:38 UTC; 7s ago
Docs: man:fail2ban(1)
Main PID: 5962 (fail2ban-server)
Tasks: 7 (limit: 2327)
Memory: 12.6M
CPU: 195ms
CGroup: /system.slice/fail2ban.service
+-5962 /usr/bin/python3 /usr/bin/fail2ban-server -xf start
You will need to restart the fail2ban service to implement future configuration changes. You can do this with sudo systemctl restart fail2ban.
You should see a list of the enabled jails:
Output : -
Status
|- Number of jail: 2
`- Jail list: nginx-http-auth, sshd
Again use the fail2ban client to get detailed information about bans imposed by specific prisons.
$ sudo fail2ban-client status nginx-http-auth
Output : -
Status for the jail: nginx-http-auth
|- filter
| |- File list: /var/log/nginx/error.log
| |- Currently failed: 0
| `- Total failed: 0
`- action
|- Currently banned: 0
| `- IP list:
`- Total banned: 0
The last step in this blog is to intentionally test blocking to see if the Fail2ban configuration is working.
Step 5 ā Testing Fail2Ban Policies
It's important to test your Fail2ban policy to make sure it blocks traffic properly. To do this, go to the server in your local web browser. Re-enter incorrect credentials in Nginx authentication request. After several attempts, the server should completely stop responding as if the connection had been lost.
If you look at the nginx-http-auth config status with fail2ban-client, you can see the IP addresses blocked on your site. :
$ sudo fail2ban-client status nginx-http-auth
Output : -
Status for the jail: nginx-http-auth
|- Filter
| |- Currently failed: 0
| |- Total failed: 5
| `- File list: /var/log/nginx/error.log
`- Actions
|- Currently banned: 1
|- Total banned: 1
`- Banned IP list: 108.172.85.62
You can also view the new rules by checking the iptables output. iptables is a command that interacts with your server's low-level ports and firewall rules. If you followed DigitalOcean's initial server setup guide, you'll be using ufw to manage your firewall rules at a higher level. Running iptables -S will show all firewall rules that ufw has already created.
$ sudo iptables -S
Output : -
-P INPUT DROP
-P FORWARD DROP
-P OUTPUT ACCEPT
-N f2b-nginx-http-auth
-N ufw-after-forward
-N ufw-after-input
-N ufw-after-logging-forward
-N ufw-after-logging-input
-N ufw-after-logging-output
-N ufw-after-output
-N ufw-before-forward
-N ufw-before-input
-N ufw-before-logging-forward
-N ufw-before-logging-input
-N ufw-before-logging-output
If you pipe the output of iptables -S into grep to retrieve these rules for the f2b line, you will see the rules added by fail2ban.
$ sudo iptables -S | grep f2b
Output : -
-N f2b-nginx-http-auth
-A INPUT -p tcp -m multiport --dports 80,443 -j f2b-nginx-http-auth
-A f2b-nginx-http-auth -s 108.172.85.62/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-nginx-http-auth -j RETURN
The line with REJECT --reject-with icmp-port-unreachable was added by Fail2ban and should reflect the IP address of the local machine. Once you have confirmed that the rule is working, you can manually unban the IP address using fail2ban-client by typing.
$ sudo fail2ban-client set nginx-http-auth unbanip 108.172.85.62
You can now try to authenticate again.
Fail2ban gives you a lot of flexibility to create policies that fit your specific security needs. Many can be found by examining the variables and patterns in the /etc/fail2ban/jail.local file and the files they depend on in the /etc/fail2ban/filter.d and /etc/fail2ban/action.d directories. , you can customize and modify it according to your needs.
Protecting your server with fail2ban can provide a useful security foundation.