Exposing Local Services Without Opening Your Router
Port forwarding has been the standard method for making home-hosted services accessible from the internet, but it comes with a list of problems that range from mildly annoying to genuinely risky. You need a static IP or a dynamic DNS workaround, your ISP may block inbound connections on common ports, and every open port is an invitation for automated scanners to start probing your network. Cloudflare Tunnel sidesteps all of that by flipping the connection model: instead of your router accepting inbound traffic, a lightweight daemon running on your machine reaches outward to Cloudflare’s network, creating an encrypted tunnel that routes requests back to your service.
The result is that you can run a web app, a dashboard, or any HTTP service on a home server or a cloud VM and give it a public URL – with no open ports, no exposed IP address, and Cloudflare’s global edge sitting in front of it. The setup takes about fifteen to twenty minutes, and the free tier covers everything most self-hosters need.

What You Need Before Starting
The prerequisites are minimal. You need a domain name whose DNS is managed by Cloudflare – not just registered through them, but actively using Cloudflare’s nameservers. If your domain currently points to another DNS provider, you will need to migrate it, which takes anywhere from a few minutes to a few hours depending on your registrar. Cloudflare’s free plan is sufficient for everything in this guide.
You also need a machine running the service you want to expose – a Raspberry Pi, a home server, a VPS, or even a regular desktop. That machine needs to have cloudflared installed, which is the official Cloudflare Tunnel daemon. It runs on Linux, macOS, and Windows, and it does not require root access to operate, though the initial service installation on Linux does.
One important clarification: Cloudflare Tunnel works well for HTTP and HTTPS traffic. TCP tunneling (for things like raw SSH or database connections) is available but requires a slightly different configuration using Cloudflare’s WARP client on the user’s side. This guide focuses on the HTTP use case, which covers the majority of self-hosted services – dashboards, media servers, recipe apps, and similar tools.
Installing and Authenticating cloudflared
On a Debian or Ubuntu system, the fastest path is to download the .deb package directly from Cloudflare’s GitHub releases page and install it with dpkg. Alternatively, you can add Cloudflare’s official apt repository and pull updates automatically. Once installed, run cloudflared tunnel login to open a browser-based authentication flow. You will be redirected to Cloudflare, asked to choose which domain the tunnel should be authorized for, and a credentials file will be saved to ~/.cloudflared/ on your machine.
After authentication, create the tunnel itself with cloudflared tunnel create my-tunnel-name. Cloudflare assigns it a UUID, and a JSON credentials file for that specific tunnel is saved locally. Keep this file safe – it is the only thing that authorizes your machine to run that tunnel. You can verify it was created by running cloudflared tunnel list.

Configuring the Tunnel and DNS Routing
The tunnel configuration lives in a YAML file, typically placed at ~/.cloudflared/config.yml. The structure is straightforward. You declare the tunnel UUID, the path to its credentials file, and an ingress block that maps public hostnames to local service addresses. A basic example for a service running on port 8080 looks like this: set tunnel to your UUID, set credentials-file to the JSON path, then under ingress add a rule where the hostname is app.yourdomain.com and the service is http://localhost:8080. Every config must also end with a catch-all rule – a final ingress entry with no hostname and the service set to http_status:404 – or cloudflared will refuse to start.
Multiple services can be routed through a single tunnel. You simply add more hostname-to-service mappings in the ingress block, each pointing to a different local port. This means one running instance of cloudflared can expose your media server on one subdomain, your home automation dashboard on another, and a self-hosted recipe manager on a third – all through a single outbound connection from your machine.
Once the config file is ready, create the DNS records automatically with cloudflared tunnel route dns my-tunnel-name app.yourdomain.com. This adds a CNAME record in your Cloudflare DNS pointing the subdomain to your tunnel’s edge address. You do not touch your router at all. If you have multiple subdomains configured in the ingress block, run the route command once for each hostname. The DNS updates propagate almost instantly since Cloudflare controls both sides of the record.
To test before committing to a permanent setup, run cloudflared tunnel run my-tunnel-name in the foreground. If everything is configured correctly, the terminal will show a successful connection and your service will be live at the public URL. Visit the subdomain in a browser and confirm it loads. If you see a Cloudflare error page instead, the most common causes are a misconfigured ingress hostname (check for typos), the local service not actually running on the declared port, or a missing catch-all ingress rule.

To make the tunnel run permanently and survive reboots, install it as a system service. On Linux, cloudflared service install registers it with systemd, reading from the config file you created. After that, sudo systemctl enable cloudflared and sudo systemctl start cloudflared are all you need. The daemon will restart automatically on failure and start on boot without any manual intervention. For self-hosters running services like Dasherr as a browser startpage, this means that startpage is now accessible from any device, anywhere, without touching the router at all.
One thing worth understanding about Cloudflare Tunnel is what you are trading for the convenience. Your traffic passes through Cloudflare’s infrastructure, which means Cloudflare can technically inspect unencrypted payloads before they reach your server. For a public-facing dashboard or a recipe app, this is rarely a concern. For services handling sensitive personal data – health records, private communications, financial information – the architecture deserves more scrutiny. Cloudflare does offer an option to disable SSL inspection at the edge if you configure your origin to use its own certificate, but the routing still transits their network. That trade-off is worth understanding before you route everything through the tunnel.





