From DuckDNS to Cloudflare Tunnel: Why I Stopped Port Forwarding

personNikos calendar_today schedule6 min read
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.