nginx-ssl

SETUP SSL with NGINX

sudo apt-get install -y letsencrypt

sudo apt-get install -y nginx

OBTAIN SSL CERTIFICATE USING WEBROOT

The Webroot plugin works by placing a special file in the /.well-known directory within your document root, which can be opened (through your web server) by the Let's Encrypt service for validation. Depending on your configuration, you may need to explicitly allow access to the /.well-knowndirectory

$ sudo vi /etc/nginx/sites-available/default

Inside the server block add the location block

location ~ /.well-known { allow all; }

Default web root path for nginx is /var/www/html

We can use the Webroot plugin to request an SSL certificate with these commands. If you want a single cert to work with multiple domain names use multiple -d option

Example

sudo letsencrypt certonly -a webroot --webroot-path=/var/www/html -d mysslnginx.com -d www.mysslnginx.com

Above command will create the certs.

If you are installing Lets encrypt for first time, it will prompt for email id and licence agreement. If everything was successful, the output will be shown with license expiry date

Your cert will expire on 2017-02-16

If you receive an error like Failed to connect to host for DVSNI challenge, your server's firewall may need to be configured to allow TCP traffic on port 80 and 443

CERTIFICATE FILES

After obtaining the cert, you will have the following PEM-encoded files:

    • cert.pem: Your domain's certificate

    • chain.pem: The Let's Encrypt chain certificate

    • fullchain.pem: cert.pem and chain.pem combined

    • privkey.pem: Your certificate's private key

It's important that you are aware of the location of the certificate files that were just created, so you can use them in your web server configuration. The files themselves are placed in a subdirectory in /etc/letsencrypt/archive. However, Let's Encrypt creates symbolic links to the most recent certificate files in the /etc/letsencrypt/live/<domain_name> directory. Because the links will always point to the most recent certificate files, this is the path that you should use to refer to your certificate files.

You can check that the files exist by running this command

sudo ls -l /etc/letsencrypt/live/<domain_name>

Generate Strong Diffie-Hellman Group

To generate a strong Diffie-Hellman group with 2048-bit, use this command.

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Once the DH group is created you can find it in /etc/ssl/certs/dhparam.pem

Configure SSL/TLS on NGINX

It is a 3 step process

1. Create a configuration snippet containing our SSL key and certificate file locations

2. Create a configuration snippet containing strong SSL settings

3. Modify Nginx server blocks to handle SSL requests and use the snippets

1. Create Configuration Snippet

Create a new Nginx configuration snippet in the /etc/nginx/snippets directory. Within this file, we just need to set the ssl_certificate directive to our certificate file and the ssl_certificate_key to the associated key

Create file /etc/nginx/snippets/ssl-mysslnginx.conf and add the below lines

ssl_certificate /etc/letsencrypt/live/mysslnginx.com/fullchain.pem;

ssl_certificate_key /etc/letsencrypt/live/mysslnginx.com/privkey.pem;

2. Create Configuration for Strong Encryption

Create file /etc/nginx/snippets/ssl-params.conf and add below contents.

Note: To set up Nginx SSL securely, we will be using the recommendations by Remy van Elst on the Cipherli.stsite. This site is designed to provide easy-to-consume encryption settings for popular software. You can read more about his decisions regarding the Nginx choices here.

# from https://cipherli.st/ # and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; ssl_ecdh_curve secp384r1; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; # Disable preloading HSTS for now. You can use the commented out header line that includes# the "preload" directive if you understand the implications.#add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"; add_header Strict-Transport-Security "max-age=63072000; includeSubdomains"; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; ssl_dhparam /etc/ssl/certs/dhparam.pem;

3. Configure NGINX to use SSL

Edit /etc/nginx/sites-available/default and modify the parameters highlighted in red.

Note that, new server snippet has to be created for SSL

Alternatively if you want to allow both http and https requests you the below snippet

server { listen 80 default_server; listen [::]:80 default_server; server_name mysslnginx.com www.mysslnginx.com; return 301 https://$server_name$request_uri; } server { # SSL configuration listen 443 ssl http2 default_server; listen [::]:443 ssl http2 default_server; include snippets/ssl-mysslnginx.com.conf; include snippets/ssl-params.conf;

server { listen 80 default_server; listen [::]:80 default_server; listen 443 ssl http2 default_server; listen [::]:443 ssl http2 default_server; server_name example.com www.example.com; include snippets/ssl-example.com.conf; include snippets/ssl-params.conf;

ADJUST FIREWALL

If ufs firewall is enabled, adjust the firewall to allow https

Enable - sudo ufw allow 'Nginx Full' which will allow both http and https requests

Disable http only rule - sudo ufw delete allow 'Nginx HTTP'

After restarting NGINX, it should be available through https.

AUTO RENEW CERTIFICATE

As the certificate expires after 3 months, it need to be renewed periodically. Cron can be setup to renew certificate automatically.

To renew certificate manually use lets encrypt renew

Edit cron crontab -e and add below 2 lines, which will renew certs, modify the date and time as required

30 2 * * 1 /usr/bin/letsencrypt renew >> /var/log/le-renew.log

35 2 * * 1 /bin/systemctl reload nginx

Links:

Lets encrypt using docker https://getcarina.com/docs/tutorials/nginx-with-lets-encrypt/#create-a-data-volume-container