Custom SSL/TLS certs

Hi all

Firstly I just want to clarify that this method was discovered myself after being unable to successfully use letsencrypt via the built-in DNS verification in Tutors default configuration (not due to fault in Tutor side, but because of infrastructure/firewall limitations)

To work around the limitation I used Certbot on my local server (not inside docker/containers) to verify using the CloudFlare API (if you are not using CloudFlare as your DNS nameservers, or you want to use a 3rd party certificate from another provider, eg GoDaddy, you can skip this initial steps and follow the instructions specific to your SSL provider to generate your public/private certs and then continue with the Caddy config)

CloudFlare:

  1. install the certbot app and cloudflare plugin
apt-get install certbot python3-certbot-dns-cloudflare
  1. create your API credentials file and secure it
    nano /etc/letsencrypt/cloudflare.passwd
    Add following lines and save:

dns_cloudflare_email = YourEmailAddressForCloudflare@domain.tld
dns_cloudflare_api_key = YourUniqueAPIKey

chmod 600 /etc/letsencrypt/cloudflare.passwd

  1. Generate your certs

certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.passwd -d *.domain.tld

The certs typically should be in /etc/letsencrypt/live/domain.tld/certs.pem
HOWEVER, this is a LINK to the original files so you should instead use the full path of /etc/letsencrypt/archive/domain.tld/certs.pem

Now, onto the Caddy configs…
Everything following this point assumes that you have already stored your private and public keys on your main server. We will be creating a mount in docker that will allow the contents of our certs folder to be accessible via Caddy

Files to edit:
.local/share/tutor/env/local/docker-compose.prod.yml

Add the path to your certificates stored on the local machine and mount to location of choice in container volumes
- /etc/letsencrypt/archive/:/tmp/
NB: the /tmp part is INSIDE the Caddy container’s file system, you can change this to a preferred location of your choice, /tmp is NOT an absolute requirement, so just change it according to YOUR configuration choice if you want, but I have tested it to work in /tmp

 volumes:
      - ../apps/caddy/Caddyfile:/etc/caddy/Caddyfile:ro
      - ../../data/caddy:/data
      - /etc/letsencrypt/archive/:/tmp/

Next file
.local/share/tutor/env/apps/caddy/Caddyfile

For each site (cms/lms/apps/etc) add the path to your certs as they appear in container
tls /tmp/domain.tld/fullchain1.pem /tmp/domain.tld/privkey1.pem

lms.domain.tld ...
...
...
...
    import proxy "lms:8000"
    tls /tmp/domain.tld/fullchain1.pem /tmp/domain.tld/privkey1.pem
...

cms.domain.tld ...
...
...
...
    import proxy "cms:8000"
    tls /tmp/domain.tld/fullchain1.pem /tmp/domain.tld/privkey1.pem

Restart and you should then be getting full SSL.

Comments and suggestions to improve this are always welcome :slight_smile:

Quick update regarding wildcard certs, I had a brain-fart and didn’t realise that wildcards don’t work for extra subdomains so it’s better to specify the domains exactly for your config.
Eg: (add on more domain names as needed with the -d switch followed by the FQDN

certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.passwd -d lms.domain.tld -d cms.domain.tld -d apps.lms.domain.tld -d preview.lms.domain.tld

@Joel I don’t know if you have seen this but it looks like Caddy supports DNS through their modules

It does look like you would have to build your own Caddy image. There is additional information here Docker Hub under the heading “Building your own Caddy-based image”

Thank you @misilot
I’ll have a poke around with this :slight_smile:

I remember I shared this method before on the Open edX Discussion forum.

I will share a link to the post: Tutor SSL config - #3 by uetuluk - DevOps - Open edX discussions