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:
- Download the cert, cert key, and intermediate CA cert to your local machine.
- Open your Synology in your web browser.
- Open Main menu -> Control panel -> Security -> Certificate.
- Click Add.
- 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.
- Go to Main menu -> Control panel -> Task Scheduler.
- Create a new scheduled task, as “User-defined script”.
- Give it a sensible name, set it to run as root, and set it to run monthly.
- 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.