Skip to main content

Cloudflare Tunnels

Expose your local services to the internet without port forwarding or firewall configuration. Get a public URL instantly using Cloudflare's infrastructure.

What are Cloudflare Tunnels?

Simple Explanation: Cloudflare Tunnels create a secure connection from your local machine to Cloudflare's edge network, giving you a public URL that anyone can access—without opening ports or configuring routers.

Analogy:

Traditional (Complex):
Your Service → Router config → Firewall rules → Port forwarding → Public IP
↑ Many steps, security risks

Cloudflare Tunnels (Simple):
Your Service → Cloudflare Tunnel → Public URL
↑ One step, secure by default

How It Works

Architecture

┌──────────────────────────────────────────────────────┐
│ Your Computer │
├──────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────────────┐ │
│ │ Local Service│◄─────┤ cloudflared │ │
│ │ (Port 3000) │ │ (Xermius managed) │ │
│ └──────────────┘ └──────────┬───────────┘ │
│ │ │
└────────────────────────────────────┼────────────────┘

Encrypted Tunnel
(Outbound only)


┌────────────────────────────┐
│ Cloudflare Edge Network │
│ │
│ Public URL Generated: │
│ https://abc-123.trycloudflare.com │
└────────────┬───────────────┘


┌────────────────┐
│ Internet Users │
│ Access via URL │
└────────────────┘

Key Points:

  • ✅ Only outbound connections (secure)
  • ✅ No port forwarding needed
  • ✅ No firewall changes required
  • ✅ Encrypted by default
  • ✅ Works behind NAT/corporate firewalls

Why Use Cloudflare Tunnels?

1. Zero Configuration

No setup needed:

Traditional:
1. Configure router
2. Set up port forwarding
3. Configure firewall
4. Get static IP (or use DynDNS)
5. Configure SSL certificate
Total: 30-60 minutes

Cloudflare Tunnels:
1. Click "Start Tunnel"
Total: 5 seconds

2. Instant Public URLs

Get URL immediately:

Start tunnel → Get URL in seconds

Example:
https://brilliant-mountain-2f3d.trycloudflare.com

- Always HTTPS
- Works instantly
- No DNS setup
- Free to use

3. Works Anywhere

Behind any network:

✓ Home network (behind router)
✓ Corporate network (strict firewall)
✓ Public WiFi (no access to router)
✓ Mobile hotspot
✓ VPN connection
✓ Docker container

4. Perfect for Development

Common dev scenarios:

✓ Demo work to clients
✓ Test webhooks locally
✓ Share dev environment
✓ Mobile device testing
✓ External API testing
✓ Quick prototyping

Use Cases

1. Webhook Testing

Test webhook integration:

Local Server: http://localhost:3000/webhook
Cloudflare URL: https://abc-123.trycloudflare.com/webhook

Give Cloudflare URL to webhook provider
Receive webhooks on local machine
Debug in real-time

Perfect for:

  • Stripe webhooks
  • GitHub webhooks
  • Payment gateways
  • Third-party integrations

2. Client Demos

Show work in progress:

You: Working on localhost
Client: In different location

Share Cloudflare URL → Client sees live site
Make changes → Refreshes and sees updates
No deployment needed

3. Mobile Testing

Test on real devices:

Desktop: Running dev server (localhost:3000)
Phone: Can't access localhost

Solution:
Start Cloudflare Tunnel
→ https://xyz-789.trycloudflare.com
Access on phone
Test on real device

4. Team Collaboration

Share local environment:

Your machine: Running feature branch
Teammate: Wants to test

Share tunnel URL
Teammate tests immediately
No push, no deploy, no setup

5. External API Testing

Test from external services:

Your API: http://localhost:8080/api
External service: Can't reach localhost

Start tunnel
→ https://api-test-123.trycloudflare.com/api
External service can now reach your API
Test integration locally

6. IoT Development

Test IoT device webhooks:

IoT device: Sends data to webhook
Your webhook: Running locally

Start tunnel
Configure device with public URL
Receive data locally
Debug and test

Types of Tunnels

Standard Tunnel

General purpose tunneling:

┌────────────────────────────────────┐
│ Standard Cloudflare Tunnel │
├────────────────────────────────────┤
│ Local Port: 3000 │
│ Public URL: Auto-generated │
│ Type: HTTP/HTTPS │
│ Use: Any web service │
└────────────────────────────────────┘

Features:

  • Tunnel to any local port
  • Automatic HTTPS
  • Random public URL
  • Works with any HTTP service

Best for:

  • Development servers
  • APIs
  • Web applications
  • Client demos

Request Debugger

Special tunnel for webhook debugging:

┌────────────────────────────────────┐
│ Request Debugger Tunnel │
├────────────────────────────────────┤
│ Built-in server: Yes │
│ Logs requests: Yes │
│ Public URL: Auto-generated │
│ Inspect: Full details │
└────────────────────────────────────┘

Features:

  • Built-in HTTP server
  • Logs all incoming requests
  • View headers, body, query params
  • No local service needed
  • Perfect for webhook testing

Best for:

  • Webhook development
  • API integration testing
  • Understanding third-party requests
  • Debugging external calls

Quick Start

1. Install cloudflared

First time setup:

Xermius will prompt:
"cloudflared not found. Install it?"
→ Click "Install"
→ Automatically installs
→ Ready to use

Or install manually: Setup Guide

2. Create Tunnel

Standard tunnel:

1. Go to "Cloudflare Tunnels" tab
2. Click "New Tunnel"
3. Fill in:
Name: My Dev Server
Local Port: 3000
4. Click "Create"
5. Click "Start"
6. Get public URL!

Request debugger:

1. Go to "Cloudflare Tunnels" tab
2. Click "New Tunnel" → "Request Debugger"
3. Fill in:
Name: Webhook Testing
4. Click "Create"
5. Click "Start"
6. Get public URL + request logging!

3. Share URL

Copy public URL:
https://brilliant-mountain-2f3d.trycloudflare.com

Share with:
- Clients
- Teammates
- Webhook providers
- Testing services
- Mobile devices

Anyone with URL can access!

Features

Auto-Start

Start tunnel automatically:

Settings:
[✓] Auto-start with Xermius
Tunnel starts when app launches

Perfect for:
- Always-running services
- Development workflows
- Daily use

Request Logging

For Request Debugger tunnels:

View all incoming requests:
- Timestamp
- Method (GET, POST, etc.)
- Path
- Headers
- Query parameters
- Request body
- Response status

Perfect for debugging!

Multiple Tunnels

Run many at once:

Tunnel 1: Frontend (port 3000)
Tunnel 2: Backend API (port 8080)
Tunnel 3: Webhook Debugger
Tunnel 4: Mobile Preview (port 3001)

All running simultaneously
Each with unique URL

Status Monitoring

Real-time status:

● Active - Running and accessible
◐ Starting - Connecting to Cloudflare
○ Inactive - Stopped
✗ Error - Problem occurred

Click tunnel to see:
- Public URL
- Local port
- Uptime
- Status
- Logs (for debugger)

Security Considerations

What's Exposed

What is accessible:

✓ Anything on specified port
✓ All paths (/, /api, /admin, etc.)
✓ All HTTP methods (GET, POST, etc.)

If your service has:
http://localhost:3000/
http://localhost:3000/admin
http://localhost:3000/api/secret

Then public URL exposes:
https://xyz.trycloudflare.com/
https://xyz.trycloudflare.com/admin
https://xyz.trycloudflare.com/api/secret

⚠️ Important: Entire service is exposed!

Security Best Practices

1. Add Authentication

// Add auth to your local service
app.use((req, res, next) => {
const token = req.headers['authorization'];
if (token !== 'your-secret-token') {
return res.status(401).send('Unauthorized');
}
next();
});

2. Use Environment Variables

// Don't hardcode secrets
const API_KEY = process.env.API_KEY;

// Rotate secrets regularly
// Don't commit to git

3. Temporary Tunnels

Start when needed
Stop when done
Don't leave running
Delete old tunnels

4. Rate Limiting

// Add rate limiting
const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per window
});

app.use(limiter);

5. Monitor Access

Check logs regularly
Watch for unusual activity
Note unexpected requests
Investigate suspicious patterns

6. Secure Sensitive Endpoints

// Protect admin routes
app.use('/admin', requireAuth);

