Cloudflared


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.