Skip to content

Cloudflare Tunnel

Tip

It is NOT a separate Ansible role yet. However, it's installation is handled by Ansible, so it works, it's just a bit of a structural issue on my end.

Overview

Cloudflare Docs

Cloudflare Tunnel provides you with a secure way to connect your resources to Cloudflare without a publicly routable IP address. With Tunnel, you do not send traffic to an external IP — instead, a lightweight daemon in your infrastructure (cloudflared) creates outbound-only connections to Cloudflare's global network. Cloudflare Tunnel can connect HTTP web servers, SSH servers, remote desktops, and other protocols safely to Cloudflare. This way, your origins can serve traffic through Cloudflare without being vulnerable to attacks that bypass Cloudflare.

Basically, you can expose your services without a publicly routable IP (like behind CGNAT) and protection handled by Cloudflare. Pretty convenient if you ask me.

Heads up

You are trusting Cloudflare with your data.

While this sounds very great, you trust Cloudflare with your data.
TLS is terminated at Cloudflare and traffic is decrypted on Cloudflare’s edge before being re‑encrypted to your origin. This enables Cloudflare’s protections, but it also means Cloudflare can technically see the plaintext.
In my opinion this doesn't make good Zero Trust access if your data is sensitive.

Installation may need some manual steps on Cloudflare Dashboard (I'll try to automate it soon).
You have to have a Cloudflare account.
You also need a valid domain name that you own.

Configuration

Onboard your domain to Cloudflare

The official documentation for onboarding can be found here.

If you didn't buy your domain from Cloudflare (which I didn't as Namecheap was, well cheaper), then do this step. If you bought it from Cloudflare, you can skip.
On https://dash.cloudflare.com/ navigate to Domains and either press Buy a domain if you don't have one and want to buy it from Cloudflare or continue with Onboard a domain.
Enter your apex domain and press Continue at the bottom.
Next, update the nameservers at your registrar.
For me, I logged in to Namecheap, navigated to Account > Domains > Manage.

Namecheap Navigation

Then I updated the nameservers with the ones Cloudflare provided:

Namecheap DNS panel


Create the Cloudflare Tunnel

Official documentation for creating the tunnel with API token can be found here

Tip

I've recently found out that creating the tunnel can be automated.
I'll dig deeper when I have the time to, and will update this section.
Until that, please use the manual method.

Official documentation for creating the tunnel through GUI can be found here

On the Cloudflare Dashboard navigate to Zero Trust > Networks > Connectors.
Here, under Cloudflare Tunnels press Create a tunnel and choose Cloudflared, then press Next.

Cloudflare Create a tunnel

Enter a recognizable name, then continue.


Installing cloudflared

Token length

The token is much longer than visible in the UI. Always use the copy button.

If you wish to delegate installation to Ansible (which is absolutely recommended), then simply copy your token (press the copy button as it's way longer than shown) and paste it into the secrets.yml vault to cloudflare_install_token.
Continue with the next step.

Choose your environment and follow the instructions.
Alma:

curl -fsSl https://pkg.cloudflare.com/cloudflared.repo | sudo tee /etc/yum.repos.d/cloudflared.repo

sudo yum update
sudo yum install cloudflared

sudo cloudflared service install {token}
Debian:
sudo mkdir -p --mode=0755 /usr/share/keyrings
curl -fsSL https://pkg.cloudflare.com/cloudflare-public-v2.gpg | sudo tee /usr/share/keyrings/cloudflare-public-v2.gpg >/dev/null

echo 'deb [signed-by=/usr/share/keyrings/cloudflare-public-v2.gpg] https://pkg.cloudflare.com/cloudflared any main' | sudo tee /etc/apt/sources.list.d/cloudflared.list

sudo apt-get update && sudo apt-get install cloudflared
sudo cloudflared service install {token}


Publishing applications

Official documentation for publishing an application with API token can be found here

Tip

I've recently found out that tunnel configuration can be automated.
I'll dig deeper when I have the time to, and will update this section.
Until that, please use the manual method.

Official documentation for publishing an application through GUI can be found here

After picking a method to install cloudflared hit Next and configure your first Published Application.

Subdomains & paths

You don't have to add a Subdomain or Path, but if you wish to publish more than one service, it will be necessary.
There are services that "don't like to live" on a path (I think Nextcloud is one), so be so kind and give them a subdomain

  1. For the Domain choose the domain added to your account.

  2. For Service select HTTPS and enter localhost:443 into the URL field.

Default port

The guide assumes you run your reverse proxy (Caddy in my case) on port 443. Adjust the port if your setup differs.

Cloudflare configure application route

To add more Published Applications, go back to Zero Trust > Networks > Connectors. and click the icon, then Configure. Go to Published application routes and repeat step 1. and 2.

Future

  1. Creating a separate Ansible role to remove the tasks from the main playbook.
  2. Automating the tunnel creation with API as detailed here
  3. Trying to find more parts of this procedure that can be automated and adding that to Ansible.