From DuckDNS to Cloudflare Tunnel: Why I Stopped Port Forwarding
The Problem with Port Forwarding
When I first exposed my homelab to the internet, I did what most people do: I opened port 443 on my router and pointed a DuckDNS subdomain at my home IP. It worked — for about a week.
Then I checked my Nginx logs and saw the reality of the public internet: bots constantly scanning for open ports, hammering /wp-admin, /.env, and every known vulnerability path you can imagine. My server was responding to all of them. Worse, my ISP (Nova, here in Greece) blocks inbound ports anyway, so half my setup was fighting the network the whole time.
Enter Cloudflare Tunnel
Cloudflare Tunnel flips the model entirely. Instead of opening a port and waiting for connections, your server makes an outbound connection to Cloudflare's edge. Traffic flows back through that tunnel. The result:
- Zero open ports on your router
- Your home IP is never exposed
- Free SSL, DDoS protection, and CDN caching included
The Setup
First, install cloudflared on your server:
# Download and install
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o cloudflared
sudo mv cloudflared /usr/local/bin/
sudo chmod +x /usr/local/bin/cloudflared
# Authenticate with your Cloudflare account
cloudflared tunnel login
Then create the tunnel and point your domain at it:
# Create a named tunnel
cloudflared tunnel create homelab
# Route your domain through it
cloudflared tunnel route dns homelab theprojecthomelab.org
The Config File
The magic lives in /etc/cloudflared/config.yml:
tunnel: your-tunnel-id-here
credentials-file: /home/nkon/.cloudflared/your-tunnel-id.json
ingress:
- hostname: theprojecthomelab.org
service: https://localhost:443
originRequest:
noTLSVerify: true
- service: http_status:404
Run it as a systemd service and you're done:
sudo cloudflared service install
sudo systemctl start cloudflared
What I Gained
| Before (DuckDNS + Port Forward) | After (Cloudflare Tunnel) |
|---|---|
| Port 443 open to the world | Zero open ports |
| Home IP exposed | IP completely hidden |
| Manual SSL renewal | Automatic SSL |
| ISP port blocking issues | Bypasses ISP entirely |
| Constant bot scans hitting server | Cloudflare absorbs the noise |
The Bonus: Browser-Based SSH
Once the tunnel was up, I added a second ingress rule for SSH access through Cloudflare's Zero Trust — meaning I can reach my server's terminal from any browser, anywhere, without a VPN. But that's a story for another post.
Conclusion
If you're running anything self-hosted at home, stop forwarding ports. Cloudflare Tunnel is free, more secure, and honestly easier to maintain. My server hasn't had a single unwanted inbound connection since I made the switch — because there's simply nothing to connect to.