# Rathole — Cloudron Package [Rathole](https://github.com/rathole-org/rathole) is a secure, stable and high-performance reverse proxy for NAT traversal (frp/ngrok class, written in Rust). This package runs the **server** side: the Cloudron box is the public-IP endpoint, rathole clients behind NAT dial the control port, and their local services are exposed through token-authenticated tunnels. ## Packaging overview | Aspect | Choice | |--------|--------| | Pattern | Pre-compiled binaries (JOURNAL pattern #5) | | Base image | `cloudron/base:4.0.0` (Ubuntu 22.04) | | Upstream binary | `rathole-x86_64-unknown-linux-gnu.zip`, v0.5.0, sha256-pinned in Dockerfile | | Addons | `localstorage` only (config persistence; no database) | | Auth | No user concept → `httpAuth.type = proxy` (see below) | | Runtime | `start.sh` seeds config, serves status page, execs rathole `--server` | Why pre-compiled: upstream ships release binaries and **dropped the musl builds in v0.5.0** (only `x86_64-unknown-linux-gnu` remains for Linux amd64). The gnu binary is built on ubuntu-latest, so the runtime needs glibc >= 2.35 — hence `cloudron/base:4.0.0` (22.04) instead of the 3.x series (20.04). Compiling from source would need a full Rust toolchain build stage for no benefit. ## Authentication (auth gate verdict: proxy) - Rathole has **no user concept**: no web UI, no accounts, no SSO hooks. - Tunnels are authorized by **mandatory per-service tokens** (a random `default_token` is generated into `/app/data/server.toml` on first start). Transport can additionally be encrypted via Noise or TLS. - The manifest declares `httpAuth: {"type": "proxy"}`: Cloudron's auth proxy gates the HTTP status page, which is the only HTTP surface this app has. The raw TCP tunnel ports cannot be HTTP-gated by design; the token layer is their access control. ## Ports | Port | Type | Purpose | |------|------|---------| | 8000 | `httpPort` | Status/health page (behind Cloudron auth proxy) | | 2333 | `tcpPorts` | Control channel — rathole clients connect here | | 5200–5299 | `tcpPorts` (100-port range) | Tunnel exit ports — one per `[server.services.*]` | With default install settings Cloudron bridges these 1:1 (external 5200-5299 → container 5200-5299). If the admin picks a different `SERVICE_PORT` start value, the *container* ports stay 5200+ and only the external numbering shifts — `server.toml` never needs editing for that. ## Configuration `/app/data/server.toml`, seeded on first run, **hot-reloaded on save** (add/remove services without restarting the app). The seed contains a placeholder `[server.services.example]` on :5200 — rathole rejects a server config with zero services, so keep at least one block. Example service: ```toml [server.services.my_nas_ssh] token = "" bind_addr = "0.0.0.0:5200" ``` Client side (machine behind NAT): ```toml [client] remote_addr = "your-cloudron.example.com:2333" [client.services.my_nas_ssh] token = "" local_addr = "127.0.0.1:22" ``` Then `ssh -p 5200 user@your-cloudron.example.com` reaches the NAS. Knob: `RUST_LOG` (error|warn|info|debug|trace, default `info`) via Cloudron environment settings — see `.env.example`. ## Build & test ```bash docker build --cgroup-parent ukrrs-batch.slice -t rathole-cloudron:test Package-Workspace/Infrastructure/rathole/ docker run --rm --entrypoint /usr/local/bin/rathole rathole-cloudron:test --version ``` ## Files - `Dockerfile` — pinned release download + sha256 gate on cloudron/base:4.0.0 - `CloudronManifest.json` — manifestVersion 2, httpAuth proxy, tcpPorts (control + 100-port service range) - `start.sh` — config seeding, status page, exec rathole server mode - `status.html` — auth-proxied landing/health page - `.env.example` — runtime knobs - `logo.png` — 256x256, padded from upstream wordmark