How to set up cloudflared to protect your (origin) server by creating a tunnel and not needing to have the web ports open to the world.
Now isn’t that an enticing title.
In any case, the requirements here are to have one or more domains that are managed by cloudflare and then the access to install the cloudflare daemon on the webserver.
Installing cloudflared is pretty straightforward I think, see step 1 here: Download and install cloudflared or just the Cloudflare packages page.
Do note that they don’t have a package for Ubuntu Linux 24 (noble) yet, but the package for 22 (jammy) can be used.
After cloudflared
has been installed on the server, go to one.dash.cloudflare.com
and click on Networks
on the menu on the left hand side. Then click on create tunnel
.
Click on “Select Cloudflared”, then name your tunnel. I suggest using something you can
identify your server by, as you should only have one tunnel per server, then click “save tunnel”.
On the next page you will install and run a connector
. Click on the
“If you already have cloudflared installed…” area to copy the command to run on your server.
It should look something like this:
$ sudo cloudflared service install eySECRETtokenTHATshouldNOTbeSHARED
Run this on your server where you just installed cloudflared. If you have an IPv4 address
on the server, the command should exit successfully and the tunnel should be running.
You’ll see something like Linux service for cloudflared installed successfully
in the console.
If you only have an IPv6 address, the command will seem to hang and never finish. Press Ctrl-C to cancel it. It will have installed successfully (at least it did in my case) but since it tries to establish an IPv4 tunnel, it will not complete.
Calling sudo systemctl status cloudflared
should show where the service file is installed.
It should be etc/systemd/system/cloudflared.service
. Edit this file and change the ExecStart
line so it looks like this:
ExecStart=/usr/bin/cloudflared --edge-ip-version 6 --no-autoupdate tunnel run --token eySECRETtokenTHATshouldNOTbeSHARED
Then execute:
$ sudo systemctl daemon-reload
$ sudo systemctl restart cloudflared
The cloudflare daemon will now connect to cloudflare using IPv6 only, and you should see that is has connected in the cloudflare dashboard. Click next to configure what address should be routed through this tunnel.
Select a subdomain or not, like www
if you want to, it is not required, and then the domain.
Then select the type of traffic your server accepts, like http. Then add the URL of your local
webserver. If it listens on port 80, URL should be localhost:80
, if it listens on port 8080,
URL should be localhost:8080
and so on.
You can also specify type=https
and then localhost:443
but I am not sure this adds much
giving this traffic is local on your server.
When your domain and server is behind cloudflare, traffic will flow something like this:
Client browser ->
closest cloudflare server
this accepts the traffic, serves the result from their cache if they should or
routes traffic within their network to closest point to your actual server
and then sendes traffic encrypted through the tunnel to your server
The acute reader might notice there is a possible privacy issue here. For cloudflare to route your traffic they need to decrypt it at their edge, which they can do as they register a certificate for your domain when you order it with them. They probably route traffic encrypted in their network, but you have to trust them not to be snooping. For this site, I am not concerned about that and the protection it gives is worth more to me.