Fusehunt

Fusehunt

Tech, web, programming, home automation, networking, and geeky blog.

31 Oct 2020

SSL Cert from Let's Encrypt for Synology via Acme.sh and Docker

In this day and age there is no excuse not to have an SSL certificate setup. Let’s Encrypt makes it so easy and as a bonus, it’s free. Acme.sh then makes it even easier.

Acme.sh can be setup with Docker. To make it readily available it can be run as a deamon with docker-compose:

  acme:
    container_name: acme
    image: neilpang/acme.sh
    volumes:
      - "./acme:/acme.sh"
    environment:
      - CF_Key="#########"
      - CF_Email="#########"
    network_mode: host
    command: daemon
    restart: always

Here we provide the ./acme directory, which is where the certificates will end up, and also two environment variables for Cloudflare key and email address. This allows Acme.sh to simply validate the domain using DNS in Cloudflare. Once the container is up and running with docker-compose up -d you’ll be able to simply run the following command to create the cert:

 docker-compose exec acme --issue --dns dns_cf -d synology.example.com

In the output you’ll see it adding a record to Cloudflare, generating the certificate, then removing the record from Cloudflare. At the end it will output that it’s created the certificate in the ./acme/synology.example.com directory.

Now comes the annoying part, adding it to Synology:

  1. Download the cert, cert key, and intermediate CA cert to your local machine.
  2. Open your Synology in your web browser.
  3. Open Main menu -> Control panel -> Security -> Certificate.
  4. Click Add.
  5. Follow the wizard to import a new certificate.

Annoyingly you will need to manually do this every 3 months.

Edit: 1st November 2020

After posting this on Reddit there were a number of comments. One from tater39 mentioned using a deploy-hook, which removes all of the “annoying” parts mentioned above. They were not using Docker, but the same idea applied. They shared their code and pointed to an article by Markus Lippert from earlier this year.

Based on these new details the docker-compose can be updated to add Synology details:

  acme:
    container_name: acme
    image: neilpang/acme.sh
    environment:
      - CF_TOKEN="#########"
      - SYNO_Scheme="http"
      - SYNO_Hostname="192.168.10.10"
      - SYNO_Port="5000"
      - SYNO_Username="#########"
      - SYNO_Password="#########"
      - SYNO_Certificate="synology.example.com"
      - SYNO_Create=1
    volumes:
      - "./acme:/acme.sh"
    network_mode: host
    command: daemon
    restart: always

Here we’re providing environment variables for Synology as described in the Acme.sh documentation. From there, once the docker containers is up and running with docker-compose up -d, we can run the commands to issue the SSL cert, then deploy the SSL cert.

 docker-compose exec acme --issue --dns dns_cf -d synology.example.com
 docker-compose exec acme --deploy -d synology.example.com --deploy-hook synology_dsm

You’ll see the command to issue the certificate is the same, the second command then deploys the certificate to Synology using the details provided in the environment variables.

Then, in the Synology UI, you can set this to renew every month.

  1. Go to Main menu -> Control panel -> Task Scheduler.
  2. Create a new scheduled task, as “User-defined script”.
  3. Give it a sensible name, set it to run as root, and set it to run monthly.
  4. In task settings add the following command:
cd /path/to/your/docker-compose/directory
docker-compose exec -T acme --cron --force

This will force all certificates your Acme.sh instance knows about to renew and deploy.

comments powered by Disqus