A Python CLI tool for effortless Cloudflare Tunnel management
Project description
Pyflared is a CLI tool for creating and managing Cloudflare Tunnels. No more manual token juggling or complex configurations — just simple commands to expose your local services to the internet. It also works as a Python library!
✨ Features
- 🚀 Quick Tunnels — Spin up instant, temporary public URLs for local services with a single command
- 🔗 DNS-Mapped Tunnels — Create persistent tunnels with automatic DNS record management
- 🧹 Automatic Cleanup — Orphan tunnel and stale DNS record detection & removal
- 🔑 SSH over Cloudflare — Expose and connect to SSH servers through Cloudflare Tunnels
- 🗝️ Token Management — Store and manage multiple Cloudflare API tokens locally
- 📦 Batteries Included — Bundles the
cloudflaredbinary, no separate installation required - 🐳 Docker Ready — Run as a container with minimal setup
📦 Installation
Using uv (Recommended)
uv tool install pyflared
Using pip
pip install pyflared
Using Docker
docker pull ghcr.io/azmainmahatab/pyflared:latest
docker run --rm ghcr.io/azmainmahatab/pyflared --help
🚀 Quick Start
Create a Quick Tunnel
Expose a local service instantly with a temporary trycloudflare.com URL:
pyflared tunnel quick 8000
This creates a public URL (e.g., https://random-name.trycloudflare.com) pointing to localhost:8000.
Create a DNS-Mapped Tunnel
Create a persistent tunnel with your own domain:
pyflared tunnel mapped api.example.com=localhost:8000 web.example.com=localhost:3000
This will:
- Create a new Cloudflare Tunnel
- Configure DNS records for your domains
- Route traffic to your local services
Note: Requires a Cloudflare API token with tunnel and DNS permissions. Set via
CLOUDFLARE_API_TOKENenvironment variable or enter when prompted.
Clean Up Orphan Tunnels
Remove stale tunnels and DNS records left behind by pyflared:
pyflared tunnel cleanup
Expose SSH via Cloudflare
Serve your local SSH daemon through a Cloudflare Tunnel:
pyflared ssh serve ssh.example.com
Connect to it from another machine:
pyflared ssh connect user@ssh.example.com
📖 Usage
pyflared --help
pyflared version
Show the bundled cloudflared version.
pyflared tunnel quick <service>
Create a quick tunnel to a local service with a temporary trycloudflare.com URL.
| Option | Description |
|---|---|
--verbose -v |
Show detailed cloudflared logs |
pyflared tunnel mapped <DOMAIN=SERVICE..>
Create DNS-mapped tunnel(s). See Mapping Format for all supported DOMAIN=SERVICE syntaxes.
| Option | Description |
|---|---|
--tunnel-name -n |
Custom tunnel name (default: auto-generated). See Tunnel Naming Behavior |
--force -f |
Take over DNS from other tunnels even if named |
--verbose -v |
Show detailed cloudflared logs |
pyflared tunnel cleanup
Remove orphan tunnels and DNS records.
| Option | Description |
|---|---|
--all -a |
Delete ALL tunnels and DNS records, not just orphans |
--force -f |
Bypass confirmation prompt when deleting all resources |
--verbose -v |
Show detailed cloudflared logs |
pyflared ssh serve <domain>
Expose local SSH server through a Cloudflare Tunnel.
| Option | Description |
|---|---|
--tunnel-name -n |
Custom tunnel name. See Tunnel Naming Behavior |
--force -f |
Take over DNS from other tunnels even if named |
--verbose -v |
Show detailed cloudflared logs |
pyflared ssh add <hostname>
Add a Cloudflare SSH host entry to your ~/.ssh/config.
pyflared ssh remove <alias>
Remove a previously added SSH config entry.
pyflared ssh connect <user@host> [args]
Connect to a remote host using SSH through Cloudflare. Extra SSH arguments are passed through.
pyflared ssh proxy <hostname>
ProxyCommand helper for use in ~/.ssh/config:
Host myhost
ProxyCommand pyflared ssh proxy %h
pyflared token list
List all stored Cloudflare API tokens.
pyflared token add <name>
Add a new API token (prompts securely for the token value).
pyflared token remove <name>
Remove a stored token by its friendly name.
pyflared token nuke
Remove all stored tokens.
🏷️ Tunnel Naming Behavior
The --tunnel-name / -n flag on tunnel mapped and ssh serve controls the tunnel lifecycle:
Without --tunnel-name (default) |
With --tunnel-name |
|
|---|---|---|
| Lifecycle | Ephemeral — tunnel and DNS records are automatically deleted on shutdown (Ctrl+C) | Persistent — tunnel and DNS records are preserved across runs |
| Next run | A brand-new tunnel is created every time | Reuses the existing tunnel if the same name exists |
| DNS protection | None — DNS records are disposable | Named tunnels protect their DNS records from being claimed by other tunnel setups |
| Force override | N/A | Use --force / -f to override DNS owned by another named tunnel |
Tip: Use unnamed tunnels for development and quick testing. Use named tunnels for long-lived services where you want DNS stability and protection across restarts.
📐 Mapping Format
The DOMAIN=SERVICE pairs used in tunnel mapped support a variety of formats.
Basic
# Port only → inferred as http://localhost:<port>
pyflared tunnel mapped app.com=8000
# Host and port
pyflared tunnel mapped app.com=localhost:3000
# Explicit scheme
pyflared tunnel mapped app.com=http://backend:9000
pyflared tunnel mapped secure.com=https://localhost:443
Path Routing
# Route a subdomain path to a specific backend path
pyflared tunnel mapped app.com/api=localhost:8000
# Port with backend path
pyflared tunnel mapped api.com=8000/v1/api
TCP & SSH
Well-known ports are automatically mapped to the correct protocol:
# SSH (port 22) → ssh://
pyflared tunnel mapped ssh.example.com=22
# PostgreSQL (5432), Redis (6379), MongoDB (27017) → tcp://
pyflared tunnel mapped db.com=5432
pyflared tunnel mapped redis.com=6379
Unix Sockets
pyflared tunnel mapped sock.com=/var/run/app.sock
TLS Verification
| Syntax | Behavior |
|---|---|
https://localhost:443 |
Auto-disables TLS verification (local backend) |
https://backend:443?verify_tls=false |
Explicitly disable TLS verification |
https://localhost?verify_tls=true |
Force TLS verification even for localhost |
https://backend:443?verify_tls=api.internal.com |
Verify against a custom server name |
Special Services
# Cloudflare built-in test page
pyflared tunnel mapped test.com=hello_world
# HTTP status code response
pyflared tunnel mapped app.com=http_status:404
# Bastion mode (SSH browser rendering)
pyflared tunnel mapped bastion.com=bastion
🔧 Configuration
Environment Variables
| Variable | Description |
|---|---|
CLOUDFLARE_API_TOKEN |
Your Cloudflare API token for tunnel management |
API Token Permissions
For DNS-mapped tunnels, your API token needs the following permissions:
- Account > Cloudflare Tunnel > Edit
- Zone > DNS > Edit
❓ Troubleshooting
SSL Handshake Failed (Error 525)
If you see an Error 525 page ("SSL handshake failed") immediately after creating a tunnel, don't worry—this is a temporary issue. Cloudflare's edge network may take a few moments to fully propagate the tunnel configuration.
What to do: Simply wait 1-2 minutes and refresh the page. The error will resolve automatically once the tunnel is fully established.
🛠️ Development
Prerequisites
- Python 3.12+
- Hatch
Setup
git clone https://github.com/AzmainMahatab/pyflared.git
cd pyflared
hatch env create
Running Tests
hatch test
Type Checking
hatch run types:check
Building
hatch build
📄 License
Pyflared is distributed under the terms of the MPL-2.0 license.
🙏 Acknowledgments
- cloudflared — The official Cloudflare Tunnel client
- Typer — CLI framework
Made with ❤️ by Azmain Mahatab
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyflared-0.1.0b7.tar.gz.
File metadata
- Download URL: pyflared-0.1.0b7.tar.gz
- Upload date:
- Size: 53.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fb36444c27ed5b70887b20c498018b1287fe0dadff7bec12acf91e1e1619eba7
|
|
| MD5 |
58fc4e224d262ee794ee5ae28ca7f464
|
|
| BLAKE2b-256 |
6b9bd7d248a3e3b59851825c837b3f747daa3fc415e251342df741b207535fb7
|
Provenance
The following attestation bundles were made for pyflared-0.1.0b7.tar.gz:
Publisher:
cd.yml on AzmainMahatab/pyflared
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyflared-0.1.0b7.tar.gz -
Subject digest:
fb36444c27ed5b70887b20c498018b1287fe0dadff7bec12acf91e1e1619eba7 - Sigstore transparency entry: 1052109154
- Sigstore integration time:
-
Permalink:
AzmainMahatab/pyflared@23e53c4326cafeb012679a8fcf1409db3f4f5a08 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/AzmainMahatab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cd.yml@23e53c4326cafeb012679a8fcf1409db3f4f5a08 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyflared-0.1.0b7-py3-none-win_amd64.whl.
File metadata
- Download URL: pyflared-0.1.0b7-py3-none-win_amd64.whl
- Upload date:
- Size: 18.0 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3339cf942bf0179f23781411265e26558b5b79710f5cf878edef03861b7eee01
|
|
| MD5 |
843749d61883a46cb65e8b61432da521
|
|
| BLAKE2b-256 |
f0c658d9f1e90821bb053672d6526a686ce7c3183c1f869fa7d09376440d804a
|
Provenance
The following attestation bundles were made for pyflared-0.1.0b7-py3-none-win_amd64.whl:
Publisher:
cd.yml on AzmainMahatab/pyflared
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyflared-0.1.0b7-py3-none-win_amd64.whl -
Subject digest:
3339cf942bf0179f23781411265e26558b5b79710f5cf878edef03861b7eee01 - Sigstore transparency entry: 1052109390
- Sigstore integration time:
-
Permalink:
AzmainMahatab/pyflared@23e53c4326cafeb012679a8fcf1409db3f4f5a08 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/AzmainMahatab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cd.yml@23e53c4326cafeb012679a8fcf1409db3f4f5a08 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyflared-0.1.0b7-py3-none-musllinux_1_1_x86_64.whl.
File metadata
- Download URL: pyflared-0.1.0b7-py3-none-musllinux_1_1_x86_64.whl
- Upload date:
- Size: 19.3 MB
- Tags: Python 3, musllinux: musl 1.1+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b940670ddfad8b8c55c6867bee9c8e8ff62029282b5d4c5cd6e5673629532cce
|
|
| MD5 |
f1b45b629269e14a9746519f5c042b54
|
|
| BLAKE2b-256 |
a5f716b1778610189b5429013245eea538faa188aa3e9b2acd3b46c1267ed740
|
Provenance
The following attestation bundles were made for pyflared-0.1.0b7-py3-none-musllinux_1_1_x86_64.whl:
Publisher:
cd.yml on AzmainMahatab/pyflared
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyflared-0.1.0b7-py3-none-musllinux_1_1_x86_64.whl -
Subject digest:
b940670ddfad8b8c55c6867bee9c8e8ff62029282b5d4c5cd6e5673629532cce - Sigstore transparency entry: 1052109489
- Sigstore integration time:
-
Permalink:
AzmainMahatab/pyflared@23e53c4326cafeb012679a8fcf1409db3f4f5a08 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/AzmainMahatab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cd.yml@23e53c4326cafeb012679a8fcf1409db3f4f5a08 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyflared-0.1.0b7-py3-none-musllinux_1_1_aarch64.whl.
File metadata
- Download URL: pyflared-0.1.0b7-py3-none-musllinux_1_1_aarch64.whl
- Upload date:
- Size: 18.0 MB
- Tags: Python 3, musllinux: musl 1.1+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
59e117f7f19984345910516341432bb17d3658c1fc8cb80d3827ebb1f9eb024e
|
|
| MD5 |
bd16479f38dbade78c3944770e38f484
|
|
| BLAKE2b-256 |
0f3b29f57479f645b7f7bb792ed28575e9695c5f4fe88dc86a5759c03bf03a99
|
Provenance
The following attestation bundles were made for pyflared-0.1.0b7-py3-none-musllinux_1_1_aarch64.whl:
Publisher:
cd.yml on AzmainMahatab/pyflared
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyflared-0.1.0b7-py3-none-musllinux_1_1_aarch64.whl -
Subject digest:
59e117f7f19984345910516341432bb17d3658c1fc8cb80d3827ebb1f9eb024e - Sigstore transparency entry: 1052109279
- Sigstore integration time:
-
Permalink:
AzmainMahatab/pyflared@23e53c4326cafeb012679a8fcf1409db3f4f5a08 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/AzmainMahatab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cd.yml@23e53c4326cafeb012679a8fcf1409db3f4f5a08 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyflared-0.1.0b7-py3-none-manylinux_2_17_x86_64.whl.
File metadata
- Download URL: pyflared-0.1.0b7-py3-none-manylinux_2_17_x86_64.whl
- Upload date:
- Size: 19.3 MB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6470595a6467cff4e8bc257d36e2e80d4a95d6aee30b8bc74710a2878d7cc296
|
|
| MD5 |
76c76245c5f05e38ae0bbc3c6d947075
|
|
| BLAKE2b-256 |
45f2beec3a00f82209d8f9d2cdb1fb6d90dcb4bf279c25cf5fcad8256fc18347
|
Provenance
The following attestation bundles were made for pyflared-0.1.0b7-py3-none-manylinux_2_17_x86_64.whl:
Publisher:
cd.yml on AzmainMahatab/pyflared
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyflared-0.1.0b7-py3-none-manylinux_2_17_x86_64.whl -
Subject digest:
6470595a6467cff4e8bc257d36e2e80d4a95d6aee30b8bc74710a2878d7cc296 - Sigstore transparency entry: 1052109540
- Sigstore integration time:
-
Permalink:
AzmainMahatab/pyflared@23e53c4326cafeb012679a8fcf1409db3f4f5a08 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/AzmainMahatab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cd.yml@23e53c4326cafeb012679a8fcf1409db3f4f5a08 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyflared-0.1.0b7-py3-none-manylinux_2_17_aarch64.whl.
File metadata
- Download URL: pyflared-0.1.0b7-py3-none-manylinux_2_17_aarch64.whl
- Upload date:
- Size: 18.0 MB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
920fdec70f812c29a4cbac874bf5f1da2c47f529d833ef48fa82a7e6248ec58b
|
|
| MD5 |
ee12ccb41be862d2134c28c2c165d8b4
|
|
| BLAKE2b-256 |
fa5297f2f11828b7dc860782fe40794311d011d24e7fd54b25eba31a46781e92
|
Provenance
The following attestation bundles were made for pyflared-0.1.0b7-py3-none-manylinux_2_17_aarch64.whl:
Publisher:
cd.yml on AzmainMahatab/pyflared
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyflared-0.1.0b7-py3-none-manylinux_2_17_aarch64.whl -
Subject digest:
920fdec70f812c29a4cbac874bf5f1da2c47f529d833ef48fa82a7e6248ec58b - Sigstore transparency entry: 1052109436
- Sigstore integration time:
-
Permalink:
AzmainMahatab/pyflared@23e53c4326cafeb012679a8fcf1409db3f4f5a08 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/AzmainMahatab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cd.yml@23e53c4326cafeb012679a8fcf1409db3f4f5a08 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyflared-0.1.0b7-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: pyflared-0.1.0b7-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 18.4 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ec51707276bec4fc42f96ff153497e9534576fa605f38d8ddd9caeddb586f88b
|
|
| MD5 |
3e24e26ca8b890e72c67b2b7b5008c30
|
|
| BLAKE2b-256 |
7e4a9a9ebd4728162dc826f1f5faf4a9a84b33280703980a922ed6ee9407be11
|
Provenance
The following attestation bundles were made for pyflared-0.1.0b7-py3-none-macosx_11_0_arm64.whl:
Publisher:
cd.yml on AzmainMahatab/pyflared
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyflared-0.1.0b7-py3-none-macosx_11_0_arm64.whl -
Subject digest:
ec51707276bec4fc42f96ff153497e9534576fa605f38d8ddd9caeddb586f88b - Sigstore transparency entry: 1052109335
- Sigstore integration time:
-
Permalink:
AzmainMahatab/pyflared@23e53c4326cafeb012679a8fcf1409db3f4f5a08 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/AzmainMahatab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cd.yml@23e53c4326cafeb012679a8fcf1409db3f4f5a08 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyflared-0.1.0b7-py3-none-macosx_10_9_x86_64.whl.
File metadata
- Download URL: pyflared-0.1.0b7-py3-none-macosx_10_9_x86_64.whl
- Upload date:
- Size: 20.1 MB
- Tags: Python 3, macOS 10.9+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2325c4a417752c727f246fe101803b96fbb64b64c14a751be051384f1dd3210c
|
|
| MD5 |
986690c22f3cb26321c0157b09f44241
|
|
| BLAKE2b-256 |
ef2c0ae834042c6f0107d45418ac34475d6d02d135ec3233ca8a941964c375d1
|
Provenance
The following attestation bundles were made for pyflared-0.1.0b7-py3-none-macosx_10_9_x86_64.whl:
Publisher:
cd.yml on AzmainMahatab/pyflared
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyflared-0.1.0b7-py3-none-macosx_10_9_x86_64.whl -
Subject digest:
2325c4a417752c727f246fe101803b96fbb64b64c14a751be051384f1dd3210c - Sigstore transparency entry: 1052109199
- Sigstore integration time:
-
Permalink:
AzmainMahatab/pyflared@23e53c4326cafeb012679a8fcf1409db3f4f5a08 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/AzmainMahatab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cd.yml@23e53c4326cafeb012679a8fcf1409db3f4f5a08 -
Trigger Event:
push
-
Statement type: