How to setup a Cloudflare tunnel on Linux
Tags: tutorial, devops
Published: 2021-12-27 15:07:12

You can now use the GUI to set up Cloudflare Tunnels instead of the CLI, which is way more streamlined and easy to do.
{% embed https://dev.to/realchaika/how-to-setup-a-cloudflare-tunnel-new-using-gui-method-4maf %}

## What are Cloudflare Tunnels

Cloudflare Tunnels can be used to expose internal services using outbound only connections. Think Ngrok tunnels. Cloudflare Tunnels can be used to proxy normal http/https connections, ssh/vnc, as well as more advanced things like arbitrary TCP, with some more restrictions.

The advantage of using Cloudflare Tunnels is not having to open any ports on your web server, no need for anything like IP Restrictions, Origin Cert checking, etc. Cloudflare Tunnels also use http/2 to connect to Cloudflare's Edge (soon http3/quic), whereas normally Cloudflare will only connect to an origin over http/1.1.

This guide will focus on setting up a tunnel for a normal web server over http. It's important to remember that since the tunnel is acting as a proxy for traffic, the web server (or whatever you are exposing via the tunnel) will see all incoming traffic as localhost. You will need to grab the real user's IP from a header (normal cdn things) but also not rely on restricting any resources to localhost.

---

## Pricing / Limits of Cloudflare Tunnels

Cloudflare Tunnels are completely free. Cloudflare Tunnels used to be named Cloudflare Argo Tunnels, and required a Cloudflare Argo Subscription. [Cloudflare Argo] (https://www.cloudflare.com/products/argo-smart-routing/) is a service Cloudflare offers where they will use "smarter routing" to route requests to your origin avoiding network congestion, charging per gigabyte transferred.

Now Cloudflare has completely separated the products, while you can still buy an Argo Subscription to try to speed up traffic to your origin. Tunnels are free for any traffic amount with only a few limits: [1000 Tunnels per account, and 100 Active Connections from each tunnel to Cloudflare's edge] (https://www.cloudflare.com/products/argo-smart-routing/).

---

### Requirements:

- Cloudflare Account (free)
- Domain added to Cloudflare (using CF nameservers, etc)
- Linux server with a web server already configured on it
- No ports need to be port forwarded or allowed through your firewall

---

### How to setup a Cloudflare Tunnel

#### Installing Cloudflared

Cloudflare Tunnels use Cloudflared, a tunneling daemon to proxy the traffic from Cloudflare, and also to provide a CLI interface to make and manage tunnels.

##### .deb install (Ubuntu, Linux Mint, Debian, etc)

```console
wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb && sudo dpkg -i cloudflared-linux-amd64.deb
```

#####​ .rpm install (Centos, Fedora, Rhel, OpenSusu, etc)

```console
wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-x86_64.rpm && sudo rpm -i cloudflared-linux-x86_64.rpm 
```


#### Login to Cloudflared

```console
cloudflared tunnel login
```

This command should give you the link to sign into Cloudflare, and select a zone (website) to create tunnels on.

When done, it will download an account certificate (cert.pem file in the default cloudflared directory). This cert will be used to authorize future API Requests to create and manage tunnels. Once your tunnel is up and running, it will use its own credentials file, and you can safely delete this unless you want to keep managing/creating/deleting tunnels from this machine.


#### Create a tunnel

```console
cloudflared tunnel create <name>
```
This command will create a named tunnel based on the name entered. It will generate a new tunnel, this includes generating a UUID for the tunnel, a tunnel credentials file in the default cloudflared directory, and a subdomain of .cfargotunnel.com that you can use to route requests to. 

In this example, I'll be naming my tunnel "frontpage".


#### Create your tunnel configuration file

Throughout the past two steps, after logging in and creating the account cert, and making a tunnel, generating the tunnel cert, cloudflared has listed the path to your .cloudflared directory, which is most likely based off your home directory.
Something like "~/.cloudflared" or "/home/{username}/.cloudflared"

Navigate to that folder now. You should see cert.pem (your account cert) and a .json file named off the UUID of your tunnel.

Create a new file in the same directory, config.yml, and open it using your preferred text editor.

```yml
url: http://localhost:80
tunnel: <Tunnel-UUID>
credentials-file: /home/{username}/.cloudflared/<Tunnel-UUID>.json
```
The URL line corresponds to the internal service you wish to expose. It's not necessary to use https://, the connection between Cloudflare Tunnel and Cloudflare's datacenter is already encrypted. This is just the tunnel connecting locally to the web server.

The Tunnel UUID is a 36 character value that corresponds with your named tunnel. It was displayed when you made the tunnel. You can also find it by going to your .cloudflared directory and looking for the newly created json credentials file for the tunnel you made. It should be named {Tunnel-UUID}.json.


#### Route traffic to your tunnel

You just create a CNAME Record to route traffic to your tunnel. You can do so easily using the cloudflared cli

```shell
cloudflared tunnel route dns <Tunnel UUID or Name> <Hostname>
```
For example, my tunnel is named `frontpage` and I wanted it to be accessible via `example.chaika.dev`. So I did
```shell
cloudflared tunnel route dns frontpage example.chaika.dev
```


#### Run your tunnel

Finally, you can test out your tunnel.

```console
cloudflared tunnel run <UUID or Name>
```
You can also specify a specific configuration file to run

```console
cloudflared tunnel --config path/config.yaml run
```

Once your tunnel is live, try accessing it via the hostname you routed it to. It may take a few seconds for the tunnel to be fully live/accessible. If something is wrong, the tunnel running in the CLI should tell you more information about errors.


#### Run your tunnel as a service

Running your tunnel manually will work, but isn't the best. It won't automatically start if your machine reboots, have to ensure its open/running, etc.

Luckily, cloudflared supports installing itself as a service very easily.

```console
sudo cloudflared service install
```
You may need to manually specify config location. In my case, I did have to specify it.

For example,

```console
sudo cloudflared --config /home/{username}/.cloudflared/config.yml  service install 
```
> Note that you specify the config argument before the 'service install' command parameters.

The configuration will be copied over to `/etc/cloudflared`
I would recommend copying over the tunnel credentials file ({Tunnel-UUID}.json) over to there as well.

Then, just launch the service and set it to start on boot

```console
sudo systemctl enable cloudflared
sudo systemctl start cloudflared
```

Ensure your tunnel started/is running fine:

```console
sudo systemctl status cloudflared
```

Test out your tunnel by visting the hostname you routed it to.

With any luck, it all worked, and your Cloudflare Tunnel is now all set up, running as a service, automatically starting on reboots, and working well!


## How the tunnel works

You may have noticed, when your tunnel starts up, it makes multiple connections. Cloudflare says it connections to multiple machines in case one crashes/reboots, it can use the other connections.

Each individual connection to Cloudflare is not limited to one user request at a time. Cloudflare says each connection can handled hundreds or thousands of requests at one time.

Each Tunnel supports up to 100 connections, you can launch more cloudflared replicas/instances for reliability. Cloudflare does not recommend doing this for load-balancing, and makes no guarantee about which connection is chosen. They recommend using their own load-balancing product along with tunnels for this. 

You can use the [Cloudflare Teams Dash](https://dash.teams.cloudflare.com/) under "Access", "Tunnels" to see a good view of each tunnel you have, what routes it has, uptime/connections it has, and all other relevant information.

Cloudflare for Teams/Cloudflare Access has a generous free plan you can use as well, for up to 50 people, using Google (or a ton of other sso options) for auth. You can very easily make an Application policy to protect your tunnel and limit it to only specific emails or other options.

{Tunnel-UUID}.cfargotunnel.com is a virtual/non-existent domain, that is only used internally when you make CName's pointing to your tunnel and other references. Other Cloudflare Customers cannot point their domains at your tunnel and bypass your Cloudflare Access or other restrictions.


## Closing notes

Hopefully, this helped you understand and create Cloudflare Tunnels. I made this tutorial in part for myself, Cloudflare's Tunnel Documentation does exist, and covers mostly everything, but glosses over a lot of details, and can be really confusing to beginners.

Thanks for reading. If you have any questions, let me know. I've used Cloudflare Tunnels for quite some time, although mostly in smaller websites/forums.