// Validate webhooks
app.post('/webhook', validateWebhookSignature);

What's Protected

Cloudflare provides:

✓ DDoS protection
✓ SSL/TLS encryption
✓ Automatic HTTPS
✓ No exposed IP address

You must provide:

✓ Application authentication
✓ API key validation
✓ Rate limiting
✓ Input validation

Limitations

Free Tunnels (trycloudflare.com)

Limitations:

  • URL Changes: New URL each time you start
  • No Custom Domains: Can't use your domain
  • No Permanence: Tunnel stops when app closes
  • Rate Limits: Cloudflare may rate limit
  • No SLA: Best effort service

Good for:

  • Development
  • Testing
  • Demos
  • Temporary sharing

Not good for:

  • Production use
  • Permanent services
  • Business critical apps

For permanent tunnels:

Use Cloudflare Zero Trust
- Custom domains
- Permanent tunnels
- Access control
- Analytics
- SLA

Configure via:
cloudflare.com/zero-trust/

Xermius supports:

  • Quick tunnels (free)
  • Testing and development
  • Temporary sharing

Comparison with Alternatives

vs ngrok

Cloudflare Tunnels:

✓ Free
✓ Unlimited tunnels
✓ No account needed
✓ Fast setup
✗ URL changes each time
✗ Less features

ngrok:

✓ Fixed URLs (paid)
✓ More features
✓ Custom domains (paid)
✗ Account required
✗ Free tier limited
✗ Paid for multiple tunnels

vs Port Forwarding

Cloudflare Tunnels:

✓ Works anywhere
✓ No router access needed
✓ Instant setup
✓ Automatic HTTPS
✗ URL not memorable
✗ Not permanent

Port Forwarding:

✓ Your own domain
✓ Permanent
✓ Full control
✗ Router config needed
✗ Firewall setup
✗ Static IP helpful
✗ Manual SSL

vs VPS Proxy

Cloudflare Tunnels:

✓ Free
✓ No server needed
✓ Instant
✓ No maintenance
✗ Limited control
✗ URL not custom

VPS Proxy:

✓ Full control
✓ Custom domain
✓ Permanent
✗ Costs money
✗ Server setup
✗ Maintenance needed

Tips & Tricks

1. Save Common Tunnels

Create reusable tunnels:
"Frontend Dev" → Port 3000
"Backend API" → Port 8080
"Mobile Preview" → Port 3001

Start with one click
No need to recreate

2. Use Descriptive Names

Good names:
✓ "Client Demo - Homepage"
✓ "Stripe Webhook Test"
✓ "Mobile App API"

Bad names:
✗ "Tunnel 1"
✗ "Test"
✗ "abc"

3. Stop When Not Needed

Tunnels use resources:
- Computer resources
- Cloudflare resources
- Expose your service

Stop when done
Start when needed

4. Test Before Sharing

Before sending URL to client:
1. Start tunnel
2. Test URL yourself
3. Check all pages work
4. Verify no errors
5. Then share

5. Document URLs

Keep track:
Tunnel: Client Demo
URL: https://xyz-123.trycloudflare.com
Purpose: Show new feature
Started: Jan 17, 2PM
Share with: John Smith

6. Use Request Debugger for Webhooks

When testing webhooks:
1. Use Request Debugger (not standard tunnel)
2. View full request details
3. See headers, body
4. Debug issues easily
5. No need for local server

Troubleshooting

Tunnel Won't Start

Error: Tunnel fails to start

Solutions:

1. Check cloudflared installed:
Settings → Check Installation

2. Check port is available:
lsof -i :3000 # Mac/Linux
netstat -ano | findstr :3000 # Windows

3. Check service is running:
curl http://localhost:3000

4. Check logs:
Tunnel details → View Logs

Can't Access Public URL

Error: URL doesn't work

Solutions:

1. Check tunnel status: Active?

2. Test locally first:
curl http://localhost:PORT
Must work locally first

3. Check firewall/antivirus:
May block cloudflared

4. Restart tunnel:
Stop → Start

URL Changed

Issue: URL different from before

This is normal!

Free tunnels get new URL each time
Solution:
- Use paid Cloudflare Zero Trust
- Or accept changing URLs
- Document current URL

Next Steps