Get the client binaries.
Download the macOS Apple Silicon or Linux amd64 ZIP, install the single binary, then connect approved TCP and UDP services through HTTPS.
Unzip, make executable, move into PATH.
The archive contains the ZelTunnel binary. After installation, use the commands from the main page to start a local or reverse tunnel.
unzip zeltunnel-macos-arm64.zip chmod +x zeltunnel sudo mv zeltunnel /usr/local/bin/ zeltunnel --help
unzip zeltunnel-linux-amd64.zip chmod +x zeltunnel sudo mv zeltunnel /usr/local/bin/ zeltunnel --help
Prepare the tunnel endpoint.
Generate the certificate, create a hashed token, and start the ZelTunnel server with a policy file that defines exactly which targets are allowed.
# Generate a development certificate zeltunnel cert generate \ --out certs \ --server-name tunnel.rocheston.com # Hash the user token before placing it in config zeltunnel token hash MY_SECRET_TOKEN
zeltunnel server \ --config examples/server.yml # Recommended public endpoint https://tunnel.rocheston.com
Run ZelTunnel server in a container.
Use Docker when you want the tunnel endpoint deployed as a repeatable service with mounted config and certificates. Expose TCP/443 for WSS and UDP/443 when QUIC transport is enabled.
# Pull published image from Docker Hub docker pull rocheston/zeltunnel:latest # Run server with mounted config and certs docker run --rm --name zeltunnel \ -p 443:443/tcp \ -p 443:443/udp \ -v $(pwd)/examples/server.yml:/etc/zeltunnel/server.yml:ro \ -v $(pwd)/certs:/etc/zeltunnel/certs:ro \ rocheston/zeltunnel:latest \ zeltunnel server --config /etc/zeltunnel/server.yml
services: zeltunnel: image: rocheston/zeltunnel:latest container_name: zeltunnel restart: unless-stopped ports: - "443:443/tcp" - "443:443/udp" volumes: - ./examples/server.yml:/etc/zeltunnel/server.yml:ro - ./certs:/etc/zeltunnel/certs:ro command: - zeltunnel - server - --config - /etc/zeltunnel/server.yml
docker compose up -d docker compose logs -f zeltunnel docker compose down
Run local and reverse tunnels.
Local forwarding lets the user connect to localhost. Reverse forwarding lets a protected machine connect outward and expose an approved remote listener.
zeltunnel connect \ --server https://tunnel.rocheston.com \ --token MY_SECRET_TOKEN \ --listen 127.0.0.1:3390 \ --target 2.3.3.3:3389 \ --protocol any \ --transport auto # Open Remote Desktop to: 127.0.0.1:3390
zeltunnel reverse \ --server https://tunnel.rocheston.com \ --token MY_SECRET_TOKEN \ --remote-listen 0.0.0.0:3390 \ --target 127.0.0.1:3389 \ --protocol any
zeltunnel client --config examples/client.yml
Keep access narrow by default.
The server policy should define allowed targets per token. ZelTunnel should not become an open proxy by accident.
auth: tokens: - id: "support-user" token_sha256: "...hashed-token..." allowed_targets: - "2.3.3.3:3389" - "10.0.0.0/8:22" security: allow_open_proxy: false allow_public_bind_default: false
server: "https://tunnel.rocheston.com" token: "MY_SECRET_TOKEN" tunnels: - name: "rdp" listen: "127.0.0.1:3390" target: "2.3.3.3:3389" protocol: "any" transport: "auto"
From download to protected service access.
This is the practical sequence for getting a user connected without exposing broad network access.
Download
Choose the macOS or Linux ZIP and install the binary into PATH.
Provision
Create a scoped token and policy entry for the exact target service.
Connect
Run the local or reverse tunnel command with protocol and transport settings.
Audit
Review auth events, byte counts, health checks, and policy decisions.
What administrators should remember.
ZelTunnel is built for precise service access. The safest deployment keeps targets explicit, tokens short-lived, and public binds controlled.
Firewall view
Client networks see HTTPS to tunnel.rocheston.com, not direct RDP, SSH, database, or DNS ports.
Transport auto
Use WSS as the reliable baseline and QUIC where UDP/443 is available.
Public binds
Require explicit approval before exposing listeners beyond localhost or approved interfaces.
No payload logs
Audit metadata should cover access, timing, targets, and byte counts, not user payload contents.
Revocation
Disable tokens server-side to cut off access without touching the user application.
Agentic layer
Metrics and health data can feed policy agents for provisioning, anomaly detection, and self-healing.
Common checks when a tunnel does not connect.
Most failures come from token mismatch, policy denial, blocked network path, or a target service that is not reachable from the server.
Authentication fails
- 1Confirm the user token matches the hashed token in server config.
- 2Check clock, expiry, and token revocation status.
- 3Review auth failure counters in metrics.
Target does not respond
- 1Verify the target host and port are reachable from the ZelTunnel server.
- 2Confirm the target is listed in the token ACL.
- 3Check whether TCP, UDP, or protocol any is required.
Connect a protected service.
Use an approved token and target from your administrator. The local app connects to localhost while ZelTunnel carries traffic through the HTTPS tunnel.
RDP
Bind 127.0.0.1:3390, then open Remote Desktop to that local address.
SSH
Bind a local port and point your SSH client at localhost.
Database
Forward only the approved database host and port instead of exposing a subnet.