Normally we don’t have to use SSL when we connect to the services via Tailscale as all connections are end-to-end encrypted and only allowed users could access your network. But there are always exceptions like you want put your tailscale domain behind a public domain or you have to use SSL for internal connections. For example, horader on ios requires the SSL and it won’t work when we host hoarder using docker even we enable HTTPS on tailscale DNS and add cert to the NAS. When I access hoarder via the tailscale of the NAS, it always returns insecure connection. I tried created the SSL cert using tailscale cert
and make it the default cert of my Synology, it still fails as tailscale cert only cover the port 443 so the services running at other ports are not covered.
Use Tailscale as Sidecar
In Remote Accessing NAS Using Tailscale, I introduced three methods to access the services hosted on the NAS. One of them is to run a sidecar of tailscale with the containerized service to expose it to the tailnet. Here we can run it with an reverse proxy and put the containerized service behind the reverse proxy. Moreover, we could use a public domain to access our containerized service.
The below is my docker-compose.yaml
which runs tailscale container as a sidecar with NPM (Nginx Proxy Manager)
.
version: "3.9"
services:
tailscale:
image: tailscale/tailscale:latest
container_name: tailscale
hostname: tailscale-router
restart: unless-stopped
networks:
- tailnet
environment:
- TS_AUTHKEY=tskey-auth-your-key
- TS_EXTRA_ARGS=--accept-routes
- TS_AUTH_ONCE=false
- TS_STATE_DIR=/var/lib/tailscale
- TS_DEBUG_FIREWALL_MODE=auto
- TS_USERSPACE=false
cap_add:
- NET_RAW
- NET_ADMIN
privileged: true
volumes:
- "/dev/net/tun:/dev/net/tun"
- "/your/tailscale/config:/var/lib/tailscale"
- "/your/tailscale/state:/var/run/tailscale"
npm:
container_name: npm
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
network_mode: "service:tailscale"
volumes:
- "/your/nginx_proxy_manager/data:/data"
- "/your/nginx_proxy_manager/letsencrypt:/etc/letsencrypt"
networks:
tailnet:
driver: bridge
Proxying
Once we have both containers up and running, we can use your.ts.net:81
to access the NPM
since they share the same network. And we can create SSL cert for our public domain like hoarder.your.domain
and it only works with DNS challenge for me. To use DNS challenge, we need to get the API key from the DNS provider to get the edit permission on our DNS records shown below (I’m using Cloudflare).
Then we can create proxy host for hoarder.your.domain
and use the SSL cert created above. The destination should be your-nas-local-ip:port
.
Setup Public Domain
The next step is to set up the public domain on the DNS resolver and I’m using Cloudflare which is highly recommended. We can create a CNAME
record for hoarder.your.domain
or use a wildcard like *.your.domain
, and the value will be the domain of the tailscale container (it can be found on the admin console of tailscale). In this way, we don’t need to add any new record to Cloudflare even we want to add more services later. All we need is to add a proxy host in NPM since the wildcard will resolve any subdomains to the domain of our tailscale container. Then NPM will pick it up and do the heavy-lifting work for us.
Final thoughts
This will do the job and allow us to access these containerized services using SSL and the public domain but it still requires the device in the tailnet (aka. the device must install the tailscale client or use subnet router) to actually access the service as we just resolve the public domain to the tailnet domain. Now I have two tailscale clients on my Synology, one is installed via package center and another one is hosted by docker, But I’m thinking of removing the one I installed via package center to reduce the redundancy.