keepcalculator

06 Numbers and Powers

Cloudflare Tunnel Setup for Self-Hosted Server

Card No. 06·27133 · Updated · Standard formula, shown below

This guide walks you through setting up a Cloudflare Tunnel to securely expose a self-hosted server (like a home NAS, web app, or game server) to the internet without opening any inbound ports on your router. You’ll connect your server to Cloudflare’s edge network, which handles HTTPS, DDoS protection, and access control. You’ll need a domain name managed by Cloudflare (free plan works), a Cloudflare account, and a server running Linux, macOS, or Windows with outbound internet access.

What You’ll Need

  • A domain name with its DNS hosted on Cloudflare (you can transfer or add it free).
  • A Cloudflare account (sign up at dash.cloudflare.com).
  • A self-hosted server (any OS) with a service listening on a local port (e.g., a web server on port 80 or 3000).
  • Command-line access to that server (SSH, terminal, or admin shell).
  • Outbound internet access from the server (standard HTTPS on port 443).

Step-by-Step

  1. Add your domain to Cloudflare – If not already done, log in to Cloudflare, click Add a site, enter your domain, and choose the Free plan. Follow the prompts to update your registrar’s nameservers to the ones Cloudflare shows. Wait for the email confirmation (can take a few minutes to a few hours).
  2. Install cloudflared on your server – The official client is a single binary. On Linux (Debian/Ubuntu), run:
    wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64
    sudo mv cloudflared-linux-amd64 /usr/local/bin/cloudflared
    sudo chmod +x /usr/local/bin/cloudflared
    For other OSes, download the appropriate package from the Cloudflare docs (or use your package manager, e.g., brew install cloudflared on macOS).
  3. Authenticate cloudflared – Run cloudflared tunnel login. It will print a URL; open it in a browser, log in to Cloudflare, and select the domain you added. This saves a certificate file (cert.pem) to your home directory.
  4. Create a tunnel – Run cloudflared tunnel create my-tunnel (replace my-tunnel with a name you like). This creates a tunnel ID and a credentials file. Note the tunnel UUID (a long string) – you’ll need it later.
  5. Configure the tunnel – Create a config file at ~/.cloudflared/config.yml (or /etc/cloudflared/config.yml on Linux). A basic example:
    tunnel: my-tunnel
    credentials-file: /home/youruser/.cloudflared/my-tunnel.json
    
    ingress:
      - hostname: app.example.com
        service: http://localhost:8080
      - service: http_status:404
    

    Replace app.example.com with your subdomain, localhost:8080 with your service’s address, and the credentials path with the actual file location.

  6. Route DNS – Run cloudflared tunnel route dns my-tunnel app.example.com. This creates a CNAME record pointing to your tunnel. You can also do it manually in the Cloudflare dashboard: add a CNAME with name app and target my-tunnel.cfargotunnel.com (proxied).
  7. Run the tunnel – Start it with cloudflared tunnel run my-tunnel. You should see logs showing a successful connection. Test by visiting https://app.example.com from any browser.
  8. Run as a service (optional but recommended) – To keep it running after logout, install it as a systemd service (Linux) or launchd (macOS). Cloudflare provides a helper: sudo cloudflared service install after you’ve run the tunnel once. This will create a background service that auto-starts.

Common Mistakes

  • Using the wrong credentials file path – The credentials-file in config.yml must point to the JSON file created by tunnel create. If the path is wrong, the tunnel won’t start.
  • Forgetting to set DNS to Proxied – The CNAME record must have the orange cloud (proxied) enabled. If it’s greyed out (DNS only), traffic won’t go through the tunnel.
  • Hardcoding the tunnel UUID instead of name – In config.yml, the tunnel key accepts either the name or the UUID. If you use the UUID, make sure it’s correct.
  • Not opening the firewall for the local service – The tunnel connects to your local service on the specified port. If the service is bound to 127.0.0.1 only, that’s fine, but if it’s bound to a specific interface, ensure it’s reachable from the cloudflared process.
  • Using HTTP instead of HTTPS in the ingress service – The service field should be the protocol your local service speaks (usually http://). If your service uses HTTPS with a self-signed cert, you may need https:// and disable cert verification in the config (advanced).

Tips

  • Use a dedicated subdomain – Create a subdomain like nas.example.com or app.example.com to keep things organized.
  • Secure with Cloudflare Access – You can add an extra layer of login (email, Google, etc.) by enabling Cloudflare Access on the tunnel’s hostname in the dashboard. This is free for up to 50 users.
  • Monitor logs – Run cloudflared tunnel run my-tunnel --loglevel debug to see detailed logs when troubleshooting.
  • Update regularly – Keep cloudflared updated to get security fixes and new features. Use your package manager or re-download the binary.
  • Use a config file for multiple services – You can expose several services by adding multiple hostname entries under ingress. Each maps a different subdomain to a different local port.

Troubleshooting

  • Tunnel starts but site doesn’t load – Check the ingress rule. The hostname in the config must match the DNS record exactly (including subdomain). Also verify the service port is correct and the service is running locally (test with curl localhost:8080).
  • Error: “Cannot determine default ingress” – This usually means your config.yml is missing or malformed. Ensure the file is in the correct location (~/.cloudflared/config.yml) and has the required tunnel and ingress sections.
  • DNS record not resolving – If the CNAME doesn’t appear or is grey, re-run cloudflared tunnel route dns. Also check the domain’s nameservers are correctly set to Cloudflare.
  • Certificate errors – Cloudflare automatically issues an SSL certificate for your hostname. If you see a certificate warning, wait a few minutes and refresh. If it persists, check that the hostname is active in the Cloudflare dashboard (SSL/TLS tab).
  • Connection refused – The tunnel can’t reach your local service. Check the service is listening on the correct interface (e.g., 0.0.0.0 or localhost) and port. Use netstat -tulpn to see listening ports.
  • Cloudflared won’t start as a service – If you installed the service before running the tunnel, it may fail because credentials are missing. Run cloudflared tunnel login and cloudflared tunnel create first, then reinstall the service.

Frequently Asked Questions

Do I need to open any ports on my router?

No. Cloudflare Tunnel makes an outbound connection from your server to Cloudflare’s edge. No inbound ports are opened, which is a major security benefit.

Can I use this with a free Cloudflare plan?

Yes. Tunnels are available on the free plan, including unlimited traffic and basic DDoS protection. Some advanced features like Access require a paid plan, but the tunnel itself is free.

What if my server is behind a NAT or a firewall that blocks outbound connections?

Cloudflare Tunnel only needs outbound HTTPS (port 443) to reach Cloudflare’s network. Most firewalls allow this. If it’s blocked, you’ll need to allow outbound 443.

Can I expose multiple services with one tunnel?

Yes. Define multiple hostname entries under ingress in the config file, each mapping to a different local service. You’ll need to create a DNS route for each hostname.

Is it safe to expose a home server this way?

Cloudflare Tunnel hides your IP address and provides HTTPS, but you should still secure your service with strong authentication. Consider adding Cloudflare Access for an extra login layer.

How do I update cloudflared?

If you installed via package manager, use that (e.g., sudo apt update && sudo apt upgrade cloudflared). For manual installs, re-download the binary and replace the old one.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →