- Rust 83.3%
- Shell 13.6%
- Go 2.4%
- Dockerfile 0.4%
- PowerShell 0.3%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .forgejo/workflows | ||
| crates/portal-relay | ||
| docs | ||
| fixtures/go | ||
| helpers/portal-ivnp-helper | ||
| scripts | ||
| .dockerignore | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| docker-compose.yml | ||
| Dockerfile | ||
| README.md | ||
portal-tunnel-rs
A lightweight Rust port of the portal-tunnel relay-server.
This source tree targets upstream portal-tunnel v2.6.4 and is released as v2.6.4+rs.1, the current production release. The exact published image passed the public live gate on the reference deployment with the official v2.6.4, v2.6.3, and v2.6.1 clients: native raw reverse transport, browser/WASM WebSocket/yamux, keyless tenant TLS, and direct fallback for clients that request --overlay. The reference deployment runs with IVNP overlay disabled, so overlay is shipped but not live-verified and is not offered there. Not every upstream feature is implemented — see docs/unsupported-features.md for the evidence boundaries and support matrix. For the release-cycle workflow, see docs/RELEASE.md.
Quick start
Published images are linux/arm64 only. The latest image is the current
production release (v2.6.4+rs.1).
docker pull code.rly.best/gofix/portal-tunnel-rs:latest
docker run --rm --cap-add=NET_ADMIN --cap-add=NET_BIND_SERVICE \
-p 4017:4017 -p 443:443 \
code.rly.best/gofix/portal-tunnel-rs:latest
A reference docker-compose.yml with persistent cert volume is included in this repo. Native source builds are supported on Linux and macOS. Windows has direct-only cross-compile coverage; IVNP is unavailable there because its authenticated helper transport requires Unix-domain sockets.
Configuration
All settings are configured through environment variables (or the equivalent --flag form). Run portal-relay --help to see the full list.
Protocol-10 tunnel / protocol-9 discovery IVNP overlay support is enabled by
setting DISCOVERY=true and IVNP_CONFIG=/path/to/ivnp.json. The file is
decoded as the upstream RouterConfig of the IVNP revision pinned by upstream
v2.6.0; fields added by the newer revision that v2.6.1 pins are not accepted
yet, and unknown or malformed fields fail startup. Published
container images bundle the pinned IVNP helper used by the Rust relay. Source
builds that enable IVNP must also build helpers/portal-ivnp-helper and set
IVNP_HELPER if it is not installed at /usr/local/bin/portal-ivnp-helper.
The helper is a trusted relay component, not a distinct-UID or filesystem
privilege boundary. The relay clears its inherited environment, gives it only
the IVNP config path and a private control socket, and maintains a stdin EOF
parent-liveness contract. Operators that want separate lifecycle/filesystem
policy can supervise the helper as a sidecar and set IVNP_HELPER_SOCKET to
its absolute Unix socket path; the external helper remains operator-trusted.
Without IVNP_CONFIG, direct protocol-10 sessions and the retained v2.3.8
compatibility paths continue to operate as before.
The bundled Compose file propagates proxy trust, IVNP, and HTTP redirect
settings from the host environment. It also exposes the upstream v2.5.1
PREAUTH_* source/global admission budgets. Static relay caching is not
implemented; CACHE_ENABLED=true fails startup instead of being ignored.
IVNP_CONFIG must name a path visible
inside the container (add a read-only config-file mount when enabling it);
IVNP_HELPER defaults to the helper bundled at
/usr/local/bin/portal-ivnp-helper.
Release tags
Production tags are exactly v<upstream>+rs.<N> and tagged dev builds are
exactly v<upstream>+rs.<N>-dev.<M>, where both counters are positive
integers. The upstream core must equal workspace.package.version. Container
images replace + with -, and only an exact production tag updates
latest. Only promoted production tags are listed below.
v2.1.8+rs.1→ first stable Rust build for upstreamv2.1.8v2.1.9+rs.1→ first build retargeted at upstreamv2.1.9v2.2.0+rs.1→ first build retargeted at upstreamv2.2.0v2.2.1+rs.1→ first build retargeted at upstreamv2.2.1v2.2.2+rs.1→ first build retargeted at upstreamv2.2.2v2.2.3+rs.1→ first build retargeted at upstreamv2.2.3v2.2.4+rs.1→ first build retargeted at upstreamv2.2.4v2.2.5+rs.1→ first build retargeted at upstreamv2.2.5v2.3.0+rs.1→ first build retargeted at upstreamv2.3.0v2.3.1+rs.1→ first build retargeted at upstreamv2.3.1v2.3.2+rs.1→ first build retargeted at upstreamv2.3.2v2.3.3+rs.1→ first build retargeted at upstreamv2.3.3v2.3.5+rs.1→ first build retargeted at upstreamv2.3.5v2.3.6+rs.1→ first build retargeted at upstreamv2.3.6v2.3.7+rs.1→ first build retargeted at upstreamv2.3.7v2.3.8+rs.1→ first build retargeted at upstreamv2.3.8v2.4.0+rs.1→ first build retargeted at upstreamv2.4.0v2.4.1+rs.1→ first build retargeted at upstreamv2.4.1v2.4.2+rs.1→ first build retargeted at upstreamv2.4.2v2.4.3+rs.1→ first build retargeted at upstreamv2.4.3v2.5.0+rs.1→ first build retargeted at upstreamv2.5.0v2.6.0+rs.1→ first build retargeted at upstreamv2.6.0v2.6.1+rs.1→ first build retargeted at upstreamv2.6.1v2.6.3+rs.1→ first build retargeted at upstreamv2.6.3(includes v2.6.2)v2.6.4+rs.1→ first build retargeted at upstreamv2.6.4; current production
Development tags were published for v2.5.1, but no v2.5.1+rs.1 production
tag was promoted.
Pick the tag whose upstream component matches the portal-tunnel version your clients expect.