Skip to main content

Best Open Source Alternatives to Cloudflare Tunnels 2026

·OSSAlt Team
cloudflare-tunnelsfrpratholeself-hostingnetworkingreverse-proxy2026

TL;DR

Cloudflare Tunnels expose your local services to the internet without opening firewall ports — but they route all your traffic through Cloudflare's infrastructure. If you want the same capability without Cloudflare dependence, the best open source alternatives use a VPS as your public endpoint: frp (Fast Reverse Proxy, 85K stars) for the most features, rathole for the best performance (Rust, ~12K stars), or Chisel for HTTP-proxy-compatible tunnels. All require a VPS with a public IP.

Key Takeaways

  • What Cloudflare Tunnels does: Exposes local services publicly without opening inbound ports
  • Why you'd self-host: No Cloudflare dependency, data privacy, no traffic routing through third parties
  • What you need: A VPS with a public IP acts as your "Cloudflare" — outbound-only tunnel from your local machine to the VPS
  • frp: ~85K stars, Go, MIT — most feature-complete self-hosted tunnel
  • rathole: ~12K stars, Rust — best performance, smallest resource footprint
  • Chisel: ~12K stars, Go — works through HTTP proxies (useful in restricted networks)
  • Use case: Home servers, local dev environments, bypassing CGNAT

How Tunnel Software Works

The pattern is the same for all alternatives:

Internet → VPS (public IP) → Tunnel → Your local machine → Service

Firewall state:
  VPS: inbound port 80/443 open (your "edge")
  Your machine: outbound only (no inbound ports needed)
  Result: home server is publicly accessible without opening home router

This is how Cloudflare Tunnels works: cloudflared on your machine opens outbound-only connections to Cloudflare's edge. Self-hosted versions replace Cloudflare with your own VPS.

You need a VPS with a public IP. Hetzner CX22 at €4.35/month works perfectly.


Comparison

ToolLanguageLicenseStarsProtocolBest For
frpGoApache 2.0~85KTCP/UDP/HTTPMost use cases
ratholeRustApache 2.0~12KTCP/UDPPerformance-critical
ChiselGoMIT~12KTCP over HTTPHTTP proxy environments
WireGuardC/GoMIT~14KUDPFull network access
Cloudflare TunnelsGo (cloudflared)Apache 2.0QUICManaged (Cloudflare infra)

frp: The Most Feature-Complete Alternative

frp (Fast Reverse Proxy) is the most popular self-hosted tunnel with ~85K GitHub stars. It supports TCP, UDP, HTTP, HTTPS, and STCP (secret TCP), with a built-in dashboard and extensive configuration options.

Architecture

Your local machine runs: frpc (client)
Your VPS runs: frps (server)

frpc → connects outbound to frps
frps → receives connections, routes to frpc

Install frp

# Download latest frp on both your VPS and local machine:
# Get version from: github.com/fatedier/frp/releases
FRP_VERSION="0.61.0"
wget https://github.com/fatedier/frp/releases/download/v${FRP_VERSION}/frp_${FRP_VERSION}_linux_amd64.tar.gz
tar xzf frp_${FRP_VERSION}_linux_amd64.tar.gz
cd frp_${FRP_VERSION}_linux_amd64

VPS: Server Config (frps.toml)

# /etc/frp/frps.toml (on your VPS)
bindPort = 7000           # Port frpc connects to
auth.token = "your-strong-secret-token"

# Optional: Web dashboard
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "your-dashboard-password"

# For HTTP/HTTPS tunnels: your VPS domain
vhostHTTPPort = 80
vhostHTTPSPort = 443
# Run frps as systemd service:
sudo cp frps /usr/local/bin/
sudo tee /etc/systemd/system/frps.service <<EOF
[Unit]
Description=frp Server
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/frps -c /etc/frp/frps.toml
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl enable frps
sudo systemctl start frps

Local: Client Config (frpc.toml)

# ~/frp/frpc.toml (on your local machine)
serverAddr = "your-vps-ip"
serverPort = 7000
auth.token = "your-strong-secret-token"

# Expose a local web server on HTTP:
[[proxies]]
name = "myapp-http"
type = "http"
localIP = "127.0.0.1"
localPort = 3000
customDomains = ["app.yourdomain.com"]

# Expose a local HTTPS app:
[[proxies]]
name = "myapp-https"
type = "https"
localIP = "127.0.0.1"
localPort = 3000
customDomains = ["app.yourdomain.com"]

# Expose a raw TCP port (database, SSH, etc.):
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000        # Access via: ssh user@your-vps -p 6000

# Expose a UDP port:
[[proxies]]
name = "game-udp"
type = "udp"
localIP = "127.0.0.1"
localPort = 7000
remotePort = 6001
# Run frpc:
./frpc -c ./frpc.toml

