Skip to content

Latest commit

 

History

History
377 lines (274 loc) · 11.6 KB

letsencrypt-wildcard-certificate.md

File metadata and controls

377 lines (274 loc) · 11.6 KB

letsencrypt-760x320

Why?

We want to deploy several App to our own Virtual Machine(s) and want all of them to be served over HTTPS (using SSL/TLS) without a much extra effort for each additional app.

What?

Setup a wildcard certificate to run any App(s) on a specific subdomain such as: api.example.com or auth.example.com

We previously covered how to setup LetsEncrypt for Heroku: https://github.com/dwyl/learn-heroku If you haven't used Heroku to deploy a "basic" App, we highly recommend doing that first as this is a more "advanced" level.

Who?

This tutorial is not "complicated" so anyone with basic development experience should be able to follow it. However it is not aimed at "beginners" who have never deployed any App(s) before. If you are new to web app development/deployment/"DevOps", we suggest you use Heroku: https://github.com/dwyl/learn-heroku (it's much easier and "free"!) once you are paying for Heroku, come back to this!

How?

0. Pre-requisites

This tutorial requires a "Cloud" Virtual Private Server (VPS) instance.
Any provider will work (AWS EC2, GCP, Azure, DigitalOcean, Linode, etc.)

If you do not yet have an instance go create one first.

1. Download & Install certbot

This approach to downloading certbot ensures we get the latest version and is OS/platform independent. (tested on CentOS and Ubuntu)

wget https://dl.eff.org/certbot-auto
chmod a+x ./certbot-auto
sudo ./certbot-auto

You should expect to see output similar to the following (depending on your OS and "cloud" provider):

Bootstrapping dependencies for RedHat-based OSes...
(you can skip this with --no-bootstrap)
yum is /bin/yum
yum is hashed (/bin/yum)
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
epel/x86_64/metalink                                          | 7.2 kB  00:00:00
 * base: mirror.netweaver.uk
 * epel: epel.mirror.constant.com
 * extras: mirror.mhd.uk.as44574.net
 * updates: mirror.netweaver.uk
base                                                          | 3.6 kB  00:00:00     
digitalocean-agent                                            | 3.3 kB  00:00:00     
docker-ce-edge                                                | 2.9 kB  00:00:00     
docker-ce-stable                                              | 2.9 kB  00:00:00     
dokku_dokku/x86_64/signature                                  |  836 B  00:00:00

Note: We are runnign the certbot-auto program as sudo ("root") because it certbot-auto needs root access to bootstrap OS dependencies the Bash code is very well commented and you can read it in about 20 mins. see: https://github.com/certbot/certbot

1.1. Install certbot Dependencies

Dependencies Resolved

===============================================================================
 Package                     Arch     Version            Repository    Size
===============================================================================
Installing:
 augeas-libs                x86_64    1.4.0-5.el7_5.1      updates     355 k
 libffi-devel               x86_64    3.0.13-18.el7        base        23 k
 openssl-devel              x86_64    1:1.0.2k-12.el7      base        1.5 M
 python-devel               x86_64    2.7.5-68.el7         base        397 k
 ...
Installing for dependencies:
 dwz                        x86_64    0.11-3.el7           base        99 k
 keyutils-libs-devel        x86_64    1.5.8-3.el7          base        37 k
 ...
 tcl                        x86_64    1:8.5.13-8.el7       base        1.9 M
 zlib-devel                 x86_64    1.2.7-17.el7         base        50 k

Transaction Summary
===============================================================================
Install  8 Packages (+18 Dependent packages)

Total download size: 12 M
Installed size: 31 M
Is this ok [y/d/N]:

Type "Y" followed by the [Enter] key.

Once the dependencies are installed, certbot will begin the certificate "wizard" ... but that will not setup a "wildcard" certificate so just cancel it.

2. Run the certbot-auto Command

Note: this is a multi-line command the only part you need to change is the last line (the domains):

sudo ./certbot-auto certonly \
--server https://acme-v02.api.letsencrypt.org/directory \
--manual --preferred-challenges dns \
-d *.ademo.app -d ademo.app

2.1 Input the Certificate Details

Enter email address

Use an email address you will have access to long term.

2.2 Create the DNS TXT Record

When you see the following output:

Please deploy a DNS TXT record under the name
_acme-challenge.ademo.app with the following value:

