Guide: Using Let's Encrypt SSL Certificates for a local or network server
A few people have emailed asking how I got HTTPS with a valid certificate working on my minimal virtual machine. It's useful to be able to work locally with a valid HTTPS certificate, it allows you to determine whether there are any HTTPS related issues when moving from development to production and test your site using HTTP 2.0.
Prerequisites
It's surprisingly easy, but you will need three things:
- A linux machine, linux virtual machine or web server to run
certbot
. Note: You will need to renew the certificates every 3 months so will need consistent access to this machine. It may also be possible to run Certbot from Windows. - A domain name or subdomain which you'll use for development.
- Access to the domain name's DNS configuration and ability to create a TXT record
v.je
and any subdomain.v.je
belowSetting up your domain
The first thing you need to do is set up your DNS to point to your local server. Edit the DNS for your domain or subdomain e.g. example.org
so that it points to 127.0.0.1
or whichever local/network IP you are using.
Getting your certificates
Secondly, you will need to use certbot
from a linux computer to generate your certificates using the dns-01
acme challenge:
sudo certbot -d example.org --server https://acme-v02.api.letsencrypt.org/directory --manual --preferred-challenges dns certonly
Where example.org
is your domain name. Give it the information it requires. Then, during the process you will need to amend the DNS for the domain and create a TXT record _acme-challenge
with the code it generates.
Depending on your DNS provider, you may be able to use a plugin to avoid having to manually configure the TXT record
After creating (or modifying if you are renewing) the TXT record I recommend waiting for at least 60 seconds before pressing continue in certbot to ensure the DNS change has propagated.
This will generate your certificates in /etc/letsencrypt/live/example.org
Moving your certificates to the development machine
If you're using the same machine for your development, you can use the certificates from here. Otherwise, you'll need to copy them to your development machine. To do that you can use the following commands:
mkdir ./certs
sudo cp -Lr /etc/letsencrypt/live/example.org ./certs/example.org
sudo chmod -R 644 ./certs
zip -r certs.zip ./certs
This will create a zip file of your certificates. Transfer this to your development machine and configure your web server to use them.
Configuring your web server
Configure your local/network web server to use the certificates as you normally would. Here's some sample configuration for NGINX:
# Redirect http requests to https
server {
listen 80;
server_name example.org;
return 301 https://example.org$request_uri;
}
server {
# Listen on port 443 for SSL and enable HTTP2 if you wish
listen 443 ssl http2;
server_name example.org;
# path to fullchain.pem on local machine, default letsencrypt location or location you extracted the zip file to
ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem;
# path to privkey.pem
ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem;
# NGINX configuration continues e.g. configuring root and php
# ....
For Apache, take a look at the Apache Documentation. You'll need to provide paths to the fullchain.pem and privkey.pem files.
Restart your web server and you'll be able to access your domain on HTTPS e.g. https://example.org/
Renewal
You will need to renew the certificates every three months. To do so, run the certbot command again to renew the certificates, then copy them back to your development machine.
Using v.je instead of your own domain
If you're using the certificats for a local machine (127.0.0.1) and you don't want the hassle of creating and renewing certificates yourself, you can use v.je as I have made the certificates publicly available to download here.
- Configure your server name (nginx: server_name, apache: ServerName) on your web server to listen on v.je
- Point your webserver to the certificates in the
v.je
subdirectory
As the certificates have already been generated and are publicly available, you can use them without requiring a linux machine or certbot.
This is insecure the green padlock in your address bar does not mean you are connecting to the correct site, you are susceptible to man-in-the-middle attacks because anyone can use my certificates!
In reality, if it's a development website running on 127.0.0.1 this is a non-issue. The advantage is that you can avoid issues that arise from developing on HTTP and deploying on HTTPS. It also lets you develop using HTTP 2.0
If you want to use v.je for an IP other than 127.0.0.1 you can edit your HOSTS file and override the DNS by pointing v.je to your network IP.
Quickly renewing v.je certificates
If you want to use the v.je certificates and quickly renew them, the following PHP script can be used to check and renew the certificates. Place this script in the directory that stores your SSL certificates and run it periodically (e.g. in a systemd timer/cron/scheduled task)
<?php
$dir = '/path/to/certificate/location';
$update = false;
chdir($dir);
if (!file_exists('./certs/expiry.txt')) {
$update = true;
}
else {
$date = new DateTime(file_get_contents('./certs/expiry.txt'));
$diff = $date->diff(new DateTime());
$dayDiff = $diff->format('%R%a');
if ($dayDiff >= -7) $update = true;
}
if (!$update) die;
echo 'updating certificates....';
exec('curl -o ./certs.zip https://r.je/tmp/vjecert.zip 2>&1', $output);
$zip = new ZipArchive();
$zip->open('./certs.zip');
$zip->extractTo($dir);
unlink('./certs.zip');
v.je wildcard certificates
The v.je certificates are wilcards which means you can use any subdomain. Add example.v.je
to your hosts file, set your server name to example.v.je
(or set up a wildcard subdomian) and use the certificates in the v.je-0001
subdirectory.