Skip to main content

Tunnex

Expose local services to the internet through public domains. Supports HTTP/HTTPS, WebSocket, TCP and UDP.

localhost:3000  →  https://my-app.tunnex.org

Features

  • HTTP/HTTPS — proxy web applications with automatic TLS
  • WebSocket — full WS support (HMR, Socket.IO, chats)
  • TCP — tunnels for databases, SSH and any TCP service
  • UDP — tunnels for VoIP, game servers, IoT
  • Web dashboard — live view of requests and TCP/UDP streams, settings management
  • Custom subdomains — your-name.tunnex.org
  • Rate limiting — on both the client and the server
  • Custom response — stub mode with a configurable response
  • Replay — resend HTTP requests from the dashboard

Quick start

Install

pip install tunnex

Run

tunnex --port 3000

Once started:

  • Public URL: https://<subdomain>.tunnex.org
  • Dashboard: http://127.0.0.1:8080

Default server: wss://connect.tunnex.org (override with --server).

CLI options

Option Description Default
--port, -p Local application port — (required)
--dashboard-port, -d Dashboard port 8080
--server, -s Tunnel server URL wss://connect.tunnex.org
--config Path to the client config —

Subcommands

tunnex start --port 3000    # start (default)
tunnex list                 # list registered subdomains

Architecture

┌──────────────┐                    ┌───────────────┐    WebSocket (TLS)    ┌───────────────┐
│  Your app    │◄──────────────────►│ Tunnex client │◄─────────────────────►│ Tunnex server │
│  :3000       │  localhost proxy   │   (Python)    │   encrypted tunnel    │               │
└──────────────┘                    └───────────────┘                       └───────┬───────┘
                                                                                    │ HTTPS/TCP/UDP
                                                                                    ▼
                                                                            ┌───────────────┐
                                                                            │    Users      │
                                                                            │  (internet)   │
                                                                            └───────────────┘

Tech stack

Component Technologies
Server Python 3.10+, FastAPI, Uvicorn, SQLAlchemy, aiosqlite
Client Python 3.10+, websockets, httpx, Click, Rich
Protocol WebSocket + JSON, Base64 for binary data
Deployment Docker, Nginx, GitLab CI/CD
Database SQLite (client), SQLite/PostgreSQL (server)

Dashboard

Local dashboard at http://127.0.0.1:8080:

  • Requests — live list of HTTP requests, filtering by method/status, URL search, headers and bodies
  • Replay — resend a request, optionally with modified parameters
  • TCP — active TCP streams, hex view, send data, close connections
  • UDP — UDP events, packet view (hex/text), send packets
  • Settings — subdomain, local port, rate limit, custom response
  • Status — connection state, public URL, uptime, errors

Updates arrive in real time over WebSocket.

Server deployment

Domain layout

Host Purpose
tunnex.org Landing page (www redirects here)
connect.tunnex.org Control endpoint the client connects to (/tunnel/connect, /api/*)
*.tunnex.org Public tunnels

DNS is hosted on Cloudflare. All records are DNS-only (not proxied): tunnels use raw TCP/UDP ports and second-level wildcards that the Cloudflare proxy cannot serve. Reserved subdomains (www, connect, api, mail, …) cannot be claimed by tunnels.

Bootstrap a fresh host

deploy/bootstrap-server.sh prepares an Ubuntu 24.04 host: installs Docker, Nginx, certbot and ufw, issues a wildcard Let's Encrypt certificate for tunnex.org + *.tunnex.org via the dns-cloudflare plugin, installs deploy/nginx/tunnex.conf and deploy/server-config.yaml, and opens ports 22, 80, 443 and 45000–46000 (TCP/UDP).

CF_API_TOKEN=<token with Zone:DNS:Edit> ./deploy/bootstrap-server.sh root@<host>

Certificates renew automatically via certbot.timer; Nginx is reloaded after renewal.

Docker

The server container is started by CI, equivalent to:

docker run -d \
  --name tunnex-server \
  --restart unless-stopped \
  --network host \
  -v /opt/tunnex/config.yaml:/app/config.yaml:ro \
  -v /opt/tunnex/certs:/app/certs:ro \
  -v /opt/tunnex/data:/app/data \
  -e SERVER_CONFIG=/app/config.yaml \
  registry.gitlab.com/homycoder/tunnex/server:latest

Server requirements

  • Public IP address
  • Domain with a wildcard DNS record (*.example.com)
  • Reverse proxy (Nginx) for TLS termination
  • Open ports: 80, 443, TCP/UDP range 45000–46000

CI/CD (GitLab)

Pipelines

On changes to server_/ or shared/:

  1. Build the Docker image and push it to the GitLab Container Registry
  2. Deploy to the server (pull + restart the container)

On changes to client/, shared/, setup.py:

  1. Bump the version (YY.MM.DD.patch)
  2. Build wheel + sdist
  3. Publish to PyPI

On changes to landing/: rsync to /opt/tunnex/landing on the server.

CI/CD variables

Server deployment (GitLab → Settings → CI/CD → Variables):

  • SSH_PRIVATE_KEY — SSH private key for deployment
  • SSH_USER — server user
  • SERVER_HOST — server address

PyPI publishing:

  • PYPI_USERNAME — __token__
  • PYPI_PASSWORD — PyPI API token

Development

make install-dev       # dev tools (ruff, black, mypy)
make lint              # lint (ruff)
make fmt               # format (black)
make mypy              # type check
make test              # tests
make build-client      # build the client package

Project layout

├── client/            # tunnel client
│   ├── client.py      # CLI (Click)
│   ├── tunnel_client.py  # tunnel logic
│   ├── dashboard.py   # FastAPI dashboard
│   ├── models.py      # SQLAlchemy models
│   └── static/        # dashboard frontend
├── server_/           # tunnel server
│   ├── main.py        # FastAPI + WS + HTTP proxy
│   ├── tunnel_manager.py  # tunnel registry
│   ├── tcp_udp_manager.py # TCP/UDP manager
│   ├── models.py      # SQLAlchemy models
│   └── Dockerfile
├── shared/            # shared code
│   └── protocol.py    # protocol message types
├── landing/           # tunnex.org landing page
├── deploy/            # server bootstrap, Nginx and server config
├── learn/             # step-by-step walkthroughs of the protocol
└── setup.py           # tunnex package

Contact

dev@tunnex.org

License

MIT

Metadata

Release files for tunnex 26.10.9.19

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tunnex 26.10.9.19
File Size Uploaded
tunnex-26.10.9.19.tar.gz 41.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tunnex 26.10.9.19
File Interpreter ABI Platform
tunnex-26.10.9.19-py3-none-any.whl Python 3 none any Details

Total release size: 84.4 kB

Release files / tunnex-26.10.9.19.tar.gz

Download URL tunnex-26.10.9.19.tar.gz
Size 41.4 kB
Tags Source
SHA-256 checksum
How to use checksums
f28bdb4e8f4cebc5c2ecea3ecebf2f18a2390a842bb9e7e5529c01b1a1b7a309
BLAKE2b-256 checksum
How to use checksums
6881a9487e7b24ab82add6599d40339731bed67e0111a1d6b6f427a496515829
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.17

Release files / tunnex-26.10.9.19-py3-none-any.whl

Download URL tunnex-26.10.9.19-py3-none-any.whl
Size 43.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8eb00eb7b1face7a391993ce8f668a418e5ffed33f5fc878b93da3064d450b81
BLAKE2b-256 checksum
How to use checksums
85cfaf08e6b37e76fa4bd08cb679b1666d3739659a1135830c8594fc6d0a848c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.17
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page