# As a systemd service (Linux) or launchd (macOS):
# See: https://github.com/fatedier/frp#configure-frpc-as-systemd-service

DNS Setup

Point your domain to the VPS:

A  app.yourdomain.com  → your-vps-ip

frps handles routing incoming requests to the correct frpc tunnel via customDomains.


rathole: Best Performance

rathole is a Rust-based tunnel with ~12K GitHub stars. It uses significantly less CPU and memory than frp, making it ideal for high-throughput scenarios or resource-constrained systems.

Key Differences from frp

  • Written in Rust — better performance, lower resource usage
  • No dashboard (simpler, but less visibility)
  • TOML config only — clean and concise
  • Transport options: TCP, TLS, Noise protocol

rathole Setup

Server (server.toml) on VPS:

[server]
bind_addr = "0.0.0.0:2333"    # Client connects here

[server.services.myapp]
token = "your-secret-token"
bind_addr = "0.0.0.0:8080"    # Public-facing port

Client (client.toml) on local machine:

[client]
remote_addr = "your-vps-ip:2333"

[client.services.myapp]
token = "your-secret-token"
local_addr = "127.0.0.1:3000"  # Your local app
# Run:
./rathole server.toml    # On VPS
./rathole client.toml    # On local machine

With TLS (secure tunnel)

# server.toml
[server]
bind_addr = "0.0.0.0:2333"
[server.transport]
type = "tls"
[server.transport.tls]
pkcs12 = "/path/to/server.pfx"
pkcs12_password = "password"

Chisel: HTTP Proxy Compatible

Chisel (~12K stars) creates TCP tunnels over HTTP or HTTPS. Its superpower: it works through corporate HTTP proxies, making it useful when other tunneling tools are blocked.

# Server (VPS):
./chisel server --port 8080 --auth user:pass --reverse

# Client (local machine):
./chisel client --auth user:pass your-vps-ip:8080 R:0.0.0.0:8080:localhost:3000
# R: = reverse tunnel (public port 8080 → local port 3000)

# Multiple tunnels:
./chisel client --auth user:pass your-vps-ip:8080 \
  R:0.0.0.0:80:localhost:3000 \
  R:0.0.0.0:443:localhost:3001

WireGuard: Full Network Access

If you want to access your entire home/office network (not just specific services), WireGuard creates a proper VPN tunnel:

# Your local machine connects to VPS via WireGuard
# Traffic routing: local machine → WireGuard VPN → VPS → internet

# This gives the VPS a route to your local machine's private IP
# Useful for: accessing all LAN devices through the VPS, not just specific ports

See our WireGuard vs OpenVPN guide for full WireGuard setup.


Cloudflare Tunnels: When to Stay

Despite the self-hosting options, Cloudflare Tunnels makes sense when:

  • Free tier is enough: Personal projects, hobby sites — Cloudflare Tunnels is genuinely free for basic use
  • You already use Cloudflare: DNS on Cloudflare + tunnels = zero extra infrastructure cost
  • DDoS protection needed: Cloudflare's edge absorbs attacks before they reach your origin
  • You don't want to manage a VPS: One less server to maintain

The self-hosted alternatives require a VPS (€4.35–$10/month) that you maintain. The trade-off is control and privacy vs. convenience.


Docker Compose for frp Server

If your VPS already runs Docker:

# On your VPS: docker-compose.yml
services:
  frps:
    image: snowdreamtech/frps:latest
    restart: unless-stopped
    volumes:
      - ./frps.toml:/etc/frp/frps.toml:ro
    ports:
      - "7000:7000"    # Client connection port
      - "7500:7500"    # Dashboard
      - "80:80"        # HTTP tunnels
      - "443:443"      # HTTPS tunnels

Decision Guide

Use frp if:
  → You want the most features and documentation
  → You need HTTP/HTTPS subdomain routing
  → A web dashboard for visibility is helpful
  → Multiple local services to expose

Use rathole if:
  → Performance is critical
  → Resource-constrained environment
  → You prefer Rust-based tooling
  → Simpler config is preferred

Use Chisel if:
  → You're behind a corporate HTTP proxy
  → Standard VPN ports are blocked
  → HTTP-wrapped tunneling is required

Use WireGuard if:
  → You need access to your entire local network
  → Multiple devices need access, not just one service
  → A full VPN is more appropriate than a tunnel

Stay on Cloudflare Tunnels if:
  → Already using Cloudflare for DNS
  → Free tier covers your needs
  → No privacy concerns with Cloudflare traffic routing
  → DDoS protection from Cloudflare's edge is valuable

See all open source networking and infrastructure tools at OSSAlt.com/categories/networking.

Comments