Caddy with Cloudflare Tunnel

This is a basic guide to using Cloudflared Tunnel with Caddy on FreeBSD.

Prerequisites

  1. Have a domain registered with Clouflare.
  2. Have a working Caddy instance with valid certs.
  3. A tunnel created at https://one.dash.cloudflare.com/ (under Access → Tunnels).

With internal HTTP

Depending on how you configured Caddy, things will change slightly. If you are serving your website over HTTP only, you will only need to set the “Service” option under “Public Hostname Page” to HTTP with the URL localhost (see below image). It should then work.

The Caddyfile should then read:

:80 {
	(site block contents)
}

Screenshot_20230119_072432

With internal HTTPS

If you are using a self-signed, standalone or DNS-validated HTTPS certificate, you will need to change two options within Cloudflare tunnel settings:

  1. Change the “Origin Server Name” to the domain Caddy is expecting.

  2. Change the “HTTP Host Header” to the same domain name.

If you are using a self-signed certificate, you also need to enable the option “No TLS Verify”

When using a self-signed, standalone, or DNS-validated HTTPS certificate, the Caddyfile will be:

cloud.server.com {
	(site block contents)
}

Once the tunnel is configured, run:

pkg install cloudflared

Then configure it to run automatically at startup by adding its command to /etc/rc.local:

echo "/usr/local/bin/cloudflared tunnel run --token YOUR-TOKEN >/dev/null 2>/dev/null &" > /etc/rc.local

Then restart your jail/OS etc…
The tunnel should start working and you should be able to access your service externally.

You can alternately use:

cloudflared tunnel run --token <your token>

for a one time run.

Please make sure your DNS is resolving properly as well. For use cases where a DNS-validated certificate is used, you might configure to have DNS resolved internally to a local jail IP, with external access enabled through the tunnel.

Cloudflare has tunnel install instructions for Docker and other things, but not FreeBSD, So only FreeBSD is included here.

1 Like

Hi,

I am looking to achieve this, using internal HTTPS but I’m struggling because I want my caddy server on a subdomain, not my root domain because I already have another server on that. I want caddy to be on server2.website.com and not website.com.

I have set cloudflared and caddy on the same docker network, then caddy on the same network as all the services I want to expose. I have set a tunnel to https://caddy:443 to server2.website.com in my docker tunnel settings. But what value should I set Origin Server Name and HTTP Host Header to ? Should it be server2.website.com or website.com ?

In both cases, I have a BAD GATEWAY error. I also tried to tell the tunnel to connect to http://caddy:80 and the same error happens.

I don’t use docker.

But I would think it should be set to server2.website.com

Did you set your tunnel to http://caddy:80 or https://caddy:443 ? Is Caddy able to get its certificates for other subdomains even with the tunnel in between ?