Skip to main content

A simple Python library to expose local servers using Cloudflare Tunnel

Project description

suxitunnel

A simple Python library to expose your local server to the internet using Cloudflare's infrastructure.

Inspired by localtunnel-py but using Cloudflare's global network for better performance and DDoS protection.

Installation

pip install suxitunnel

Quick Start

from suxitunnel import Tunnel

# Expose local port 8000
tunnel = Tunnel(8000)
print(f"Your URL: {tunnel.url}")

# Keep your app running...
input("Press Enter to close tunnel...")

tunnel.close()

That's it! No configuration, no authentication, no manual setup.

Features

  • 🚀 Zero Configuration - Just pass a port number
  • 🔒 Secure - Uses Cloudflare's infrastructure with DDoS protection
  • 🌍 Global CDN - Fast access from anywhere in the world
  • 📦 Auto-install - Automatically downloads cloudflared if needed
  • 🐍 Simple API - Clean, Pythonic interface

Usage

Basic Usage

from suxitunnel import Tunnel

tunnel = Tunnel(8000)
print(tunnel.url)  # https://random-name.trycloudflare.com

# Your local server is now public!
# Keep tunnel alive...
tunnel.close()  # Close when done

Context Manager (Recommended)

from suxitunnel import Tunnel

with Tunnel(8000) as tunnel:
    print(f"Public URL: {tunnel.url}")
    # Do your work...
    # Tunnel automatically closes when exiting the block

With Flask

from flask import Flask
from suxitunnel import Tunnel
import threading

app = Flask(__name__)

@app.route('/')
def index():
    return "Hello from Flask!"

if __name__ == '__main__':
    # Start tunnel in background
    tunnel = Tunnel(5000)
    print(f"🌐 Public URL: {tunnel.url}")
    
    # Start Flask
    app.run(port=5000)

With FastAPI

from fastapi import FastAPI
from suxitunnel import Tunnel
import uvicorn

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Hello from FastAPI!"}

if __name__ == "__main__":
    # Start tunnel
    tunnel = Tunnel(8000)
    print(f"🌐 Public URL: {tunnel.url}")
    
    # Start FastAPI
    uvicorn.run(app, host="0.0.0.0", port=8000)

Check Tunnel Status

tunnel = Tunnel(8000)

print(tunnel.url)           # Public URL
print(tunnel.is_alive())    # True if tunnel is running
print(tunnel.port)          # 8000
print(tunnel)               # <Tunnel port=8000 url=https://... status=active>

Custom Host

# Tunnel a service running on a different host
tunnel = Tunnel(8000, host="192.168.1.100")

Manual cloudflared Path

# Use specific cloudflared binary
tunnel = Tunnel(8000, cloudflared_path="/usr/local/bin/cloudflared")

Disable Auto-download

# Don't automatically download cloudflared
tunnel = Tunnel(8000, auto_download=False)

API Reference

Tunnel(port, host="localhost", cloudflared_path=None, auto_download=True)

Create a tunnel to expose a local port.

Parameters:

  • port (int): Local port to expose (required)
  • host (str): Local hostname (default: "localhost")
  • cloudflared_path (str): Path to cloudflared binary (auto-detected if None)
  • auto_download (bool): Auto-download cloudflared if not found (default: True)

Attributes:

  • url (str): Public HTTPS URL for the tunnel
  • port (int): Local port being exposed
  • host (str): Local hostname
  • is_alive() (bool): Check if tunnel is running
  • close(): Close the tunnel

Example:

tunnel = Tunnel(8000)
print(tunnel.url)  # https://abc123.trycloudflare.com
tunnel.close()

open_tunnel(port, host="localhost")

Convenience function to create a tunnel.

from suxitunnel import open_tunnel

tunnel = open_tunnel(8000)

How It Works

Technical Overview

This library uses Cloudflare Quick Tunnels (also called TryCloudflare), which:

  1. Creates an outbound HTTP/2 connection from your machine to Cloudflare's edge
  2. No inbound ports are opened on your machine (firewall-friendly!)
  3. No authentication or account required
  4. Traffic is routed through Cloudflare's global network
  5. Automatic HTTPS with valid certificate

Architecture:

Your App (localhost:8000) → cloudflared → Cloudflare Edge → Internet
                             (HTTP/2)     (Global CDN)     (HTTPS)

Cloudflared Binary

The library automatically downloads the cloudflared binary on first use if it's not already installed. The binary is saved to the library's installation directory.

Supported platforms:

  • Linux (x64, ARM64)
  • macOS (x64, ARM64/M1)
  • Windows (x64)

Comparison with Alternatives

Feature suxitunnel localtunnel ngrok
Free tier ✅ Unlimited ✅ Yes ⚠️ Limited
Custom domains ❌ Random ❌ Random 💰 Paid
DDoS protection ✅ Included ❌ No ⚠️ Limited
Global CDN ✅ Yes ❌ No ⚠️ Limited
Auth required ✅ No ✅ No ⚠️ Yes
Connection limits ✅ None ⚠️ Yes ⚠️ Yes
Rate limits ✅ Generous ⚠️ Yes ⚠️ Yes

Limitations

  1. Random URLs: Each tunnel gets a random *.trycloudflare.com URL (no custom domains)
  2. Temporary: Tunnels are meant for development/testing, not production
  3. No persistence: URL changes each time you create a new tunnel
  4. Rate limits: Subject to Cloudflare's fair use policy

For production use with custom domains, see the full cloudflared documentation.

Security Considerations

What This Tunnel Provides

DDoS protection - Cloudflare's network absorbs attacks
HTTPS encryption - Valid SSL certificate included
No exposed ports - Outbound connection only
Firewall-friendly - Works behind NAT/firewalls

What You Still Need

⚠️ Application security - Implement authentication/authorization
⚠️ Input validation - Protect against malicious input
⚠️ Rate limiting - Prevent abuse of your endpoints
⚠️ Access control - Not everyone should access your tunnel

Important: Once your local server is exposed via a tunnel, anyone with the URL can access it. Make sure your application has proper authentication!

Best Practices

# ❌ DON'T: Expose services without authentication
tunnel = Tunnel(8000)  # If port 8000 has no auth, anyone can access it!

# ✅ DO: Use authentication in your application
from flask import Flask, request, abort
from functools import wraps

def require_auth(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        auth = request.headers.get('Authorization')
        if auth != 'Bearer YOUR_SECRET_TOKEN':
            abort(401)
        return f(*args, **kwargs)
    return decorated

@app.route('/api/data')
@require_auth  # Protected!
def get_data():
    return {"data": "sensitive"}

Troubleshooting

"cloudflared not found"

The library should auto-download cloudflared. If it fails:

# Manual install
# macOS
brew install cloudflare/cloudflare/cloudflared

# Linux
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64
chmod +x cloudflared-linux-amd64
sudo mv cloudflared-linux-amd64 /usr/local/bin/cloudflared

# Or disable auto-download and specify path
tunnel = Tunnel(8000, cloudflared_path="/path/to/cloudflared", auto_download=False)

"Tunnel failed to start"

Check that:

  1. Your local service is running: curl http://localhost:8000
  2. The port is not already in use
  3. You have internet connectivity
  4. Firewall allows outbound HTTPS (port 443)

Tunnel URL not appearing

The library waits up to 30 seconds for the URL. If it times out:

  1. Check your internet connection
  2. Verify cloudflared is working: cloudflared --version
  3. Try running manually: cloudflared tunnel --url http://localhost:8000

Random disconnections

Quick Tunnels are designed for temporary use. For stable connections:

  1. Restart the tunnel when disconnected
  2. For production, use authenticated Cloudflare Tunnels with named tunnels
  3. Implement automatic reconnection logic

Examples

See the examples/ directory for complete working examples:

  • basic_example.py - Simplest usage
  • flask_example.py - Flask integration
  • fastapi_example.py - FastAPI integration
  • context_manager.py - Using with context manager
  • multiple_tunnels.py - Running multiple tunnels

Development

# Clone the repo
git clone https://github.com/sadwx/suxitunnel.git
cd suxitunnel

# Install in development mode
pip install -e .

# Run tests
python -m pytest tests/

License

MIT License - see LICENSE file for details.

Related Projects

Credits

This library is a Python wrapper around cloudflared, the official Cloudflare Tunnel client.

Inspired by the simplicity of localtunnel-py.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

suxitunnel-0.1.2.tar.gz (10.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

suxitunnel-0.1.2-py3-none-any.whl (23.4 kB view details)

Uploaded Python 3

File details

Details for the file suxitunnel-0.1.2.tar.gz.

File metadata

  • Download URL: suxitunnel-0.1.2.tar.gz
  • Upload date:
  • Size: 10.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for suxitunnel-0.1.2.tar.gz
Algorithm Hash digest
SHA256 d98db41145d28a9d689bd0a14e4bfd7ca7a538a7106a859670186b09bd4fdeea
MD5 2486a8c37010e16a0f17fbf343e1b025
BLAKE2b-256 2fbdf086fac251283947ada37b54e267c5f270a3bf008664a4dd9ea7892ff1d4

See more details on using hashes here.

Provenance

The following attestation bundles were made for suxitunnel-0.1.2.tar.gz:

Publisher: publish.yml on sadwx/suxitunnel

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file suxitunnel-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: suxitunnel-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 23.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for suxitunnel-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 7e9a537fa4c639adc6c97ae7f8b380f1525082db0c8fd593c40b515187f28eea
MD5 09de8fe89f35bb119c72a1fdd3598f33
BLAKE2b-256 af8d44ee53ad14724497eb49ed1b8587ceaa0bbdbd6d6deaf2fd6dae52b6b8d7

See more details on using hashes here.

Provenance

The following attestation bundles were made for suxitunnel-0.1.2-py3-none-any.whl:

Publisher: publish.yml on sadwx/suxitunnel

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page