ManagedCloud Servers

High performance handled and monitored by us 24/7/365. A complete solution to provide you with our in house expertise 24/7 tailored to your specific needs. We'll setup a bespoke server for your site using the latest technologies so you can get the most out of your hardware and get your website loading quickly and reliably. Find out more..

cPanelCloud Servers

Recommended - High performance cloud servers with no technical knowledge required. If you're hosting multiple websites already and you're looking to consolidate, or if you're looking to isolate yourself from the shared hosting environment but you don't have the time or knoweldge to manage a server, then the Managed cPanel Servers are for you. Find out more..

UnmanagedCloud Servers

Our unmanaged range gives you complete control at rock bottom prices and our cloud platform boasts super fast multipath 40Gb/s network, the latest Intel Xeon V3 CPUs and enterprise grade redundant SSDs. If you're a sysadmin look no further, we offer some of the best specification to price ratio servers available. Find out more..

Want your very own server? Get our 1GB memory, Xeon V4, 20GB SSD VPS for £10.00 / month.

Get a Cloud Server

How to Secure Nginx Using Fail2ban on Centos-7


NGINX is the world's most popular open source web server and load balancer for high-traffic sites, powering over 140 million properties, so it is important to protect your website and users from brute-force attacks. Fail2ban is an intrusion prevention software framework that protects computer servers from brute-force attacks which is written in Python programming language. It is able to run on POSIX systems that have an interface to a packet-control system or firewall installed locally, for example, iptables or TCP Wrapper.

Fail2ban scans log files (e.g. /var/log/apache/error_log) and bans IPs that show the malicious signs -- too many password failures, seeking for exploits, etc. Generally Fail2Ban is then used to update firewall rules to reject the IP addresses for a specified amount of time, although any arbitrary other action (e.g. sending an email) could also be configured. Fail2Ban is able to reduce the rate of incorrect authentications attempts however; it cannot eliminate the risk that weak authentication presents. Configure services to use only two factor or public/private authentication mechanisms if you really want to protect services.Fail2ban blocks the source address using the regular linux firewall like iptables. You can configure fail2ban to send alert emails to you on each block. You can specify the amount of time you want the malicious source address to be kept blocked. You can also specify a list of source addresses in fail2ban configuration to be ignored.


  • Monitoring of log files.
  • Intrusion prevention.
  • Preventing dictionary attack.
  • Protection from DoS Attacks.
  • Update Netfilter/iptables or PF firewall rules.
  • Protect against a distributed brute-force attack.

In this tutorial, we will learn how to install Fail2ban and configure it to secure your Nginx server from DDoS attacks on CentOS-7


  • A server running CentOS-7.
  • A static IP Address for your server.
  • A non-root user account with sudo privilege set up on your server.

Getting Started

Let's start by making sure that your CentOS server is fully up to date.

You can update your server by running the following command:

sudo yum update -y

Install Nginx

By default Nginx is not available in the Centos-7 repository. You will need to install EPEL repository in order to install Nginx.

You can install the EPEL repository by running the following command:

sudo yum install epel-release

Now that the Nginx repository is installed on your server, you can install Nginx using the following yum command:

sudo yum install nginx

Nginx does not start on its own. To get Nginx running, type:

sudo systemctl start nginx

If you are running a firewall, run the following commands to allow HTTP and HTTPS traffic:

sudo firewall-cmd --permanent --zone=public --add-service=httpsudo firewall-cmd --permanent --zone=public --add-service=httpssudo firewall-cmd --reload

Before continuing, you will probably want to enable Nginx to start when your system boots. To do so, enter the following command:

sudo systemctl enable nginx

Now check on your machine that nginx web server is running or not by typing the URL http://localhost or http://server-ip-address in your browser.

You will see following image:

The above page is used to test the proper operation of the nginx HTTP server after it has been installed. If you can read this page, it means that the web server installed at this site is working properly.

#Configure Nginx Password Authentication

To start out, you need to create the file that will hold your username and password combinations. You can do this by using the OpenSSL utilities that may already be available on your server. If you have OpenSSL installed on your server, you can create a password file with no additional packages. We will create a hidden file called .htpasswd in the /etc/nginx configuration directory to store our username and password combinations.

You can add a username to the file using this command. We are using hitesh as our username, but you can use whatever name you'd like:

sudo sh -c "echo -n 'hitesh:' > /etc/nginx/.htpasswd"

Next, add an encrypted password entry for the username by typing:

sudo sh -c "openssl passwd -apr1 >> /etc/nginx/.htpasswd"

You can repeat this process for additional usernames. You can see how the usernames and encrypted passwords are stored within the file by typing:

cat /etc/nginx/.htpasswd

You should see the following output:


