I recently decided enough is enough, I want to access my self-hosted services while I'm on the go. A lot of people's first thought to accomplish this is Tailscale, a service where you can create a private network "bubble" of your chosen devices (called a Tailnet), which can be accessed via an oauth of your choosing. Upon signing up, you're given a unique subdomain, such as tailb12345.ts.net
, which is used for DNS. As such, you can access your devices using this name instead of an IP address.
That's great and all, but I had wondered if I could take this a step further and use my own domain to access my devices. So, here we are. "But Jack" I hear you say, "Won't it be secure anyway if we're connecting through Tailscale?". And to that I say, well yes! But this method does come with a couple of benefits:
- Not having to remember which port is which since it'll all be handled via reverse proxy
- Not having to remember (frankly ugly) domain names
- A Synology NAS
- Docker installed on your NAS
- A domain managed via Cloudflare
- The ability to SSH into your NAS
First off, you'll need to install Tailscale on your Synology NAS. There's a great video by Tailscale's YouTube channel that explains step-by-step how to install Tailscale, configure auto-update, and enable HTTPS: https://www.youtube.com/watch?v=0o2EhK-QvmY
Once you think you've got it set up, give it a test by going to https://[nas name].[tailnet name].ts.net
. In my case, my nas is called ds920
, and my tailnet name is tailb12345
.
And, we have a successful connection to our machine over HTTPS.
Now comes the fun part! We're going to use Certbot to get us a wildcard certificate by using the Cloudflare API to complete the DNS-01 challenge.
- Create a User API token.
Go to My Profile > API Tokens > Create Token. Give it whatever name you desire, and set parameters like so:
- Permissions:
- Zone: Zone: Read
- Zone: DNS: Edit
- Zone Resources:
- Include: Specific zone:
domain.com
(wheredomain.com
is your domain)
- Include: Specific zone:
Your summary should look like this:
- Save the API key somewhere, because you won't be able to see it again.
This section will assume your volume is called volume1
and that you have a folder called docker
inside. Please make necessary adjustments if this doesn't align with your setup.
- SSH into your NAS (if you don't know how to do this on your platform, there are a lot of guides out there)
- Create the necessary directories for Certbot:
sudo mkdir -p /volume1/docker/certbot/{logs,lib_letsencrypt,etc_letsencrypt}
- Create the Certbot configuration file:
sudo touch /volume1/docker/certbot/lib_letsencrypt/cloudflare.ini
- Add your Cloudflare API token:
echo "dns_cloudflare_api_token = your-cloudflare-api-token" | \
sudo tee /volume1/docker/certbot/lib_letsencrypt/cloudflare.ini > /dev/null
- Use the folling command to launch a temporary Docker container which runs Certbot and adds the necessary DNS records to your domain. Make sure you replace the domains and email with your own.
sudo docker run --rm \
-v /volume1/docker/certbot/etc_letsencrypt:/etc/letsencrypt \
-v /volume1/docker/certbot/lib_letsencrypt:/var/lib/letsencrypt \
-v /volume1/docker/certbot/logs:/var/log/letsencrypt \
certbot/dns-cloudflare:latest certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /var/lib/letsencrypt/cloudflare.ini \
--dns-cloudflare-propagation-seconds 30 \
-d "*.subdomain.domain.com" -d "subdomain.domain.com" \
--non-interactive --agree-tos --email your-email@example.com
- If successful, you'll find your new certificates at
.../docker/certbot/etc_letsencrypt/live
. You'll need to download the following files:
- Private Key -
privkey.pem
- Certificate -
cert.pem
-
Import the certificate to your NAS. It'll be in Control Panel > Security > Certificate. Select Add > Add a new certificate > Import certificate > Upload the
Private Key
andCertificate
. Don't worry about the Intermediate certificate.
Download the certificate check script and run it once to create a configuration file. Then, add your certificate details to the file.
-
Download the script and make it executable:
sudo wget -O check_certs.sh https://raw.githubusercontent.com/telnetdoogie/synology-scripts/main/check_certs.sh && \ sudo chmod +x check_certs.sh
-
Run the script to create the configuration file:
sudo ./check_certs.sh
-
Open the configuration file in a text editor and add your certificate's Common Name (CN) and file path:
{ "config": [ { "cn": "*.subdomain.domain.com", "cert_path": "/volume1/docker/certbot/etc_letsencrypt/live/domain.com" } ] }
Let's Encrypt certificates expire every 90 days, but you can automate renewals with the Synology Task Scheduler. To do this, schedule two tasks: one to renew your certificates and another to install them using check_certs.sh
.
-
In Synology DiskStation Manager, go to Control Panel > Task Scheduler.
-
Using Create > Scheduled Task > User Defined Script, add two repeating tasks which run as
root
one hour apart.For each task, in the Task Settings tab under Run Command, enter the following.
a. For the script to renew certificates in the Certbot folder:
/bin/bash sudo docker run -v /volume1/docker/certbot/etc_letsencrypt:/etc/letsencrypt \ -v /volume1/docker/certbot/lib_letsencrypt:/var/lib/letsencrypt \ -v /volume1/docker/certbot/logs:/var/log/letsencrypt \ --rm \ --cap-drop=all \ certbot/dns-cloudflare:latest \ renew
b. For the script to install certificates on your NAS:
/bin/bash cd /path/to/script # Change into the script directory bash /path/to/script/check_certs.sh --update
Now that we've got a wildcard SSL certificate for our subdomain, we'll need to add a couple of CNAME records which will point our domain towards our Tailnet name.
- The first record we'll add will have the following attributes:
- Type:
CNAME
- Name:
*.subdomain
(a subdomain of your choosing) - Target:
ds920.tailb12345.ts.net
(wheretailb12345
is your tailnet name andds920
is the name of your NAS) - Proxy status:
DNS Only
- TTL:
Auto
- Type:
- The second is optional, but I like to have this as a kind of "home page" where I can link all of my services in one place.
- Type:
CNAME
- Name:
subdomain
- Target:
ds920.tailb12345.ts.net
- Proxy status:
DNS Only
- TTL:
Auto
- Type:
And that's Cloudflare setup complete! Your DNS records page should look something like this:
Since we've only set up a wildcard CNAME record, we still need to tell the NAS where to route a request. One of the amazing showstopping spectacular features of Synology DSM is a built-in reverse proxy manager that's ready to go. We'll be using this to point various sub-subdomains of our choosing to the correct service. In this example, we'll add a reverse proxy to connect to DSM.
- Open Control Panel > Login Portal > Advanced > Reverse Proxy
- Hit Create
- Under General:
- Source:
- Name:
dsm
- Protocol:
HTTPS
- Hostname:
dsm.subdomain.domain.com
- Port:
443
- HSTS: Unchecked
- Destination:
- Protocol:
HTTPS
(because we'll be connecting to the secure port 5001) - Hostname:
localhost
- Port:
5001
- Hit Save
- Add as many services as you desire. Important: you should only use HTTPS in the destination if you are positive that it's a secure port. If you aren't sure, use HTTP. In most cases, you will be using HTTP.
Once configured, your reverse proxy list should look something like this:
- Now, open back up your certificate settings and set your reverse proxies to use your wildcard SSL certificate:
If we've done everything correctly, we should be able to get to each of our services securely (without having to worry about ports!) Let's give it a go with Portainer:
Success!
Disclaimer: Some of this guide was copied verbatim from https://github.com/btbristow/tutorials/blob/main/certbot-with-cloudflare.md