If you need a free SSL certificate, there are plenty of places that will offer one. Except for very few places, they’re all trial certificates. After a short period, you’ll have to apply for another one somewhere else.
You have to go through the ordeal of setting things up again with another certificate vendor. Many of them will give out misleading or false information to sell you a costly SSL certificate, which you probably don’t even need.
I’ve only found two sources that offer a truly free SSL certificate. One of them is StartSSL, which I used until I found something better. The StartSSL certificate has to be renewed every year and they’re very good about letting you know well before your current certificate expires. I used one from them for more than a year on one site.
Before I continue, let me clarify something. I’m talking about the lowest level certificates. Regardless of what any certificate vendor calls them, they’re domain validation certificates. That means you only have to prove domain ownership. Other certificates need more information and use stricter validation methods. Unless you’re dealing with money or sensitive information on a website, you probably don’t need any kind of SSL certificate. It’s a good idea anyway because SSL combined with the new http/2 network protocol is going to be faster than running without SSL. I invite you to google it for more information.
The other source of truly free SSL certificates is the Let’s Encrypt service, which I’m now using. So far, I’ve found it to be more reliable than StartSSL.
You can find instructions in a few places for the Apache web server if you search for it. Far fewer places mention Nginx because things have to be set up manually with it. That’s okay because I’m going to show you how to automate it. Well, at least on Ubuntu. It will probably work on other distributions if you change “apt” to whatever they use.
You have to make sure you have “git” and “bc” installed so you can clone a git repository:
apt install git bc git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
You have to stop Nginx to do the next step or it will fail. Well, I assume it will because it failed for me twice.
service nginx stop kill all nginx
Here’s where the fun starts:
cd /opt/letsencrypt ./letsencrypt-auto certonly --standalone
If it craps out on you, hit control-c and run it again. It crapped out on me the first time. Enter your e-mail address and the domain name (both with and without the “www” prefix). You’ll only have to do it once. Now start Nginx back up again (no, you’re not done yet but you don’t want too much down time):
service nginx start
Let’s do the back-end work:
cp /opt/letsencrypt/examples/cli.ini /usr/local/etc/le-renew-webroot.ini nano /usr/local/etc/le-renew-webroot.ini
You’ll need to change three lines and verify another:
rsa-key-size = 4096 email = domains = webroot-path =
The email and the domains (separated by a comma) are going to be the same as you gave in the previous step. The webroot is the complete path to the document root of your website.
If you don’t have cURL installed, do it now:
apt install curl
Now we fetch the script we’ll need from another source:
curl -L -o /usr/local/sbin/le-renew-webroot https://gist.githubusercontent.com/thisismitch/e1b603165523df66d5cc/raw/fbffbf358e96110d5566f13677d9bd5f4f65794c/le-renew-webroot chmod +x /usr/local/sbin/le-renew-webroot
The next step is to set up two cron jobs to execute once a week. The first is to make sure your client is up-to-date. It should be set to run at least a few minutes before the one that follows (an hour is good):
cd /opt/letsencrypt && git pull
The next one updates the client certificate:
/usr/local/sbin/le-renew-webroot >> /var/log/le-renewal.log
A free SSL certificate doesn’t do you any good if you haven’t set up SSL on Nginx to begin with. The distribution default copy of the nginx.conf file only includes these lines:
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE ssl_prefer_server_ciphers on;
Make sure your nginx.conf file has those lines, as well as these:
ssl_ciphers [read below] ssl_session_cache shared:SSL:50m; ssl_session_timeout 1d; ssl_session_tickets off;
Use the Mozilla SSL Configuration Generator to get the ciphers you need in the [read below] area above.
You’ll need a dhparam.pem file. Generate it like this:
openssl dhparam -out /etc/ssl/private/dhparam.pem 2048
Check to make sure that “private” directory exists before you run it. Use whatever directory usually holds SSL certificates.
Now, your virtual host (“server”) configuration needs these lines:
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/domain.com/chain.pem; ssl_dhparam /etc/ssl/private/dhparam.pem; ssl_stapling on; ssl_stapling_verify on; resolver 126.96.36.199 188.8.131.52 valid=300s ipv6=off; resolver_timeout 10s;
The “domain.com” is your root domain, without any “www” prefix. The “ssl_dhparam” parameter must match what you used in the step to generate it.
You should know you also need this line at the beginning of your server code block:
listen 443 ssl http2;
The Let’s Encrypt service doesn’t offer wildcard certificates yet, but that’s okay. You can set up a free SSL certificate for each subdomain you want to secure (and you have to secure it if you’re using HSTS). The easiest way to do it is to start the first script all over again, this time using the full subdomain name. Then copy and edit some files:
cp /usr/local/etc/le-renew-webroot.ini /usr/local/etc/le-renew-XXX.ini cp /usr/local/sbin/le-renew-webroot /usr/local/sbin/le-renew-XXX chmod +x /usr/local/sbin/le-renew-XXX
Use the first part of your subdomain name for “XXX” above. It’ll make it easy to see which is which if you start building a bunch of websites under subdomains.
Edit the “.ini” file as you did before and then edit the other one on this line:
Make it match the file name above and then set up another cron job. Check the “/etc/letsencrypt/live/” directory to see what your full path is for your subdomain server configuration file. It should show your full subdomain name.
The cron jobs run every week, if you’ve set it up that way. When the certificate expires in under 30 days, a new one will be automatically generated and installed.
The only issue I’ve ever had is that I have to restart Webmin (my control panel) after a new certificate is installed. That’s a minor thing to do for a free SSL certificate.
Previous and Next Articles (if any):
Please read some of my more important pages if you have the time: