Skip to content
Sunday, April 11
  • About Me
  • Must Watch Videos
  • Proof of Concepts (POCs)

The Tech Check

Tech from one dev to another

The Tech Check

Tech from one dev to another

  • Data Science
  • Tech
  • General
  • Proof of Concepts (POCs)
  • About Me / Products
  • Must Watch Videos
  • Data Science
  • Tech
  • General
  • Proof of Concepts (POCs)
  • About Me / Products
  • Must Watch Videos
Trending Now
  • out() vs. outE() – JanusGraph and Gremlin
  • Getting Started With JanusGraph
  • I made a website which tells if you’re wearing a mask or not – without machine learning
  • Free apps vs. Paid apps
  • Binary Search Tree Implementation in Java
  • Different ways of iterating on a HashMap in Java
Home>>Tech>>Secure your web app with free and valid SSL (Nginx, Ubuntu, Let’s Encrypt)
Source: Digital Ocean
Tech

Secure your web app with free and valid SSL (Nginx, Ubuntu, Let’s Encrypt)

Sunny SrinidhiFebruary 13, 2017 523 Views0

HTTPS is now the standard. If you are an online service provider, getting an SSL certificate for your web app is a no-brainer. If you want your users to trust you, you need to get yourself one of those. Even otherwise, to secure the data you hold, it is important to provide the basic security that the HTTPS protocol provides. If you are not sure what it is, you can check out this Wikipedia page. This is a technical topic, and if you are coming here to learn how to secure your web app with an SSL certificate, it is better if you know your way around a computer and your cloud machine (you’ll be doing everything in a terminal window, so knowing how to use one is important as well).

Ideally, you need to buy an SSL certificate from the very many providers out there. You can actually create your own certificate as well, but it wouldn’t be trusted by everyone. But there’s an easy, legal, legitimate, and valid way to get a free SSL certificate which is as good as a certificate you’d buy. But anything free would have a catch, you’d think. The only big drawback I see here is that the certificate is valid only for 90 day, you’ll have to renew it after that. But you can automate that as well, as we’ll see later in this post.

I have tested this on Ubuntu 16.04 and Nginx on an AWS micro instance, with two different web apps. This blog is one of them. So you can see it’s working. The version of Nginx is not really very important, just make sure you are the latest version. Let’s get started then.

Let’s Encrypt

Remember I told you that you need to buy your certificate from a provider? Well, Let’s Encrypt is one of those, and it is relatively a new Certificate Authority (CA). These people give certificates for free so that you can secure your web servers for free. Good people Anyway, according to the research that I’ve done, they have automated the whole process of getting a certificate, downloading it, and configuring it to work on your server – only for Apache web servers. But I prefer Nginx. So it takes a bit more work to get this working than Apache would require.

Assumptions

  1. You have an Ubuntu (16.04) instance.
  2. A non-root user with sudo privileges is set up.
  3. You already have a registered domain (not necessary – you can use the public IP or the DNS provided by Amazon AWS).
  4. You can created an A Record pointing that domain to the public IP of you AWS instance.

Let’s get started

Step 1. Update apt indexes and install the letsencrypt client. To do this, execute the following commands in a terminal:

$ sudo apt update

$ sudo apt install letsencrypt

Step 2. Configure Nginx to serve the ./well-known location. Let’s Encrypt requires that you serve the ./well-known route, so that it can validate your domain. So you need to add this as a ‘location’ block in your Nginx configuration. For this, open your Nginx configuration file in a text editor of your choice. By default, the file is located at /etc/nginx/sites-available/default. Use the following command to open the file using vim:

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

Add the following inside the server block in the configuration file:

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

Save the file and exit. Now, restart the Nginx service with the following command:

$ sudo service nginx restart

Now, try if you are able to access the ./well-known route from your browser. If there’s any error, your browser will let you know. I found that in some cases, creating the ./well-known directory in your document root helps. So if you get a 404, try doing that.

Step 3. Now let’s get the certificate. For this you need to know the document root of your project. Let’s assume for now that it’s located at /var/www/html. With this information, you can get the certificate with the following command:

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

Replace example.com and www.example.com with your domain name. Once you run this command, you’ll ideally get two prompts. One to enter your domain name again, and the other to accept the terms and conditions. Complete these two; and if everything went well, you’ll get a success confirmation message on your terminal. In the confirmation message, you’ll also get the path to a fullchain.pem and privatekey.pem. Note the path to these two file, you’ll need them later.

Step 4. After this, it’s good to increase your security with a Diffie-Hellman group. Do generate a 2048 bit group, run the following command:

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

Step 5. Now let’s create a config file to tell Nginx where to look for the .pem files for the certificate. We’ll do this in a new file, where we will save only the snippet required for the SSL certificates. Create a file like below:

$ sudo vim /etc/nginx/snippets/ssl-example.com.conf

Add the following lines in the file:

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

Replace the paths to the .pem files with the paths you copied earlier. Save and exit.

Step 5. We’ll now have to create another similar configuration file to store the configuration for the DH group we created earlier. For this, create a file like this:

$ sudo vim /etc/nginx/snippets/ssl-params.conf

Add the following configuration to the file:

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;

Save and close the file.

Step 6. Now you’ll have to add some more configuration to your Nginx vhost file. Let’s open it up again:

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

You can remove the lines which tell Nginx to listen to port 80. Instead of that, we’ll now be listening to port 443, because that’s where we want our HTTPS to work. You’re new configuration inside the server{} block should look like this:

listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;

Now, we have make sure that people will still be able to use the web app without having to manually add “https://” in the URL. For this, we’ll listen to port 80 (or http://) and then redirect the request to https://. For this, you’ll have to add a second server{} block in the same configuration block. You can use the following snippet for that, just replace example.com with your domain name.

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

You’re all set. You just need to restart Nginx once and your new SSL certificate should now be working. Run the following command:

$ sudo service nginx restart

Step 7. Remember I told you this certificate is valid only for 90 days? Well, that means you’ll have to renew it every 90 days to make sure your server is secure. You can do this manually by running just one command, without any kind of extra configuration. But there’s a better and easy option, just setup a cron job and let the computer handle this for you. For this, open up your crontab with the following command:

$ sudo crontab -e

Now add the following at the end of the file:

30 2 * * 1 /usr/bin/letsencrypt renew >> /var/log/le-renew.log
35 2 * * 1 /bin/systemctl reload nginx

DONE! You now have a valid SSL certificate for your server and it’s set to auto-renew itself every 90 days, without you having to worry about anything else.

As a bonus, you can check the rating of your SSL certificate and how secure it is by using a free tool. Go to the following URL in your browser (and remember to replace example.com with your domain name):

https://www.ssllabs.com/ssltest/analyze.html?d=example.com

Below is a screenshot of what I got for this blog.

About the author

Sunny Srinidhi

Coding, reading, sleeping, listening, watching, potato. INDIAN.
“If you don’t have time to do it right, when will you have time to do it over?” – John Wooden

See author's posts

Share this:

  • Twitter
  • Facebook

Like this:

Like Loading...

Related

Share:

Previous Post

A few basic (but powerful) ImageMagick commands

ImagicMagik

Next Post

Use Config Caching to Speed Up Your Laravel App

laravel-logo-white

Related Articles

Bixby Routines SmartphonesTech

Bixby Routines, they actually work!

Google Allo & Duo Tech

Why I will stick to Hangouts for as long as I can before moving to Allo/Duo

apache_kafka_streams Tech

How you can improve your backend services’ performance using Apache Kafka

apache_kafka_streams Data ScienceTech

Getting started with Apache Kafka Streams

load balancer Tech

The art of load balancing – Part 2

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

O’Reilly Live Online Training

Getting Started with Amazon Athena

by Sunny Srinidhi
23rd April, 2021
Register now here
Sunny Srinidhi's DEV Community Profile
AWS_Community_Builder

Follow Us

  • Twitter
  • LinkedIn
  • Medium
  • GitHub

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 20 other subscribers

Recent Posts

  • out() vs. outE() – JanusGraph and Gremlin
  • Getting Started With JanusGraph
  • I made a website which tells if you’re wearing a mask or not – without machine learning
  • Free apps vs. Paid apps
  • Binary Search Tree Implementation in Java

Categories

  • Data Science (43)
  • General (4)
  • Rants (6)
  • Smartphones (1)
  • Tech (71)

Archives

  • March 2021
  • February 2021
  • January 2021
  • December 2020
  • October 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • September 2019
  • June 2019
  • May 2019
  • April 2019
  • November 2018
  • August 2018
  • July 2018
  • August 2017
  • July 2017
  • June 2017
  • April 2017
  • March 2017
  • February 2017
  • January 2017
  • September 2016
  • August 2016
  • March 2016

Tags

ai amazon apache apache kafka apache spark artificial intelligence aws best practices bigdata big data coding data science datascience data structure implementation in java data structures feature reduction feature selection java java data structures java data structures implementation java linked list example java linked list implementation javascript kafka linkedlist linked list in java linked lists machine learning machine learning models ml natural language processing nlp php programming python scikit python sklearn rants scikit scikit learn sklearn spring spring boot tech technology the fasttext series
Sunny Srinidhi | WordPress Theme Ultra Seven
%d bloggers like this: