11th June, 2016 | Tutorials |

Install and Secure Nginx on CentOS 7

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

Get a Cloud Server


Nginx [engine x] is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server, originally written by Igor Sysoev.

Nginx is a high performance web server software. It was released for production in 2004. Nginx uses an asynchronous event-driven approach to handling requests, similar to Apache HTTP Server Event MPM model. Nginx's modular event-driven architecture can provide more predictable performance under high loads.


Nginx is a much more flexible and lightweight program than Apache Web Server. It features an event-driven design, which can make better use of today's computer hardware than Apache's process-driven design. It comes in two flavours 1. Free & Open Source and 2. Nginx Plus, which is commercially supported product from NGINX, Inc.

The detailed features are listed below:

  1. Handling of static files, index files and auto-indexing.
  2. Load balancing with in-band health checks.
  3. Ability to handle more than 10,000 simultaneous connections with a low memory footprint.
  4. TLS/SSL with SNI and OCSP stapling support, via OpenSSL.
  5. Name and IP address-based virtual servers.
  6. gzip compression and decompression.
  7. Web page access authentication.

The paid NGINX Plus product includes additional features such as advanced load balancing and access to an expanded suite of metrics for performance monitoring.

In this tutorial, we will learn how to install nginx (FOSS) & secure it on CentOS 7 GNU/Linux.


Getting Started

Let's start by making sure that your Centos-7 server is fully up to date. You can update your server by running the following command:

sudo yum update -y

Install Nginx

Before installing Nginx, you will need to install the EPEL repository as pre-requisite to install nginx.

You can install it by simply running the following command:

sudo yum install epel-release

Then, install Nginx by running the following command:

sudo yum install nginx

Next, start Nginx service by running the following command:

sudo systemctl start nginx

Then, add Nginx service to start at boot time by running the following command:

sudo systemctl enable nginx

You should see the following output:

    Created symlink from /etc/systemd/system/ to /usr/lib/systemd/system/nginx.service.

Next, you will need to allow the default Nginx port 80 (HTTP) and 443 (HTTPS) using FirewallD. You can do this by running the following commands:

sudo firewall-cmd --permanent --add-port=80/tcp sudo firewall-cmd --permanent --add-port=443/tcp

Reload the firewall service for the changes to take effect.

sudo firewall-cmd –reload

Secure Nginx Web Server

In this section, we will learn how to secure Nginx web server.

Update Your Server Packages

A great first step in securing your entire system along with nginx is to update all the packages on your system.

sudo yum update -y

Note: Be sure to determine whether or not update will cause issues with anything running on your system other than Nginx before updating all the packages on your system.

Hide Nginx Version

By default, Nginx shows its name and version in the HTTP headers which can be checked by running following curl command.,

curl -I http://localhost
    Output of curl -I http://localhost
    HTTP/1.1 200 OK
    Server: nginx/1.5.6 (CentOS)

The version of Nginx and the name of the operating system can be seen in the above output, which an attacker can try to solve to compromise Nginx server.

This can be a major security issue for your web server. To hide this information, you need to edit Nginx main configuration file.

sudo nano /etc/nginx/nginx.conf

