9.9 KiB
navigation, title, main
navigation | title | main | ||
---|---|---|---|---|
true | Cloudflare Zero Trust |
|
:ellipsis{left=0px width=40rem top=10rem blur=140px}
Cloudflare Zero Trust
::alert{type="info"} 🎯 Goals:
- Understand the concept of Cloudflare Tunnels
- Configure your Cloudflare account
- Configure SWAG
- Manage multiple tunnels ::
Introduction
The Zero Trust architecture is the practice of designing systems based on the principle of "never trust, always verify", as opposed to the traditional principle of "trust, but verify". This concept has become increasingly popular recently due to the growing number of attacks targeting user data. It’s a broad concept, but we’ll focus on how to apply Zero Trust to the web services we host.
Cloudflare tunnels offer a simple way to implement Zero Trust, using SWAG and Authentik.
Simply put, Cloudflare Tunnels allow you to:
- Hide your server’s IP (and your home IP if it's self-hosted)
- Authenticate traffic
- Benefit from Cloudflare protections (DDoS attacks, blacklists, malicious requests, etc.)
- Use Cloudflare's CDN to cache and speed up your websites
- Avoid opening router ports for services exposed by SWAG
Here we’ll explain how to integrate SWAG with Cloudflare tunnels.
::alert{type="warning"} :::list{type="warning"}
- Warning: :::
- Do not use Cloudflare tunnels to expose a mail server
- Do not use Cloudflare tunnels to expose a video service like Plex (if you followed this guide, Plex is not exposed, so it’s fine)
- Do not use Cloudflare tunnels for the BitTorrent protocol (if you followed this guide, everything is fine) ::
Cloudflare Configuration
DNS Zone
First, you need to set Cloudflare as your DNS zone manager. If you bought your domain from Cloudflare, that’s already done. Otherwise, check with your registrar how to add external DNS servers. Cloudflare provides step-by-step documentation on how to configure a DNS Zone, whether your domain is external or registered with Cloudflare.
If you only have one server to protect behind Cloudflare, you can delete all existing DNS records. By default, your domain and all its subdomains will be redirected to the tunnel.
If you have subdomains pointing to other servers, you can still define them in the DNS zone using A records.
If you have several servers and tunnels under one domain, see here.
API Key
Start by creating a new Cloudflare API token and retrieving your zone and account IDs.
On your Cloudflare dashboard, on your domain overview page, you’ll see the zone
and account
IDs at the bottom right. Save both securely.
Just below that is a link titled Get your API token. Click it. The token scope must include Zone:DNS:Edit
and Account:Cloudflare Tunnel:Edit
. Your page should look like the screenshot below.
Once created, your token will only be shown once. Save it securely, as it cannot be viewed again later.
Cloudflare Zero Trust
You must register for Cloudflare Teams to access the Zero Trust dashboard that manages tunnels and access policies. This is a premium service, but there’s a free plan for up to 50 users—perfect for a home lab. Keep in mind that a valid credit card is required to register, but the free plan incurs no charges.
Register via this link.
SWAG Configuration
::alert{type="info"} :::list{type="info"}
- This guide assumes you own
mondomaine.fr
and that its DNS is correctly pointing to Cloudflare, as described above. ::: ::
SWAG supports two Docker Mods:
- Cloudflared, the container used to create and manage tunnels
- Cloudflared Real IP, which allows SWAG to receive the true source IP of incoming requests instead of Docker’s internal IP (important for IP geolocation mods like DBIP).
These two mods, merged into the SWAG container, require some configuration.
Tunnel Configuration
Create a file tunnelconfig.yml
to reference in your SWAG compose.yaml
.
::alert{type="success"} ✨ Tip: Use File Browser to navigate and edit files instead of using the terminal. ::
sudo vi /docker/swag/config/tunnelconfig.yml
Press i
to enter insert mode and paste:
ingress:
- hostname: mondomaine.fr
service: https://mondomaine.fr
- hostname: "*.mondomaine.fr"
service: https://mondomaine.fr
- service: http_status:404
Press Esc
, then save and exit with :x
and Enter
.
Cloudflare Real IP Configuration
Now configure Cloudflare Real IP.
Open the nginx.conf
file:
sudo vi /docker/swag/config/nginx/nginx.conf
Press i
and add the following at the end of the http
section:
real_ip_header X-Forwarded-For;
real_ip_recursive on;
include /config/nginx/cf_real-ip.conf;
set_real_ip_from 127.0.0.1;
Save and exit with :x
.
Docker Compose
In Dockge, edit your SWAG stack with this:
---
services:
swag:
image: lscr.io/linuxserver/swag:latest
container_name: swag
cap_add:
- NET_ADMIN
env_file:
- .env
environment:
- DOCKER_MODS=linuxserver/mods:swag-dbip|linuxserver/mods:swag-dashboard|linuxserver/mods:swag-auto-reload|linuxserver/mods:universal-cloudflared|linuxserver/mods:swag-cloudflare-real-ip
- PUID=${PUID}
- PGID=${PGID}
- TZ=Europe/Paris
- URL=${DOMAIN}
- SUBDOMAINS=wildcard
- VALIDATION=dns
- DNSPLUGIN=${PLUGIN}
- EMAIL=${EMAIL}
- CF_ZONE_ID=${ZONE_ID}
- CF_ACCOUNT_ID=${ACCOUNT_ID}
- CF_API_TOKEN=${API_TOKEN}
- CF_TUNNEL_NAME=${TUNNEL_NAME}
- CF_TUNNEL_PASSWORD=${TUNNEL_PW}
- FILE__CF_TUNNEL_CONFIG=/config/tunnelconfig.yml
extra_hosts:
- ${DOMAIN}:127.0.0.1
ports:
- 81:81
volumes:
- /docker/swag/config:/config
- /docker/swag/config/fail2ban/fail2ban.sqlite3:/dashboard/fail2ban.sqlite3:ro
restart: unless-stopped
::alert{type="success"} ✨ Tip: Add a Watchtower label to automate updates:
labels:
- com.centurylinklabs.watchtower.enable=true
::
Fill in your .env
file:
PUID=
PGID=
DOMAIN=
PLUGIN=
EMAIL=
ZONE_ID=
ACCOUNT_ID=
API_TOKEN=
TUNNEL_NAME=
TUNNEL_PW=
Variable | Value | Example |
---|---|---|
PUID |
User ID (id username ) |
1000 |
GUID |
Group ID (id username ) |
1000 |
DOMAIN |
Your reserved domain | mondomaine.fr |
PLUGIN |
DNS provider (also configure cloudflare.ini ) |
cloudflare |
EMAIL |
Email for the certificate | you@email.com |
ZONE_ID |
Cloudflare Zone ID | aNhcz1l3JfWbFZo2XMpzQlP2iOqk |
ACCOUNT_ID |
Cloudflare Account ID | buKsjNHLyzKMM1qYnzOy4s7SHfly |
API_TOKEN |
API token | 53ydYus9TFFk1DOXNdP87iIcJtQjoW |
TUNNEL_NAME |
Tunnel name | my_tunnel |
TUNNEL_PW |
Strong, random password | iSzKRmP4VbnlsMvdSdgBEJiJi |
Once done, deploy the stack. Check the logs—you should reach server ready
.
Then confirm your tunnel appears under Networks > Tunnels in Cloudflare Zero Trust. By default, all subdomains will be routed through the tunnel—no need to define them in your DNS zone.
::alert{type="success"}
✨ Tip: If you want to expose a service without a tunnel, just define an A record in your DNS zone. If resolution fails, disable the proxy function for that record—e.g., for sub.mondomaine.fr
.
::
Managing Multiple Tunnels for Multiple Servers
By default, all subdomains of your domain are routed through the single tunnel. But if you have a second server, just change the tunnel name in that SWAG instance.
In your DNS zone, redirect subdomains to the correct tunnel.
Go to Networks > Tunnels in Cloudflare Zero Trust.
Note the tunnel IDs:
Then in the Cloudflare DNS dashboard, click your domain name.
Click Add Record
and add these two CNAME records (include .cfargotunnel.com
):
Type | Name | Target |
---|---|---|
CNAME |
subdomain1 |
yourtunnelid1.cfargotunnel.com |
CNAME |
subdomain2 |
yourtunnelid2.cfargotunnel.com |
If you have many subdomains, point them to the above reference subdomains.
This way, if a tunnel ID changes, you only update one DNS record.
Example:
sub1
andsub2
also point to the server behindsubdomain1
:
Type | Name | Target |
---|---|---|
CNAME |
sub1 |
subdomain1 |
CNAME |
sub2 |
subdomain1 |
sub3
andsub4
point to the server behindsubdomain2
:
Type | Name | Target |
---|---|---|
CNAME |
sub3 |
subdomain2 |
CNAME |
sub4 |
subdomain2 |