reverse proxy self-hosted services with cloudflare tunnel
Cloudflare Tunnel (once known as Argo Tunnel) is a mix between a reverse proxy and a TCP-based tunnel that links local TCP ports (e.g., a service that binds to 127.0.0.1 and TCP port 23456) and proxies all requests to and from Cloudflare at its edges to port 443.
Cloudflare Tunnels have recently become free to all.
The solution is not so different to using a service such as frp, and it escapes CGNAT as well.
Advantages over a self-hosted solution:
- No “proxy VPS” needed anymore, as the exposed part is provided by Cloudflare itself.
- Cloudflare provides DDOS protection, DNS hosting, and SSL certificates for free.
- On SSL: there is no need anymore to handle Letsencrypt certificates from own VPS or NAS at home. Cloudflare Tunnel connection from origin server to Cloudflare Edge is encrypted. From the public Internet to the Cloudflare Edge, there is Cloudflare free SSL.
- Argo Smart Routing is included for free.
- Signing up with a Cloudflare for Teams Free (up to 50 users) adds further nice features such as Cloudflare Access and Cloudflare Gateway.
- You can protect your instance with zero trust sign in methods. Easiest one: you receive a PIN via e-mail before accessing your service from the public Internet.
- Cloudflare Tunnel can change DNS records via command line, meaning that the whole process from “My service is up and listens to localhost” to “We are live on the public Internet” can all be made via command line.
- Tunnels are heavily thought for HTTP(S) services and for raw TCP. Even raw TCP support is limited (so far, only SSH and RDP work well). UDP is not supported.
- Vendor lock-in is stronger. It is difficult to leave Cloudflare already because of its DNS hosting, CDN services, and SSL handling. Cloudflare Tunnels are yet another lock-in mechanism.
- Cloudflare won’t implement all possible use cases. For example, WebDAV needs configuration changes to work, and only with Apache (no NGINX WebDav).
Documentation is available at Cloudflare, but some steps and concepts can be made clearer.
Binary, .deb, and .rpm are available for x86-64, x86, and ARMv6 and ARM64.
wget -q https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-amd64.deb dpkg -i cloudflared-stable-linux-amd64.deb
Visit the URL and authorize your domain.
cloudflared tunnel create your-tunnel-name
Tunnel credentials get written to a file named like
tunnel: 123456-abcdef credentials-file: /root/.cloudflared/123456-abcdef.json ingress: - hostname: app.yourdomain.com service: http://localhost:80 - service: http_status:404
Cloudflared can create the DNS entry for you:
cloudflared tunnel route dns your-tunnel-name app.yourdomain.com
To try out the tunnel:
cloudflared tunnel run
And visit the app at
To make the tunnel permanent at system start:
cloudflared service install
Configuration will be moved to
For Ubuntu/Debian, start the service with:
systemctl start cloudflared
Additional bits that weren’t explained by Cloudflare or weren’t clear to me:
- One tunnel (one instance of cloudflared) handles all services from one origin server. All services from one origin server are defined in
/etc/cloudflared/config.yml. This is the easiest configuration.
- Do not use one tunnel per service on a single origin server.
- End the ingress rules with a
- service: http_status:404so that non-existing paths and services generate an error.
- The configuration file supports wildcards.
I do not use a commenting system anymore, but I would be glad to read your feedback. Feel free to contact me.