Cloudflare tunnel

Cloudflare tunnel is great when it works. Internet is full of examples to set it up, and every guide and review tells how easy it is.

In my case, I considered this as not actually true, I had that much difficulties on setting up tunnels that I decided to write a guide on topic. Start by creating account at cloudflare.

Site

First you need yourself a domain that you add as a site to Cloudflare's service. Free plan is sufficient for most users.

You get instructions on how to point domain to selected Cloudflare's DNS servers. Sometimes it takes awhile for DNS on domain to set, so in the meantime- setup rest of your settings. My setup didn't take very long as I registered a cheap domain specific for this purpose and have no plans to host anything there for the audience. Finally when DNS has settled and your site's status says active, we can proceed.

Zero trust

Select Zero trust from the sidebar, this is where tunnels are managed. Set up things as you like but you do not need to set up that much, for example under Gateway you find DNS and Firewall policies, there is no need to touch them at all to get tunnel(s) working. Under SettingsGeneral settings you can find your Team domain. Sub-domain/hostname part, meaning that part before .cloudflareaccess.com is something that you should remember as when you login with WARP (available for desktop os's and phones) to establish a client connection, this Team ID is asked on logon. So write it up if it is difficult to remember.

Important note

Under SettingsNetwork you can find setting for proxy. To get tunnels working, you must enable proxy. As default, it seems to be disabled. When you enable it, you can select either TCP or UDP, or both - I chose both. This is part rarely mentioned in other guides.

Other settings on that page, are not important for tunneling, except Split tunnels and local domain fallback - So select manage. Under there, you can find settings for device enrollments. Make necessary changes there, for login requirements. For example *.yourmaildomain.com

Edit also default profile - there you find section Split tunnels, select what you prefer, but in this example we choose to Exclude IPs and domains. Click manage after that, and you find yourself from a list of subnets, ip addresses and domain names. Make sure, that network you want to connect to is not in the list. For example, if your lan is 192.168.0.1/24, make sure none of subnets on list include your used ip range.

For service mode, I chose Gateway with WARP, not sure if other modes work. It should be chosen as default.

If you want local dns to resolve to ip addresses, that is set under Local Domain Fallback, but as I did not use it, I won't be giving guidance on setting it up. But if you want that feature, that's where you find it.

On Device posture, as WARP Client checks, I added Gateway with name Gateway - but that possible is not a requirement. Other settings on that page can be leaved as-is.

Finally, basic setup is complete. Keep your browser open and make sure you stay logged in to Cloudfare.

Openwrt shell

Login to your router and install cloudflared package.

It has some settings at /etc/config/cloudflared, but only setting that should be changed is enabled boolean. It is false as default.

Second place for configuration is at /etc/cloudflared, some changes there are necessary- but at this moment, we don't touch there at all.

Let's create our tunnel

root@openwrt:/etc/cloudflared# cloudflared tunnel login
Please open the following URL and log in with your Cloudflare account:

https://dash.cloudflare.com/argotunnel?callback=https%3A%2F%2Flogin.cloudflareaccess.org%2FXXXXXXXXXX

Leave cloudflared running to download the cert automatically.

Copy the link and open it in your browser to proceed. If you were still logged in, you will get a view where you see the site as option that we added in the beginning. Select your site and click Authorize.

Go back to shell, and you see a notification that cert.pem has been created. We copy it to cloudflared's config path.

You have successfully logged in.
If you wish to copy your credentials to a server, they have been saved to:
/root/.cloudflared/cert.pem
root@openwrt:/etc/cloudflared# cp /root/.cloudflared/cert.pem /etc/cloudflared/

Next we create the tunnel, in this example, our tunnel is called TUNNELNAME. Finally, copy generated file to config path. XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX is generated id.

root@openwrt:/etc/cloudflared# cloudflared tunnel create TUNNELNAME
Tunnel credentials written to /root/.cloudflared/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.json. cloudflared chose this file based on where your origin certificate was found. Keep this file secret. To revoke these credentials, delete the tunnel.

Created tunnel TUNNELNAME with id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
root@openwrt:/etc/cloudflared# cp /root/.cloudflared/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.json /etc/cloudflared/

Now we edit /etc/cloudflared/config.yml, I commented out first line about url. It is unnecessary. File looks like this:

#url: http://localhost:8000
tunnel: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
credentials-file: /etc/cloudflared/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.json

Finally I edited /etc/init.d/cloudflared because I got errors to log about wrong sysctl values. I first added them to sysctl.d but even though sysctl was executed before cloudflared, original settings had remained and errors kept on log. Here I added 2 lines beginning with

sysctl -w

to avoid errors.

#!/bin/sh /etc/rc.common
# Copyright (C) 2021 Tianling Shen <cnsztl@immortalwrt.org>

USE_PROCD=1
START=99

CONF="cloudflared"
PROG="/usr/bin/cloudflared"

append_param_arg() {
	local value
	config_get value "config" "$1" $2
	[ -n "$value" ] && procd_append_param command "--$1" "$value"
}

start_service() {
	config_load "$CONF"

	local enabled
	config_get_bool enabled "config" "enabled"
	[ "$enabled" -eq "1" ] || return 1

	sysctl -w net.ipv4.ping_group_range="0 429296729"
	sysctl -w net.core.rmem_max=2500000

	procd_open_instance "$CONF"
	procd_set_param command "$PROG" "tunnel"
	procd_append_param command "--no-autoupdate"

	append_param_arg "config" "/etc/cloudflared/config.yml"
	append_param_arg "origincert" "/etc/cloudflared/cert.pem"
	append_param_arg "region"
	append_param_arg "loglevel"
	append_param_arg "logfile"

	procd_append_param command "run"

	procd_set_param respawn
	procd_set_param stderr 1

	procd_close_instance
}

reload_service() {
	stop
	start
}

service_triggers() {
	procd_add_reload_trigger "$CONF"
}

After this, start service.

root@openwrt:/etc/cloudflared# /etc/init.d/cloudflared start

We are still not there, go back to browser now and at Cloudflare Zero Trust, open AccessTunnels, on the list you can see our freshly created TUNNELNAME. Choose to configure it and you get a prompt that tunnel must be migrated and migration is irreversible. Go ahead and migrate it, confirm all queries. Now, re-configure it. Choose Private Network tab and add new network. On the CIDR prompt add your lan's subnet, on this example it was 192.168.0.0/24.

After this we enable, and restart cloudflared as we are all setup now.

root@openwrt:/etc/cloudflared# /etc/init.d/cloudflared stop
root@openwrt:/etc/cloudflared# /etc/init.d/cloudflared enable
root@openwrt:/etc/cloudflared# /etc/init.d/cloudflared start

Test network

Install Cloudflare WARP to your phone, disable wi-fi staying on mobile network and start WARP. On SettingsAccount, you must enter your team name - I told in the beginning of this guide that it is in Cloudflare's settings in General Settings. If you added proper rule to SettingsWarp settingsDevice enrollment you will be asked your credential, meaning your email address. You get a verification code to your mail then which you need to enter there.

Under WARP's SettingsAdvancedConnection optionsExcluded routes verify that your lan's subnet isn't on the list - we earlierly excluded it, then under Virtual Networks verify that profile that you decided to use is checked. Mine is default as I edited default profile without creating a new one. Finally exit settings - front page should say Zero Trust, Connected and Your internet is protected. Open your web browser and point it to your router's ip at 192.168.0.1 and if all went well, LuCi opens (in case you have it installed).

One final note

You may notice, that ping doesn't work. This is normal and you cannot do anything about it because we enabled TCP and UDP earlierly and IGMP used by ping, is not available as a feature on cloudflared.

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
  • Last modified: 2023/03/21 16:07
  • by tmomas