└── README.md
/README.md:
--------------------------------------------------------------------------------
1 | # How to use Tailscale with a custom domain via Cloudflare and reverse proxy on a Synology NAS
2 |
3 | ## Introduction
4 | 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.
5 |
6 | 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:
7 | - Not having to remember which port is which since it'll all be handled via reverse proxy
8 | - Not having to remember (frankly ugly) domain names
9 |
10 | ## Prerequisites
11 | - A Synology NAS
12 | - Docker installed on your NAS
13 | - A domain managed via Cloudflare
14 | - The ability to SSH into your NAS
15 |
16 | ## Initial setup
17 | 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
18 |
19 | 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`.
20 | 
21 | And, we have a successful connection to our machine over HTTPS.
22 |
23 |
24 | ## Custom domain with wildcard
25 | 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.
26 |
27 | ### Generating a Cloudflare API token
28 |
29 | 1. Create a User API token.
30 |
31 | Go to My Profile > API Tokens > Create Token. Give it whatever name you desire, and set parameters like so:
32 | - Permissions:
33 | - Zone: Zone: Read
34 | - Zone: DNS: Edit
35 | - Zone Resources:
36 | - Include: Specific zone: `domain.com` (where `domain.com` is your domain)
37 |
38 | Your summary should look like this:
39 |
40 |
41 | 2. Save the API key somewhere, because you won't be able to see it again.
42 |
43 | ### Running Certbot
44 |
45 | 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.
46 |
47 | 1. SSH into your NAS (if you don't know how to do this on your platform, there are a lot of guides out there)
48 | 2. Create the necessary directories for Certbot: `sudo mkdir -p /volume1/docker/certbot/{logs,lib_letsencrypt,etc_letsencrypt}`
49 | 3. Create the Certbot configuration file: `sudo touch /volume1/docker/certbot/lib_letsencrypt/cloudflare.ini`
50 | 4. Add your Cloudflare API token:
51 | ```
52 | echo "dns_cloudflare_api_token = your-cloudflare-api-token" | \
53 | sudo tee /volume1/docker/certbot/lib_letsencrypt/cloudflare.ini > /dev/null
54 | ```
55 | 5. 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.
56 | ```
57 | sudo docker run --rm \
58 | -v /volume1/docker/certbot/etc_letsencrypt:/etc/letsencrypt \
59 | -v /volume1/docker/certbot/lib_letsencrypt:/var/lib/letsencrypt \
60 | -v /volume1/docker/certbot/logs:/var/log/letsencrypt \
61 | certbot/dns-cloudflare:latest certonly \
62 | --dns-cloudflare \
63 | --dns-cloudflare-credentials /var/lib/letsencrypt/cloudflare.ini \
64 | --dns-cloudflare-propagation-seconds 30 \
65 | -d "*.subdomain.domain.com" -d "subdomain.domain.com" \
66 | --non-interactive --agree-tos --email your-email@example.com
67 | ```
68 |
69 | 6. If successful, you'll find your new certificates at `.../docker/certbot/etc_letsencrypt/live`. You'll need to download the following files:
70 | - Private Key - `privkey.pem`
71 | - Certificate - `cert.pem`
72 | >A couple of people have reported that their certificates were generated in `.../docker/certbot/etc_letsencrypt/archive` instead of `/live`.
73 |
74 | 7. 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` and `Certificate`. Don't worry about the Intermediate certificate.
75 |
76 | 8. Your certificates page should now look something like this:
77 | 
78 |
79 | ## Configure the certificate check script
80 |
81 | Download the certificate check script and run it once to create a configuration file. Then, add your certificate details to the file.
82 |
83 | 1. Download the script and make it executable:
84 |
85 | ```bash
86 | sudo wget -O check_certs.sh https://raw.githubusercontent.com/telnetdoogie/synology-scripts/main/check_certs.sh && \
87 | sudo chmod +x check_certs.sh
88 | ```
89 | 2. Run the script to create the configuration file:
90 |
91 | ```bash
92 | sudo ./check_certs.sh
93 | ```
94 |
95 | 3. Open the configuration file in a text editor and add your certificate's Common Name (CN) and file path:
96 |
97 | ```json
98 | {
99 | "config": [
100 | {
101 | "cn": "*.subdomain.domain.com",
102 | "cert_path": "/volume1/docker/certbot/etc_letsencrypt/live/domain.com"
103 | }
104 | ]
105 | }
106 | ```
107 |
108 | ## Schedule certificate renewals
109 |
110 | 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`.
111 |
112 | 1. In Synology DiskStation Manager, go to **Control Panel** > **Task Scheduler**.
113 |
114 | 1. Using **Create** > **Scheduled Task** > **User Defined Script**, add two repeating tasks which run as `root` one hour apart.
115 |
116 | For each task, in the **Task Settings** tab under **Run Command**, enter the following.
117 |
118 | a. For the script to **renew certificates** in the Certbot folder:
119 |
120 | ```bash
121 | /bin/bash
122 | sudo docker run -v /volume1/docker/certbot/etc_letsencrypt:/etc/letsencrypt \
123 | -v /volume1/docker/certbot/lib_letsencrypt:/var/lib/letsencrypt \
124 | -v /volume1/docker/certbot/logs:/var/log/letsencrypt \
125 | --rm \
126 | --cap-drop=all \
127 | certbot/dns-cloudflare:latest \
128 | renew
129 | ```
130 | b. For the script to **install certificates** on your NAS:
131 |
132 | ```bash
133 | /bin/bash
134 | cd /path/to/script # Change into the script directory
135 | bash /path/to/script/check_certs.sh --update
136 | ```
137 |
138 | ## Adding Cloudflare CNAME wildcard
139 | 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.
140 | 1. The first record we'll add will have the following attributes:
141 | - Type: `CNAME`
142 | - Name: `*.subdomain` (a subdomain of your choosing)
143 | - Target: `ds920.tailb12345.ts.net` (where `tailb12345` is your tailnet name and `ds920` is the name of your NAS)
144 | - Proxy status: `DNS Only`
145 | - TTL: `Auto`
146 | 2. 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.
147 | - Type: `CNAME`
148 | - Name: `subdomain`
149 | - Target: `ds920.tailb12345.ts.net`
150 | - Proxy status: `DNS Only`
151 | - TTL: `Auto`
152 |
153 | And that's Cloudflare setup complete! Your DNS records page should look something like this:
154 | 
155 |
156 | ## Synology NAS reverse proxy
157 | 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.
158 | 1. Open Control Panel > Login Portal > Advanced > Reverse Proxy
159 | 2. Hit Create
160 | 3. Under General:
161 | - **Source**:
162 | - Name: `dsm`
163 | - Protocol: `HTTPS`
164 | - Hostname: `dsm.subdomain.domain.com`
165 | - Port: `443`
166 | - HSTS: Unchecked
167 | - **Destination**:
168 | - Protocol: `HTTPS` (because we'll be connecting to the secure port 5001)
169 | - Hostname: `localhost`
170 | - Port: `5001`
171 | 4. Hit Save
172 | 5. 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.**
173 | Once configured, your reverse proxy list should look something like this:
174 | 
175 | 6. Now, open back up your certificate settings and set your reverse proxies to use your wildcard SSL certificate:
176 | 
177 |
178 | ## Testing
179 | 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:
180 |
181 | Success!
182 |
183 | > Disclaimer: Some of this guide was copied verbatim from https://github.com/btbristow/tutorials/blob/main/certbot-with-cloudflare.md
184 |
--------------------------------------------------------------------------------