Now that you have a file with your users and passwords in a format that Nginx can read, you need to configure Nginx to check this file before serving our protected content. Begin by opening up the server block configuration file that you wish to add a restriction to.

sudo nano /etc/nginx/nginx.conf

Inside, with the comments stripped, the file should look similar to this:

    server {

listen 80 default_server;

listen [::]:80 default_server;

server_name _;

root /usr/share/nginx/html;

# Load configuration files for the default server block.

include /etc/nginx/default.d/*.conf;

location / {


error_page 404 /404.html;

location = /40x.html {


error_page 500 502 503 504 /50x.html;

location = /50x.html {



To set up authentication, you will need to decide on the context to restrict. Among other choices, Nginx allows you to set restrictions on the server level or inside a specific location. In our example, we'll restrict the entire document root with a location block, but you can modify this listing to only target a specific directory within the web space. Within this location block, use the auth_basic directive to turn on authentication and to choose a realm name to be displayed to the user when prompting for credentials. We will use the auth_basic_user_file directive to point Nginx to the password file we created:

sudo nano /etc/nginx/nginx.conf

Add / Edit the following lines:

    server {

listen 80 default_server;

listen [::]:80 default_server;

server_name _;

root /usr/share/nginx/html;

# Load configuration files for the default server block.

include /etc/nginx/default.d/*.conf;

location / {

} error_page 404 /404.html;

location = /40x.html {


auth_basic "Restricted Content";

auth_basic_user_file /etc/nginx/.htpasswd;

error_page 500 502 503 504 /50x.html;

location = /50x.html {



Save and close the file when you are finished. Restart Nginx to implement your password policy:

sudo systemctl restart nginx

The directory you specified should now be password protected.

To confirm that your content is protected, try to access your restricted content in a web browser by typing the URL http://server-ip-address. You should be presented with a username and password prompt that looks like this:

If you enter the correct credentials, you will be allowed to access the content. If you enter the wrong credentials or hit "Cancel", you will see the "Authorization Required" error page:

You should now have everything you need to set up basic authentication for your site. Keep in mind that password protection should be combined with SSL encryption so that your credentials are not sent to the server in plain text.

Install Fail2ban

Once your Nginx server is running and password authentication is enabled, you can go ahead and install Fail2ban. Fail2ban is an intrusion prevention framework, which works together with a packet-control system or firewall installed on your server. It is commonly used to block connection attempts after a number of failed tries. It operates by monitoring log files for certain type of entries and runs predetermined actions based on its findings. Install the program using the command below.

sudo yum install fail2ban fail2ban-systemd

By default, fail2ban is configured to only ban failed SSH login attempts. You will need to enable some rules that will configure it to check our Nginx logs for patterns that indicate malicious activity. Once installed, copy the default jail.conf file to make a local configuration with this command

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Then open the new local configuration file for edit with your favourite text editor, for example

sudo nano /etc/fail2ban/jail.local

Add / Edit the file as shown below:


# MISCELLANEOUS OPTIONS # "ignoreip" can be an IP address, a CIDR mask or a DNS host. Fail2ban will not # ban a host which matches an address in this list. Several addresses can be # defined using space separator.

ignoreip = server-ip-address

# External command that will take an tagged arguments to ignore, e.g. , # and return true if the IP is to be ignored. False otherwise. # ignorecommand = /path/to/command

ignorecommand =

# "bantime" is the number of seconds that a host is banned.

bantime = 600

# A host is banned if it has generated "maxretry" during the last "findtime" seconds.

findtime = 600

# "maxretry" is the number of failures before a host get banned.

maxretry = 5

Save and close the file.

  • Ignoreip is used to set the list of IPs which will not be banned. The list of IP addresses should be given with a space separator. This parameter is used to set your personal IP address (if you access the server from a fixed IP).
  • The Bantime parameter is used to set the duration of seconds for which a host needs to be banned.
  • Findtime is the parameter which is used to check if a host must be banned or not. When the host generates maxrety in its last findtime, it is banned.
  • Maxretry is the parameter used to set the limit for the number of retry's by a host, upon exceeding this limit, the host is banned.

Execute the following lines of command to run the protective Fail2Ban software on the server.

sudo systemctl enable fail2bansudo systemctl start fail2ban

Configuring Fail2Ban to Monitor Nginx Logs

Now that you have some of the general Fail2ban settings in place, you can concentrate on adding some Nginx-specific jails that will monitor your web server logs for specific behavior patterns. Each jail within the configuration file is marked by a header containing the jail name in square brackets (every section but the [DEFAULT] section indicates a specific jail's configuration).

sudo nano /etc/fail2ban/jail.local

Add the following content:

    #To enable log monitoring for Nginx login attempts.

[nginx-auth] enabled = true filter = nginx-auth action = iptables-multiport[name=NoAuthFailures, port="http,https"] logpath = /var/log/nginx*/*error*.log bantime = 600 # 10 minutes maxretry = 6

[nginx-login] enabled = true filter = nginx-login action = iptables-multiport[name=NoLoginFailures, port="http,https"] logpath = /var/log/nginx*/*access*.log bantime = 600 # 10 minutes maxretry = 6

#This is the only Nginx-specific jail included with CentOS 7 fail2ban package. However, you can create our own jails to add additional functionality. #You can create an [nginx-noscript] jail to ban clients that are searching for scripts on the website to execute and exploit. If you do not use PHP #or any other language in conjunction with your web server, you can add this jail to ban those who request these types of resources: #to ban clients that are searching for scripts on the website to execute and exploit.

[nginx-noscript] enabled = true action = iptables-multiport[name=NoScript, port="http,https"] filter = nginx-noscript logpath = /var/log/nginx*/*access*.log maxretry = 6 bantime = 86400 # 1 day

#You can add a section called [nginx-badbots] to stop some known malicious bot request patterns: # to stop some known malicious bot request patterns

[nginx-badbots] enabled = true filter = apache-badbots action = iptables-multiport[name=BadBots, port="http,https"] logpath = /var/log/nginx*/*access*.log bantime = 86400 # 1 day maxretry = 1

#If you do not use Nginx to provide access to web content within users' home directories, you can ban users who request these resources by adding an #[nginx-nohome] jail: #to provide access to web content within users' home directories

[nginx-nohome] enabled = true port = http,https filter = nginx-nohome logpath = /var/log/nginx/access.log maxretry = 2

#We should ban clients attempting to use our Nginx server as an open proxy. We can add an [nginx-noproxy] jail to match these requests: #ban clients attempting to use our Nginx server as an open proxy

[nginx-proxy] enabled = true action = iptables-multiport[name=NoProxy, port="http,https"] filter = nginx-proxy logpath = /var/log/nginx*/*access*.log maxretry = 0 bantime = 86400 # 1 day

When you are finished making the modifications you need, save and close the file. You now have to add the filters for the jails that we have created.

Adding the Filters for Additional Nginx Jails

You will need to updated the /etc/fail2ban/jail.local file with some additional jail specifications to match and ban a larger range of bad behavior. You need to create the filter files for the jails we've created. These filter files will specify the patterns to look for within the Nginx logs.Begin by changing to the filters directory:

cd /etc/fail2ban/filter.d

We actually want to start by adjusting the pre-supplied Nginx authentication filter to match an additional failed login log pattern. You can do this by creating nginx-auth.conf file:

sudo nano nginx-auth.conf

Add the following content:

    # Auth filter /etc/fail2ban/filter.d/nginx-auth.conf:
    # Blocks IPs that fail to authenticate using basic authentication


failregex = no user/password was provided for basic authentication.*client: user .* was not found in.*client: user .* password mismatch.*client:

ignoreregex =

Save and close the file when you are finished.

Next, create another file:

sudo nano nginx-proxy.conf

Add the following content:

    # Proxy filter /etc/fail2ban/filter.d/nginx-proxy.conf:
    # Block IPs trying to use server as proxy.
    # Matches e.g.
    # - - "GET
    failregex = ^ -.*GET http.*
    ignoreregex =

Save and close the file when finished.

Next, create the filter for the [nginx-noscript] jail:

sudo nano nginx-noscript.conf

Add the following content:

    # Noscript filter /etc/fail2ban/filter.d/nginx-noscript.conf:
    # Block IPs trying to execute scripts such as .php, .pl, .exe and other funny scripts.
    # Matches e.g.
    # - - "GET /something.php

[Definition] failregex = ^ -.*GET.*(.php|.asp|.exe|.pl|.cgi|scgi) ignoreregex =

Save and close the file when you are finished.

Next, create the filter for the [nginx-noscript] jail:

sudo nano nginx-login.conf

Add the following content:

    # Login filter /etc/fail2ban/filter.d/nginx-login.conf:
    # Blocks IPs that fail to authenticate using web application's log in page
    # Scan access log for HTTP 200 + POST /sessions => failed log in
    failregex = ^ -.*POST /sessions HTTP/1.." 200
    ignoreregex =

Save and close the file when you are finished.

To implement your configuration changes, you'll need to restart the fail2ban service. You can do that by typing:

sudo service fail2ban restart

The service should restart, implementing the different banning policies you've configured.

You can see all of your enabled jails by using the fail2ban-client command:

sudo fail2ban-client status

You should see a list of all of the jails you enabled:

    |- Number of jail:  5
    `- Jail list:       nginx-badbots, nginx-login, nginx-proxy, nginx-auth, nginx-noscript, nginx-nohome

You should test your fail2ban rules with the fail2ban-regex command:

sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-auth.conf

You should see the following output:

    Running tests

Use regex file : /etc/fail2ban/filter.d/nginx-auth.conf Use log file : /var/log/nginx/access.log

Results =======

Failregex: 0 total

Ignoreregex: 0 total

Summary =======

Sorry, no match

Look at the above section 'Running tests' which could contain important information.

You can look at iptables to see that fail2ban has modified your firewall rules to create a framework for banning clients. Even with no previous firewall rules, you would now have a framework enabled that allows fail2ban to selectively ban clients by adding them to purpose-built chains:

sudo iptables –S

You should see the following output:

    -N FORWARD_direct
    -N FWDI_public
    -N FWDI_public_allow
    -N FWDI_public_deny
    -N FWDI_public_log
    -N FWDO_public
    -N FWDO_public_allow
    -N FWDO_public_deny
    -N FWDO_public_log
    -N INPUT_direct
    -N IN_public
    -N IN_public_allow
    -N IN_public_deny
    -N IN_public_log
    -N OUTPUT_direct
    -N fail2ban-BadBots
    -N fail2ban-NoAuthFailures
    -N fail2ban-NoLoginFailures
    -N fail2ban-NoProxy
    -N fail2ban-NoScript
    -A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-NoProxy
    -A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-NoScript
    -A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-BadBots
    -A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-NoLoginFailures
    -A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-NoAuthFailures
    -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    -A INPUT -i lo -j ACCEPT
    -A INPUT -j INPUT_direct
    -A INPUT -p icmp -j ACCEPT
    -A INPUT -j REJECT --reject-with icmp-host-prohibited
    -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    -A FORWARD -i lo -j ACCEPT
    -A FORWARD -j FORWARD_direct
    -A FORWARD -p icmp -j ACCEPT
    -A FORWARD -j REJECT --reject-with icmp-host-prohibited
    -A OUTPUT -j OUTPUT_direct
    -A FORWARD_IN_ZONES -i eth0 -g FWDI_public
    -A FORWARD_IN_ZONES -g FWDI_public
    -A FORWARD_OUT_ZONES -o eth0 -g FWDO_public
    -A FWDI_public -j FWDI_public_log
    -A FWDI_public -j FWDI_public_deny
    -A FWDI_public -j FWDI_public_allow
    -A FWDO_public -j FWDO_public_log
    -A FWDO_public -j FWDO_public_deny
    -A FWDO_public -j FWDO_public_allow
    -A INPUT_ZONES -i eth0 -g IN_public
    -A INPUT_ZONES -g IN_public
    -A IN_public -j IN_public_log
    -A IN_public -j IN_public_deny
    -A IN_public -j IN_public_allow
    -A IN_public_allow -p tcp -m tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT
    -A IN_public_allow -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
    -A IN_public_allow -p tcp -m tcp --dport 8080 -m conntrack --ctstate NEW -j ACCEPT
    -A fail2ban-BadBots -j RETURN
    -A fail2ban-NoAuthFailures -j RETURN
    -A fail2ban-NoLoginFailures -j RETURN
    -A fail2ban-NoProxy -j RETURN
    -A fail2ban-NoScript -j RETURN

Testing Fail2Ban Policies

It is important to test your Fail2ban policies to ensure they block traffic as expected. For instance, from the client machine open your web browser and type the URL http://server-ip-address, whe Nginx authentication prompt, give incorrect credentials a number of times. After you have surpassed the limit, you should be banned and unable to access the site.

On server machine, If you look at the status with the fail2ban-client command, you will see your IP address being banned from the site:

sudo fail2ban-client status nginx-auth


    Status for the jail: nginx-auth
    |- filter
    |  |- File list: /var/log/nginx/error.log
    |  |- Currently failed: 5
    |  `- Total failed: 0
    `- action
       |- Currently banned: 1
       |  `- IP list:   
       `- Total banned: 1
       `- Banned IP list:

When you are satisfied that your rules are working, you can manually un-ban your IP address with the fail2ban-client command:

sudo fail2ban-client set nginx-auth unbanip

You should now be able to attempt authentication again.


In this tutorial, you learned how to install nginx and fail2ban in CentOS-7. Fail2ban provides a great deal of flexibility to construct policies that will suit your specific security needs. You can look at the variables and patterns within the /etc/fail2ban/jail.local file, and the files it depends on within the /etc/fail2ban/filter.d and /etc/fail2ban/action.d directories, you can make more secure environment for your website. By using fail2ban, you can stop security attacks on your web server and prevent this type of attack in automated manner.

Want your very own server? Get our 1GB memory, Xeon V4, 20GB SSD VPS for £10.00 / month.

View Plans