ZGoegXW6Xsp-kTGBCjvcghTANZDfgl8LRgcmspDGvK0

Before continuing, verify the record is deployed.

In your Domain Name (or DNS) provider, setup the TXT record.

on Digital Ocean, go to: https://cloud.digitalocean.com/networking/domains and select your domain.

e.g: https://cloud.digitalocean.com/networking/domains/ademo.app dokku-dns-txt-record

Check that TXT Record is Working

Run the following command:

dig -t txt _acme-challenge.ademo.app

Response:

; <<>> DiG 9.10.6 <<>> -t txt _acme-challenge.ademo.app
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54442
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
;; QUESTION SECTION:
;_acme-challenge.ademo.app.	IN	TXT

;; ANSWER SECTION:
_acme-challenge.ademo.app. 3599	IN	TXT	"ZGoegXW6Xsp-kTGBCjvcghTANZDfgl8LRgcmspDGvK0"

;; Query time: 144 msec

Confirm that the response value matches what LetsEncrypt expects!

Via: https://serverfault.com/questions/148721/linux-command-to-inspect-txt-records-of-a-domain

2.3 Successful Output

Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/ademo.app/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/ademo.app/privkey.pem
   Your cert will expire on 2018-08-21. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot-auto
   again. To non-interactively renew *all* of your certificates, run
   "certbot-auto renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

3. Add the Ceritifacte to your App

Since we are using Dokku to deploy our apps, and dokku automatically generates an nginx.conf file for each app, we can either update the file manually or using a the dokku certs:add command.

3.a Automatically Add the Cert to Dokku App

There is a command for adding the certificate to a dokku app:

dokku certs:add <app> CRT KEY   
cd /etc/letsencrypt/live/ademo.app/
dokku certs:add hello fullchain.pem privkey.pem

Annoyingly running that command returned the following error:

CRT file specified not found, please check file paths

So, after a bit of searching, I discovered a "workaround":

cat fullchain.pem > server.crt
cat privkey.pem > server.key
tar cvf certs.tar server.crt server.key
dokku certs:add hello < certs.tar

in my case:

cd /etc/letsencrypt/live/ademo.app/
cat fullchain.pem > server.crt
cat privkey.pem > server.key
tar cvf certs.tar server.crt server.key
dokku certs:add hello < certs.tar

This tar step only needs to be done once. then all subsequent apps which are a subdomain e.g: staging.ademo.app will just need:

dokku certs:add yourapp < /etc/letsencrypt/live/ademo.app/certs.tar

e.g:

dokku certs:add staging < /etc/letsencrypt/live/ademo.app/certs.tar

via: https://github.com/dokku/dokku/blob/master/docs/configuration/ssl.md
with: https://www.hakobaito.co.uk/b/setting-up-lets-encrypt-on-dokku

3.b Manually Update nginx.conf file

If you prefer to update your nginx.conf manually for any reason, you will need to locate, open and edit the nginx.conf file for your app.

In the case of our hello app, the file is: /home/dokku/hello/nginx.conf

Note this will still work if you are not using Dokku/Docker, you simply need to find and update the right nginx.conf file.

The only lines we changed were the two that related to the SSL cert: From:

ssl_certificate     /home/dokku/hello/tls/server.crt;
ssl_certificate_key /home/dokku/hello/tls/server.key;

To:

ssl_certificate /etc/letsencrypt/live/ademo.app/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/ademo.app/privkey.pem; # managed by Certbot

This is where certbot stores the certificates, don't move them (or the certificate renewal will fail)

4. Reload Nginx

Run the following command to both test the nginx config is valid and to reload the server:

nginx -t && nginx -s reload

You should see:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok

Test The SSL!

To test that the SSL/TLS certificate is setup correctly, test it! e.g: https://www.ssllabs.com/ssltest/analyze.html?d=ademo.app

ssl-report

Automating it!

Once you have got your Wildcard Certificate setup, it's a single command to add it to any new apps you deploy using Dokku.

For an example of how this can be done see: https://github.com/nelsonic/hello-world-node-http-server/blob/5b6f2a29d8d4568cf7337a84ceecf666e50d353e/bin/deploy.sh#L47-L49

Background Reading

My starting point was:

Neither of these two were for CentOS, Digital Ocean or Dokku so I had to "assemble" this guide from a few other sources ...

Additional Resources: