Technologie im Fokus

Serve a website with SSL encryption

S

Serving a website with SSL encryption makes sure that the connection between your web server and your user’s browsers remain private and integral. Any information that’s transmitted is encrypted and unreadable to everyone except the user and the intended server.

display of it.artindustrial.com SSL certification information on chrome
How an SSL certified website looks in Chrome: Secure and green

This guide will help you to create a certificate for your domain and establish an SSL encryption for your website via https. This guide will also explain how you can have your certificate automatically renewed once a month.

How to set up an SSL encryption

Setting up a website with SSL encryption is easy and can be done for free with Let’s Encrypt, a service that provides free, automated and open SSL certificates.

The validation process works like this:

  1. The website of Let’s Encrypt is called with a certificate request for your website.
  2. Let’s Encrypt will respond to this request with a challenge, that’s a small file you’ll have to put on your website with a specific path. Let’s Encrypt will then try to download the file from your website. When this process is completed successfully, you’ll have proven that you’re in control of your website.
  3. The certificate is then added to the configuration of your webserver and SSL is activated

Most of those steps can be automated by Certbot, a service that automates certificate issuance and installation. Nonetheless, some things you’ll have to do manually. In this article I will explain the manual steps we have to do in detail:

In this article, I will explain all necessary manual steps in detail.

The site used in this article will run the domain cms.example.com and will have Debian Jessie OS and Nginx as webserver.

  1. Create a path for the challenges of Certbot
  2. Configure Nginx (SSL config of your website, redirect all requests to SSL, make an exception for the Certbot challenges)
  3. Installation of Let’s Encrypt, Certbot & creating the certificate
  4. Renewal of certificates
  5. Conclusion
  6. Sources

Create a path for the challenges of certbot

First, we need a path, where Certbot can create the challenges and our Nginx will serve them at the URL Let’s Encrypt expects them.

The pros of this approach are that the certificate creation/renewal process is independent of the real website configuration (eg proxy forward to tomcat) or the state of the certificate (eg not yet created) and we can always request a certificate or a renewal of it.

To do this, we create a new directory in our nginx docroot (in my case that’s /usr/share/nginx/www )

sudo mkdir -p /usr/share/nginx/www/letsencrypt/cms.example.com/.well-known

and change the owner to the nginx User (eg. www-data)

sudo chown www-data:www-data -R /usr/share/nginx/www/letsencrypt/cms.example.com

Tip: It proved to be quite useful creating an index.html file to check if the configuration is working as expected:

sudo
 echo "<html><body>letsencrypt Challenge Testpage for 
cms.example.com</body></html>" 
>/usr/share/nginx/www/letsencrypt/cms.example.com/.well-known/index.html

Now Let’s Encrypt can put its challenges in that path.

Next, we’ll have to configure Nginx and then we can check with our index.html if it’s working correctly.

Configure Nginx

Let’s create a simple nginx config for cms.example.com via

sudo vim /etc/nginx/sites-available/cms.example.com

with this content:

# this is our website config (for your example cms)
server {
	listen 443 ssl;
	ssl_certificate    /etc/letsencrypt/live/cms.example.com/fullchain.pem;
	ssl_certificate_key    /etc/letsencrypt/live/cms.example.com/privkey.pem;

	root /usr/share/nginx/www/cms;
	index index.html index.htm index.php;
	server_name cms.example.com;

	location / {
		# First attempt to serve request as file, then
		# as directory, then fall back to displaying a 404.
		try_files $uri $uri/ /index.php?q=$request_uri;
		if ($request_uri ~* ".(jpg|jpeg|gif|gz|zip|flv|rar|wmv|avi|css|swf|png|htc|ico|mpeg|mpg|txt|mp3|mov|js)(\?v=[0-9.]+)?$") {
			expires 30d;
			access_log off;
			break;
		}
	}
}

# This is for redirection to https and the letsencrypt config
server {
	listen 80;
	# the root is the parent directory of our previously created .well-known directory
	root /usr/share/nginx/www/letsencrypt/cms.example.com;
	server_name cms.example.com;
	# this is the important exclusion of .well-known, all other requests are redirected to https
	location /.well-known/ {
	}
	# redirect all http requests to https
	location / {
		return 301 https://$host$request_uri;
	}
}

The content of the first server {} block is the configuration of the website you want to serve via https (in our case some CMS).

The content of the second server {} block is the redirection of all http requests to https except the requests to http://cms.example.com/.well-known/. We also configured in this block our previously created directory as root.

Tip: Make sure to use the parent directory of the .well-known as root since the location /.well-known will automatically add this to the path.

We now test the config with this input:

sudo nginx -t

If the test was successful, we can now restart nginx via

sudo service nginx restart

Next, we try accessing our Test index.html via the URL http://cms.example.com, which should redirect us to https – where we will see an error page from our browser.

Installation of Let’s Encrypt, Certbot & creating the certificate

Now we install Certbot with

sudo apt-get install certbot

Tip: You can get installation guides for many OS on the Certbot website.

After it is installed, we are able to create a certificate by calling

sudo certbot-auto certonly --webroot -w /usr/share/nginx/www/letsencrypt/cms.example.com -d cms.example.com

This creates the challenge in the path given after the -w parameter (/usr/share/nginx/www/letsencrypt/cms.example.com). Now the letsencrypt server tries to download it from the domain given after the -d parameter (cms.example.com). If everything worked, a new certificate will be stored in

If everything worked out and the file was downloaded successfully, your new certificate will be stored in

/etc/letsencrypt/live/

Certbot can startup its own webserver but using your existing webserver has the advantage of not needing to stop the webserver for renewing the certificate.

Since we added the certificate previously in our Nginx config we should now be able to access the website via https.

Renewal of certificates

A certificate is only as good as long as it’s valid. To make sure that your certificates are valid you have to renew them periodically.

To renew all due certificates just call

sudo certbot-auto renew

Since Certbot saves the configuration, it can simply rerun the process it did for creating the first certificate.

If you create a cronjob with

sudo crontab -e

and add the line

0 23 1 * * certbot-auto renew

you will not have to worry about renewing the certificates again because our cron job invokes the Certbot every month. Certbot will then renew all due certificates it finds on that server.

Conclusion

In this article, we made sure that our example website will always be served via https and the SSL certificates will be automatically renewed right before they are due.

Sources

Let’s Encrypt: https://letsencrypt.org/getting-started/

Certbot: https://certbot.eff.org/

Über den Autor

Manuel Manhart
Manuel Manhart

Manuel Manhart ist seit 2012 Projektleiter und Senior Softwareentwickler bei artindustrial it. Seine Schwerpunkte sind Software Architektur und die agile Softwareentwicklung mit Scrum.

Manuel Manhart Von Manuel Manhart
Technologie im Fokus

Hier finden Sie uns

Adresse
Mariahilferstrasse 111/6-7
1060 Wien
Kartenansicht

Öffnungszeiten
Montag – Freitag: 9–17 Uhr

Kontakt
Mail: it@artindustrial.com
Tel.: +43 1 5954023

Folgen Sie uns