Sunday, November 30, 2014

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. For some types of traffic, like page content that would normally be displayed to all end users, encryption isn't necessary. But when you're dealing with user authentication where a password needs to be transmitted, or a shopping service that needs to send out the user's credit card information, encryption is absolutely necessary.

The type of security we're implementing is 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.

Prerequisites: If you haven't set yourself up with a server yet, make sure to check out this article, first. That article will also link to this guide about a basic Nginx setup.

Alright, now that you have your server and Nginx set up, we can move onto to encrypting your channels.

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

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 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;
}

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.

No comments:

Post a Comment