Secure Your Homelab with Tailscale & Cloudflare

There are instances when you want to ensure that only you have remote access to specific areas of your homelab. In this post, we’ll explore how to leverage Tailscale, Traefik, and Cloudflare to establish a private and secure connection to your homelab services.

Cloudflare

Cloudflare API

To begin, we need to generate the necessary API keys with Cloudflare.

Go the API page and login with your Cloudflare Account.

Create a API Key on the link above.

  1. Select Create Token
  2. Select a template Edit zone DNS
  3. Make sure that the Permissions is set to Zone / DNS / Edit
  4. By Zone Resources you can select for which domain the API key will be used
  5. Select Continue to summary.
  6. Review the token summary. Select Edit token to make adjustments. You can also edit a token after creation.
  7. Select Create Token to generate the token’s secret.

Make sure to save this API Key, as it will be needed later in the setup process.

Cloudflare DNS Record

To differentiate between regular public domain names and those intended for use exclusively on Tailscale, we will create a wildcard DNS record in Cloudflare. This record will point to the Tailscale Traefik container, using a CNAME configuration.

Here’s how to set it up:

  1. In Cloudflare, navigate to your DNS settings for the domain you want to configure.
  2. Create a new CNAME record:

By setting up this wildcard record, any domain that ends with .ts.example.com will be routed to the Traefik container. This ensures that these domains are accessible only when connected to your Tailnet, eliminating the need to create individual DNS records for each specific domain name.

Tailscale Auth key

To generate an auth key for Tailscale, which will allow your Docker container to access your Tailnet, follow these steps:

  1. Open the Keys page in the Tailscale admin console.
  2. Click on Generate auth key.
  3. Fill out the form with the necessary details:
  1. Click Generate key.

Make sure to save this Auth Key, as you will need it later for your Docker container setup.

Docker

To set up Tailscale and Traefik using Docker, you’ll create a docker-compose.yml` file that defines both services. Here’s a basic example of how to structure this file:

docker-compose.yml
 1services:
 2  tailscale-traefik:
 3    image: tailscale/tailscale
 4    container_name: tailscale
 5    hostname: traefik
 6    environment:
 7      - TS_AUTHKEY=${TS_AUTHKEY}
 8      - TS_STATE_DIR=/var/lib/tailscale
 9      - TS_USERSPACE=false
10    volumes:
11      - ./tailscale-traefik/state:/var/lib/tailscale
12      - /dev/net/tun:/dev/net/tun
13    cap_add:
14      - net_admin
15      - sys_module
16    restart: unless-stopped
17  traefik:
18    image: traefik
19    container_name: traefik
20    restart: unless-stopped
21    security_opt:
22      - no-new-privileges:true
23    environment:
24      - TZ=Europe/Amsterdam # Change this to your timezone
25      - CF_API_EMAIL=${CF_API_EMAIL}
26      - CF_DNS_API_TOKEN=${CF_DNS_API_TOKEN}
27    depends_on:
28      - tailscale-traefik
29    network_mode: service:tailscale-traefik
30    volumes:
31      - /var/run/docker.sock:/var/run/docker.sock:ro # Docker socket to watch for Traefik
32      - traefik-certs:/certs # Docker volume to store the acme file for the Certifactes
33    command:
34      # Tell Traefik to discover containers using the Docker API
35      - --providers.docker=true
36      - --providers.docker.exposedByDefault=false
37      # Enable the Trafik dashboard
38      - --api.dashboard=true
39      # Set up LetsEncrypt
40      - --certificatesresolvers.letsencrypt.acme.dnschallenge=true
41      - --certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare
42      - --certificatesresolvers.letsencrypt.acme.email=${LE_EMAIL}
43      - --certificatesresolvers.letsencrypt.acme.storage=/certs/acme.json
44      # Set up an insecure listener that redirects all traffic to TLS
45      - --entrypoints.web.address=:80
46      - --entrypoints.web.http.redirections.entrypoint.to=websecure
47      - --entrypoints.web.http.redirections.entrypoint.scheme=https
48      - --entrypoints.websecure.address=:443
49      # Set up the TLS configuration for our websecure listener
50      - --entrypoints.websecure.http.tls=true
51      - --entrypoints.websecure.http.tls.certResolver=letsencrypt
52      - --entrypoints.websecure.http.tls.domains[0].main=${DOMAIN}
53      - --entrypoints.websecure.http.tls.domains[0].sans=${SANS_DOMAIN}
54    labels:
55      - "traefik.enable=true"
56      - 'traefik.http.routers.traefik.rule=Host(`traefik.ts.example.com`)'
57      - "traefik.http.routers.traefik.entrypoints=websecure"
58      - "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
59      - "traefik.http.routers.traefik.service=api@internal"
60      - "traefik.http.services.traefik.loadbalancer.server.port=8080"
61volumes:
62  traefik-certs:
63    name: traefik-certs
Click to expand and view more

Don’t forget to change traefik.ts.example.com to your domain name.

To store sensitive information and configuration values, create a .env file in the same directory as your docker-compose.yml`.

BASH
1nano .env
Click to expand and view more

In this .env file place the following content.

.env
1CF_API_EMAIL=<Cloudflare email>
2CF_DNS_API_TOKEN=<Cloudflare API Token>
3TS_AUTHKEY=<Tailscale Auth Key>
4LE_EMAIL=<Your email for LetsEncrypt>
5DOMAIN=ts.example.com       # Your main domain
6SANS_DOMAIN=*.ts.example.com # Your wildcard domain
Click to expand and view more

This setup will allow you to securely access your applications hosted on your homelab through Tailscale, while Traefik handles routing and SSL termination.

Start Traefik and Tailscale

To launch your containers for Traefik and Tailscale, use the following command in your terminal:

BASH
1docker compose up -d
Click to expand and view more

Depending on your Tailscale configuration, you may need to approve the tailscale-traefik device in the Tailscale Admin Console. Log in to the Tailscale Admin Console to manage devices.

Once your Tailscale connection is established, you can access the Traefik dashboard at:

https://traefik.ts.example.com

Now that your setup is complete, any services you add to Traefik with a domain ending in *.ts.example.com will be accessible exclusively through your Tailnet. This adds a layer of security, ensuring that only authenticated users connected to your Tailnet can access your services.

Summary

By integrating Tailscale with Traefik, you’ve created a secure and streamlined way to manage access to your homelab services, while leveraging Docker for container management. Enjoy exploring and expanding your self-hosted environment!

Copyright Notice

Author: Sven van Ginkel

Link: https://svenvg.com/posts/secure-your-homelab-with-tailscale-cloudflare/

License: CC BY-NC-SA 4.0

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Please attribute the source, use non-commercially, and maintain the same license.

Start searching

Enter keywords to search articles

↑↓
ESC
⌘K Shortcut