Normally, there's an ad running in this spot, but you're using an ad blocker. To help support our blog, which provides free tutorials for everybody, we just ask that you whitelist or follow us on facebook, twitter, or subscribe using the form to the leftabove. Thank you!

    Configuring an SSL Server Block for NGiNX

    Until you're configured your web server to transmit and receive data over an encrypted protocol like TLS (Transport Layer Security) or SSL (Secure Socket Layer), your traffic is exposed to anyone and everyone, putting your visitors at risk.

    Encryption is somewhat necessary to improve your website's search engine rankings, but absolutely necessary if you're prompting your visitors for any form data like passwords or credit card information.

    The type of security we're implementing involves a two part process. You'll need to first generate a self-signed SSL certificate, and then you'll need to create an ssl server block in your nginx configuration.

    The self-signed certificate is suitable for local development, but when deploying to production, we'll want to purchase an SSL certificate from a certificate authority like DigiCert or RapidSSL.

    Prerequisites

    1. Installing NGiNX

    Alright, now that we have our server and NGiNX set up, we can move onto to encrypting our traffic.

    Generating the Certificate

        
        # create a directory to store the SSL certificate
        sudo mkdir /etc/nginx/ssl
        # generate the certificate (one line)
        sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
        
      
        
        # create a directory to store the SSL certificate
        sudo mkdir /usr/local/etc/nginx/ssl
        # generate the certificate (one line)
        sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /usr/local/etc/nginx/ssl/nginx.key -out /usr/local/etc/nginx/ssl/nginx.crt
        
      

    As you can see from the last command, we're running the openssl utility as root, and passing in a number of flags. We've indicated that we want to use an X.509 certificate signing request with req -x509. We've skipped the need to enter a passphrase on server startup with -nodes. We've also set an expiration date on the certificate to one year with -days 365. Finally, we've created in rsa key that's 2048 bits long with -newkey rsa:2048, and given openssl directories to store the key and certificate with -keyout and -out paths.

    Now, the utility is going to provide you with a series of prompts wherein you'll have to add your information.

    Adding Your Information to the Certificate

    Country Name (2 letter code) [AU]:US
    State or Province Name (full name) [Some-State]:New York
    Locality Name (eg, city) []:New York City
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:Company Name LLC
    Organizational Unit Name (eg, section) []:Engineering
    Common Name (e.g. server FQDN or YOUR name) []:http://domain.com # or ip
    Email Address []:admin@your_domain.com
    

    We're finally ready to create our server block.

    Creating the NGiNX SSL Server Block

    Now, you're going to want to update your server block to include the lines indicated below:

    server {
        listen 80 default_server;
        listen [::]:80 default_server ipv6only=on;
    
        listen 443 ssl;
    
        root /var/www/domain.com;
        index index.html index.htm;
    
        server_name domain.com;
        access_log /var/log/nginx/domain.com.access.log;
        error_log /var/log/nginx/domain.com.error.log;
    
        location / {
            # First attempt to serve request as file, then
            # as directory, then fall back to displaying a 404.
            try_files $uri $uri/ =404;
            # Uncomment to enable naxsi on this location
            # include /etc/nginx/naxsi.rules
        }
    
        ssl on;
        ssl_certificate /etc/nginx/ssl/nginx.crt;
        ssl_certificate_key /etc/nginx/ssl/nginx.key;
    
        ssl_session_timeout 5m;
    
        ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
        ssl_prefer_server_ciphers on;
    }
    
    server {
        listen 80 default_server;
        listen [::]:80 default_server ipv6only=on;
    
        listen 443 ssl;
    
        root /var/www/domain.com;
        index index.html index.htm;
    
        server_name domain.com;
        access_log /var/log/nginx/domain.com.access.log;
        error_log /var/log/nginx/domain.com.error.log;
    
        location / {
            # First attempt to serve request as file, then
            # as directory, then fall back to displaying a 404.
            try_files $uri $uri/ =404;
            # Uncomment to enable naxsi on this location
            # include /usr/local/etc/nginx/naxsi.rules
        }
    
        ssl on;
        ssl_certificate /usr/local/etc/nginx/ssl/nginx.crt;
        ssl_certificate_key /usr/local/etc/nginx/ssl/nginx.key;
    
        ssl_session_timeout 5m;
    
        ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
        ssl_prefer_server_ciphers on;
    }
    

    Testing Your Web Server

    # restart nginx
    sudo service nginx restart
    
    # verify that http still works
    curl -iv http://domain.com # or ip
    
    # verify that https is serving 
    curl -ivk https://domain.com # or ip
    

    The output of the above commands should be a 200 OK response and the body of the website. We're passing in the -k flag to instruct curl to skip verifying the certificate. You should also navigate to the domain in your browser use both http and the https protocols. If everything is working properly you'll get a warning that the site's security certificate is not trusted, but that's nothing to be concerned about. You're certificate is self-signed. Click on "proceed anyway" or "continue" and if you're redirected to your site, then it's working. You can now transmit encrypted traffic over SSL.

    Did you like this tutorial? Help us pay for server costs by following us on Facebook, Twitter, and subscribing below, where you'll get post notifications, training webinar invites, and free bundles.