To hide this header information, add the line server_tokens off; inside the http configuration part in 'nginx.conf' file.

    http {
        server_tokens off;

Save & exit config file and reload 'nginx' service.

sudo systemctl reload nginx

The following is the output of curl after turning of server tokens on nginx configuration -

    HTTP/1.1 200 OK
    Server: nginx

Setup HTTP Basic Authentication

You will need to install the httpd-tools package to get the htpasswd command. This command configures the password to restrict access to the target website.

sudo yum install -y httpd-tools

Create a username & password for basic http authentication. The username & password can be stored in a file which we specify at creation time. The password will be encrypted & saved in file. Run following command to create credentials,

sudo htpasswd -c /etc/nginx/.htpasswd nginx

In above command we are storing credentials in /etc/nginx/.htpasswd for user nginx.

You can check the contents of the newly-created file to see the username and hashed password.

sudo cat /etc/nginx/.htpasswd

Update the 'nginx' configuration by adding the auth_basic and auth_basic_user_file directives in its configuration file.

Add above mentioned directives by editing /etc/nginx/nginx.conf file:

sudo nano /etc/nginx/nginx.conf

Under the server section, add auth_basic and auth_basic_user_file directives,

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;
        auth_basic "Private Property";
        auth_basic_user_file /etc/nginx/.htpasswd;

Reload nginx to test the changes with the following command -

sudo systemctl reload nginx

Now try accessing the website you just secured by going to http://your_server_ip/ in your browser. It should present an authentication window (which says "Private Property", the string we set for auth_basic), and you will not be able to access the website until you enter the correct credentials.

onfigure SSL for Nginx

SSL (Secure Socket Layer protocol) was created by Netscape to secure transactions between web servers and browsers.

SSL is an essential part of creating a secure Apache site. SSL certificates allow you encrypt all the traffic sent to and from your Apache web site to prevent others from viewing all of the traffic. It uses public key cryptography to establish a secure connection. This means that anything encrypted with a public key (the SSL certificate) can only be decrypted with the private key.

In order to set up the self-signed certificate, you will need to install mod_ssl Apache module in your system.

You can install mod_ssl by running the following command:

sudo yum install mod_ssl

Create a directory for SSL certificates with following command:

sudo mkdir /etc/nginx/ssl/

For SSL we'll need a certificate with a strong signature algorithm, SHA256. For testing purposes or non-production environments you can use a self-signed certificate while ignoring the SSL warnings. Create one self-signed cerificate with following command,

sudo openssl req -x509 -nodes -sha256 -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt

Answer the all questions shown below:

    Generating a 2048 bit RSA private key
    writing new private key to '/etc/nginx/ssl/nginx.key'
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    Country Name (2 letter code) [XX]:IN
    State or Province Name (full name) []:GUJARAT
    Locality Name (eg, city) [Default City]:AHMEDABAD
    Organization Name (eg, company) [Default Company Ltd]:Hostpresto
    Organizational Unit Name (eg, section) []:IT
    Common Name (eg, your name or your server's hostname) []:Hitesh
    Email Address []

After that it will create a 2048 bit RSA encrypted key in the file /etc/nginx/ssl/nginx.key and a SHA256 certificate in the file /etc/nginx/ssl/nginx.crt.

Now generate stronger, 4096 bit long DH parameters. It may take long time depending upon your system. Run following command to generate the DH parameters,

sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096

Once you get all the SSL related files ready, configure the default server block for SSL. Open its configuration file for editing,

sudo nano /etc/nginx/sites-enabled/default

Edit the server configuration part adding the SSL part after the server_name directive as shown below,

    server {
           server_name localhost;
            ### SSL Config
            listen 443 ssl;
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
            ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
            ssl_prefer_server_ciphers on;
            ssl_dhparam /etc/nginx/ssl/dhparam.pem;
            ssl_certificate /etc/nginx/ssl/nginx.crt;
            ssl_certificate_key /etc/nginx/ssl/nginx.key;


Let's quickly go through each of the configuration parameters configured above :-

Save and close the file, reload 'nginx' to bring above settings in effect.

sudo systemctl reload nginx

Restrict Access by IP

To avoid attackers exploiting weak passwords or software vulnerabilities in your website to gain unauthorised access, you can restrict the site by IP addresses.

For example, if you have an admin site and its admin area is at /site-admin/, you should limit the access to it only to your IP or to the IPs of all the administrators. To allow or deny access by IP open the corresponding server block — the default server block for Nginx is /etc/nginx/sites-enabled/default,

sudo nano /etc/nginx/sites-enabled/default

Add following in server configuration part in file,

    server {
        location /site-admin/ {
            deny  all;

In above example, make sure to replace and with your IPs & subnet mask.

Disable Unwanted HTTP Methods

Most of the time, you need just GET, HEAD & POST HTTP requests in your web application. Allowing TRACE or DELETE is risky as it can allow Cross-Site Tracking attack and potentially allows hackers to steal the cookie information.

You can do this by editing nginx.conf file:

sudo nano /etc/nginx/nginx.conf Add the following line inside server block:
    if ($request_method !~ ^(GET|HEAD|POST)$ )
           return 405;

Save the file and restart the nginx.

sudo systemctl restart nginx

Now, use telnet command to test Nginx server.

telnet localhost 80

You should now show 405 Not Allowed:

    Connected to
    Escape character is '^]'.
    TRACE / HTTP/1.1
    Host: testing

HTTP/1.1 405 Not Allowed Server: nginx/1.6.3 Date: Tue, 31 May 2016 02:59:08 GMT Content-Type: text/html Content-Length: 172 Connection: close

<title>405 Not Allowed</title>

<h1>405 Not Allowed</h1> <hr>nginx/1.6.3

Connection closed by foreign host.

Secure Nginx From A Clickjacking Attack

Clickjacking is a well known web application vulnerability. It is a malicious technique used by an attacker to collect an infected user's clicks.

The X-Frame-Options in an HTTP response header can be used to indicate whether or not a browser should be allowed to open a page in frame or iframe. This will prevent site content embedded into other sites.

There are three settings for X-Frame-Options:

You can do this by editing the nginx.conf file:

sudo nano /etc/nginx/nginx.conf

Add the following line inside server block:

    add_header X-Frame-Options "SAMEORIGIN";

Save and close the file and restart Nginx service.

sudo systemctl restart nginx


In this tutorial, you have learned how to install and secure the nginx HTTP server. Try to find a balance between functionality and security while working with web servers so that you can run your web sites securely on the network without compromising usability. Security is an ongoing task which requires regular updating, reconfiguration, scanning, etc.

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

Get a Cloud Server