Reaching the relay through a Cloudflare Tunnel
A Cloudflare Tunnel gives your relay a public HTTPS address without a server of
your own and without opening a port on your router. OAR can run Cloudflare's
cloudflared program for you: it starts it with the relay, restarts it when it
drops and shows its state in the status dot. Choose it when you have a domain on
Cloudflare and want to reach the relay from a phone or another network, or when
you need HTTPS for installing the page as an app
and push notifications.
cloudflared connects outward to Cloudflare. The relay keeps listening on this
machine only (localhost stays true), and Cloudflare carries requests for
your hostname down that connection to the relay's port.
What you need #
- A Cloudflare account with Zero Trust, and a domain (a zone) on it for the public hostname.
cloudflaredinstalled on the machine that runs the relay. OAR does not include it and does not install it.- A tunnel that you create in Cloudflare. OAR runs it from the tunnel's token.
The relay runs the program named in cloudflared, or else the
cloudflared it finds on its PATH. Install it with:
| System | Install |
|---|---|
| Windows | winget install --id Cloudflare. |
| macOS | brew install cloudflared |
| Linux | Cloudflare's package repository (Debian, Ubuntu, RHEL): pkg.cloudflare.com |
On Windows, a . or . launcher does not work. OAR starts a . or
. file.
One kind of tunnel
OAR supports a tunnel that runs from a token, the kind Cloudflare calls a
remotely managed tunnel. There is no setting for a credentials file or a tunnel
name, and none for a quick tunnel with a random address. If you run such a tunnel
yourself, start cloudflared outside OAR. OAR then knows nothing about it.
Setting it up #
- In your Cloudflare Zero Trust account, create a tunnel. Copy its token.
- Give the tunnel a public hostname on your zone, for example
relay., and point it atexample. com http://. If you changedlocalhost: 3333 portinconfig., use that port. This routing lives in Cloudflare, not on your machine.json - Add the
cloudflaredblock toTunnel config.with the token (see Config keys).json - Restart the relay with
oar restart.
Open https:// in a browser. You sign in with the access token
as usual.
The config block #
{
"cloudflaredTunnel": {
"mode": "managed",
"required": false,
"token": "<tunnel token>",
"binary": "cloudflared",
"extraArgs": []
}
}
| Key | Type | Default | What it does |
|---|---|---|---|
mode |
"disabled" or "managed" |
"disabled" |
managed makes the relay run cloudflared. |
token |
string | none | The tunnel's token. Required when managed; without it the tunnel stays off and the log says why. |
required |
boolean | false |
While the tunnel is not connected, the relay pauses taking messages from the queue. See Required tunnel. |
binary |
string | cloudflared |
The program: an absolute path, or a name looked up on PATH. A path must point at an executable file. A relative path with a folder in it counts from the relay's program folder, so use an absolute one. |
extra |
string array | [] |
Arguments added after cloudflared tunnel run --token <token>. Empty entries are dropped. |
The old form "enabled": true still works for mode: "managed". Three
environment variables override the file: COPILOT_,
COPILOT_ and COPILOT_. The
config.json reference lists the
keys with the other tunnel settings, and the
environment variables page lists the
variables.
The relay hands the token to cloudflared as a command-line argument
(cloudflared tunnel run --token <token>), not through the environment. On a
machine with other users, the token can therefore show up in the list of running
processes. The relay's log shows it as <redacted>.
How it behaves #
- Start and stop. The relay starts
cloudflaredwhen it starts and stops it (a termination signal) when it shuts down. - Connected. The tunnel counts as connected when
cloudflaredreports a registered connection, or, failing that, when it has run for five seconds. - Drops. When
cloudflaredexits, the relay starts it again after a wait of about 5, 10, 20, 40 and then 60 seconds, each with up to 20 percent added. The steps start over after a connection that lasted more than 30 seconds. - Bad token or deleted tunnel. If
cloudflaredexits within 10 seconds three times in a row, the relay reports the errorauth-and from then on retries only about once a minute.or- config - No
cloudflared. The relay starts as usual and the tunnel stays off. It looks again every minute and starts the tunnel once the program is there. If you installed it into a folder that is not on the relay'sPATH, restart the relay.
Required tunnel #
With required: true the relay does not take messages from the queue while the
tunnel is not connected. That includes the time before it first connects and a
missing cloudflared or token. Use it when the relay is only useful if you can
reach it from outside. Messages wait in the queue and run once the tunnel is
connected (see turns and the queue).
Seeing the state #
| Where | What it shows |
|---|---|
| Status dot | Amber, tooltip Web relay reachable via Cloudflare Tunnel, while the tunnel is connected. Green when it is set up but not connected: the tooltip says Web relay reachable; Cloudflare tunnel disconnected (cloudflared is missing. The relay still answers. See the menu and appearance. |
oar status |
A Tunnel: line when the tunnel is on: running, not connected, not connected (<reason>) or off: <reason>. With the relay stopped, it shows the same wording as oar doctor. See oar status. |
oar doctor |
disabled, managed (cloudflared: <path>) or managed, cannot start: <reason>. It reads the config only and changes nothing. See oar doctor. |
| The log | Lines that start with [cloudflared-: the command (the token shown as <redacted>), Tunnel connected, exits and reconnect delays, and cloudflared's own output. |
The relay does not know your public hostname, because the routing lives in Cloudflare, so none of these shows it.
Telling tunnel traffic apart #
Cloudflare adds a cf- header to every request it forwards. The relay uses
it to tell a request that came through the tunnel from one made on this
machine. To also treat the headers your own edge adds this way, list them in
tunnel. public lists the hostnames that reach the
relay, and trust says which proxies the relay believes about the
forwarded address. The default, "loopback", suits cloudflared on the same
machine. All three are in the config.json reference.
A second hostname for previews #
Previews need their own hostname, so a previewed app
never shares a login cookie with the relay. Add it to the same tunnel as a second
public hostname that points at the preview listener (http:// by
default). The previews page has the ingress example
and the previews block. Put the relay's hostname into public.
Cloudflare Access in front of the relay #
A Cloudflare Access application over the relay's hostname applies to every
visitor, including viewers of a shared conversation.
Without an exception they are asked to sign in and the link does not work. Let
/ and / through without a login.
Do not add a Cloudflare cache rule for /. A shared page reloads
that address to follow the conversation, and a cached answer would keep showing
an old state. The relay marks every API answer with Cache-, and every
answer with CDN- and Cloudflare- set to
no-. Cloudflare obeys those two ahead of a cache rule in your zone.
Security #
A tunnel puts the relay on the public internet. The access token is what keeps others out. See The access token and who can reach the relay and What OAR exposes.
The relay's session workers connect over sockets that only run on this machine.
Because a public tunnel forwards every path, the relay answers 403 to a request
on those paths that carries cf- or one of your tunnel, and the
log notes it with [tunnel-. Shared links, which arrive over the tunnel
without a login, are not affected.
Troubleshooting #
| What you see | What to do |
|---|---|
The tooltip says Cloudflare tunnel off: cloudflared is not installed (followed by how to install it), or oar doctor says cloudflared is not installed |
Install cloudflared (see What you need). The tunnel starts within a minute. |
cloudflared was not found as configured (<path>) |
cloudflared points at nothing. Correct the path, or clear the key to use cloudflared from PATH. |
cloudflared |
Add the token to the config, or set COPILOT_. |
Tunnel: not connected (auth- |
cloudflared keeps exiting at once. Check the token and that the tunnel still exists in Cloudflare. The log has cloudflared's own message. |
Tunnel: not connected (exit:<code>) |
cloudflared ended with that exit code. The relay is trying again; read the log. |
| The dot stays green although you opened the relay through the tunnel | The tunnel is not connected from the relay's side. Read the tooltip and oar status. |
| Messages do not run and the queue is paused | required is true and the tunnel is not connected. Fix the tunnel, or set required to false. |
| A shared link asks the viewer to sign in | Cloudflare Access is in the way. Let / and / through. |
| A shared page shows an old state | A cache rule covers /. Remove it. |
403 on a session-worker path |
Expected: those paths are closed to tunnel traffic. |
cloudflared is installed, but the tunnel does not start |
The relay may not see it on its PATH. Set binary to the full path and run oar restart. |