After reading that Roli is considering https for juce.com (http://www.juce.com/forum/topic/you-are-collecting-credit-card-numbers-non-secure-site) I decided to publish my to date private guide here. Bear in mind that I'm not an expert on this, I'm a sole audio software developer.
Two month ago I switched from a regular certificate to one from letsencrypt.org. Such a certificate is free and you can renew it AUTOMATICALLY. That's the awesome part! You don't have to spend hours each year to renew your certificate.
They have their own huge scripts for your sever, you need to give those quite some rights and they will modify your server. That's not cool at all. Luckily there are alternatives, small scripts you can easily verify yourself and that don't need any modifications of your server. In particular acme-tiny.
***********************************
How to set up the let's encrypt SSL
***********************************
Sources:
https://www.metachris.com/2015/12/comparison-of-10-acme-lets-encrypt-clients/
https://github.com/diafygi/acme-tiny
Background
==========
ACME
----
The Automated Certificate Management Environment (ACME) protocol defines a way of automatically obtaining trusted certificates without human intervention. First, the control of a domain has to be proven, then the agent can request, renew and revoke certificates.
Certificates issued by Let's Encrypt are valid for 90 days, and are expected to be renewed automatically. More background information can be found on https://letsencrypt.org/howitworks/technology/
At the time of writing, these rate limits has been in place:
- 10 Registrations per IP per 3 hours
- 5 Certificates per Domain per 7 days (incl. subdomains)
Once the agent has an authorized key pair, requesting, renewing, and revoking certificates is simple - just send certificate management messages and sign them with the authorized key pair.
SSL Certs & Signing
-------------------
Obtaining a valid SSL certificate generally includes the following steps:
1. You create a private and public key pair on the server.
2. You create a Certificate Signing Request (CSR) which includes the domain name, organization name, the public key, and other information. The CSR is signed with your private key.
3. You send the CSR to the certificate authority.
4. The certificate authority signs the request, thus producing a public certificate.
5. You use the public certificate in your webserver.
Step 0: Get ACME tiny
=====================
mkdir ~/ssl_acme_tiny
cd ~/ssl_acme_tiny
git clone https://github.com/diafygi/acme-tiny.git .
Step 1: Create a private key
==================================================
cd ~/ssl_acme_tiny
openssl genrsa 4096 > acme-tiny/account.key
chmod 660 acme-tiny/account.key
Step 2: Create a certificate signing request (CSR) for your domains
===================================================================
The ACME protocol (what Let's Encrypt uses) requires a CSR file to be submitted to it, even for renewals. You can use the same CSR for multiple renewals. NOTE: You can't use your account private key as your domain private key!
#generate a domain private key
openssl genrsa 4096 > domain.key
chmod 660 domain.key
#for multiple domains (use this one if you want both www.yoursite.com and yoursite.com)
openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:<yourAwesomeCompany>.com,DNS:www.<yourAwesomeCompany>.com,DNS:mail.<yourAwesomeCompany>.com")) > acme-tiny/domain.csr
Step 3: Make your website host challenge files
==============================================
You must prove you own the domains you want a certificate for, so Let's Encrypt requires you to host some files for them. This script will generate and write those files in the folder you specify, so all you need to do is make sure that this folder is served under the ".well-known/acme-challenge/" url path.
mkdir ~/ssl_acme_challenge
Example for nginx
server {
listen 80;
server_name <yourAwesomeCompany>.com www.<yourAwesomeCompany>.com;
location /.well-known/acme-challenge/ {
alias /home/<yourUserName>/ssl_acme_challenge/;
try_files $uri =404;
}
...the rest of your config
}
Step 4: Get a signed certificate
================================
cd ~/ssl_acme_tiny/acme-tiny
python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /home/<yourUserName>/ssl_acme_challenge/ > ./signed.crt
Step 5: Install the certificate
===============================
For nginx, you need to append the Let's Encrypt intermediate cert to your cert
wget -O - https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem > intermediate.pem
cat signed.crt intermediate.pem > chained.pem
Step 6: Setup an auto-renew cronjob
===================================
Congrats! Your website is now using https! Unfortunately, Let's Encrypt
certificates only last for 90 days, so you need to renew them often. No
worries! It's automated! Just make a bash script called e.g. renew_cert.sh
and add it to your crontab. The content of that file:
#!/bin/bash
acmeTinyDirectory=/home/<yourUserName>/ssl_acme_tiny/acme-tiny/
acmeChallengeDirectory=/home/<yourUserName>/ssl_acme_challenge/
python $acmeTinyDirectory/acme_tiny.py --account-key $acmeTinyDirectory/account.key --csr $acmeTinyDirectory/domain.csr --acme-dir $acmeChallengeDirectory > $acmeTinyDirectory/signed.crt || exit
wget -O - https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem > $acmeTinyDirectory/intermediate.pem
cat $acmeTinyDirectory/signed.crt $acmeTinyDirectory/intermediate.pem > $acmeTinyDirectory/chained.pem
chmod 775 renew_cert.sh
Add it to the crontab of <yourUserName>:
# ------------------ SSL cert refresh -------------------------
# runs at 4 o clock on the 5th of each month
#min hour mday month wday command
0 4 5 * * /home/<yourUserName>/ssl_acme_tiny/acme-tiny/renew_cert.sh 2>> /home/<yourUserName>/ssl_acme_tiny/acme-tiny/acme_tiny.log
Add to the crontab of root:
# ------------------ SSL cert refresh -------------------------
# runs at 4:05 on the 5th of each month
#min hour mday month wday command
5 4 5 * * service nginx reload > /dev/null
Cheers,
Samuel
