Updating LAN SSL certificates

Renewing LAN based SSL certificates and installing them to a Synology NAS and RouterOS device was a bit of a hullabaloo, so want it documented for when it breaks in three years, by which time I will have forgotten how it was configured.

This approach was inspired by Renew Let’s Encrypt certificates on Synology using acme.sh – Christos Georgiadis.

The updating is via a monthly CRON script which runs on my Synology NAS device (SINO).

acme.sh is used to do the updating, but rather than install it directly on SINO, it will be run from within the neilpang/acme.sh docker image. For context, I used to have it installed directly on SINO, but with a host of permission issues, it needed to run as root, and was never entirely stable. Using Docker will allow me to keep things simple, with the least setup should it need to be moved to a different host. the image is based on Alpine Linux, so only about 5MB.

SINO Setup

  1. Install the Docker app onto Synology.
  2. From Docker, download the neilpang/acme.sh docker image.
  3. SSH into SINO and create the following folder: /volume1/docker/acme
  4. From the Synology control panel, create a user with the following permissions:
    • Disallow user to change password
    • Groups: Administrators, Users
    • Share Permissions: docker
    • Applications: DSM

Mikrotik Setup

  1. Create a new user group with the following permissions:
    • ssh, ftp, read, write, password, sensitive
  2. Create a new user, and assign to the newly created group

SSH Configuration

In order to update the Mikrotik RouterOS, we will need to be able to connect via SSH. For this to work, we need to setup several things.

  1. Create a pair of SSH keys with ssh-keygen.
  2. Copy the keys to /volume1/docker/acme on Redbeard.
  3. Copy the public key (probably id_rsa.pub) to the Mikrotik router, and assign it to the user we created under System -> Users -> SSH Keys

Renewal Script

Create a bash script to run the renewal steps and save it to /volume1/docker/acme

<code class="language-bash"># DNS verification variables
export DH_API_KEY='ZZZ-ZZZ'
# Synology deployment variables
export SYNO_Server='192.16.1.1'
export SYNO_Username='sinoUser'
export SYNO_Password='xxxx-xxxx'
# RouterOS deployment variables
export ROUTER_OS_USERNAME=mikUser
export ROUTER_OS_PASSWORD='yyyy-yyyy'
export ROUTER_OS_HOST=192.168.2.2
export ROUTER_OS_PORT=22
# setup acme
acme.sh --upgrade
acme.sh --set-default-ca  --server  letsencrypt
# get certificates
acme.sh --issue --dns dns_dreamhost -d &lt;gaul's domain name> --dnssleep 300
acme.sh --issue --dns dns_dreamhost -d &lt;sino's domain name> --dnssleep 300
#deploy to Synology NAS
acme.sh --deploy -d &lt;sino's domain name> --deploy-hook synology_dsm
# deploy to RouterOS
# Setup SSH before we can deploy to RouterOS.
mkdir /root/.ssh
cp /acmeConf/id_rsa /root/.ssh/
chmod 600 /root/.ssh/id_rsa
ssh-keyscan -H $SOUTER_OS_HOST >> /root/.ssh/known_hosts
echo "Host *
HostKeyAlgorithms +ssh-rsa
PubkeyAcceptedKeyTypes +ssh-rsa" >> /root/.ssh/config
acme.sh --deploy -d &lt;gaul's domain name> --deploy-hook routeros</code>

Wiring it all up

The final step is to create a cron job on SINO to renew the certs every two months.

  1. SSH into SINO, and elivate the terminal with sudo -i.
  2. Add the following line to the crontab file (note, tabs, not spaces):
<code class="language-bash">0	0	1	*/2	*	root	bin/su -c 'docker run --rm --mount type=bind,source=/volume1/docker/acme,target=/acmeConf neilpang/acme.sh ./acmeConf/dockerRenew.sh >> /volume1/docker/acme/certInstall.log' sslUpdator </code>

Some blurb to remind me of what’s going on.

  • The docker image is raw; no changes are made to it, so we can grab a new image with a new version of acme.sh, and no additional changes will be required to the image.
  • All config is found on SINO at /volume1/docker/acme.
  • When docker starts the container, it binds the config folder to the container, making it available within the running docker container.
  • The docker container is not long running. The bash script starts the container up, causes it to execute our script, then shuts down the container. The log file is saved to the config folder.
  • Oh, and Lance, remember that the scripts are in your GitHub repository.

Leave a Reply

Your email address will not be published. Required fields are marked *