CLI reference
This reference reflects the current code in cmd/mytunnel, cmd/mytunneld, and scripts.
mytunnel
Section titled “mytunnel”Top-level usage:
usage: mytunnel <http|ls|stop|rm|doctor> [args]Version:
mytunnel --versionmytunnel -vmytunnel http
Section titled “mytunnel http”Usage:
mytunnel http <local_port> [flags]Starts a tunnel to a local HTTP service.
| Flag | Default | Meaning |
|---|---|---|
--edge <host> | required | SSH destination for the edge. |
--ssh-bin <path> | ssh | SSH binary. |
--no-ssh-mux | false | Disable SSH muxing for short control commands. |
--remote-bin <path> | mytunneld | Remote daemon binary. |
--name <slug> | generated | Requested slug. |
--owner <owner> | local user env | Compatibility only; server ignores it. |
--force | false | Force-replace existing active slug, admin users only. |
--ttl <duration> | daemon default | Requested lease TTL. |
--reconnect | true | Reconnect SSH tunnel when dropped. |
Remote config override flags are also accepted: --db-path, --base-domain, --caddy-admin-url, --caddy-server, --min-port, --max-port, --lease-ttl, --cleanup-interval, --reconcile-interval, --health-timeout, --log-format, and --max-leases-per-owner.
Example:
mytunnel http 3000 --edge mytunnel-edge --base-domain tunnel.example.com --name portalSuccess output:
url: https://portal.tunnel.example.comlease: <id>mytunnel ls
Section titled “mytunnel ls”Usage:
mytunnel ls [flags]Lists leases owned by the SSH user.
Flags:
| Flag | Meaning |
|---|---|
--edge <host> | SSH destination for the edge. |
--json | Emit JSON output. |
| common remote flags | Same remote flags as http. |
Example:
mytunnel ls --edge mytunnel-edge --jsonJSON shape:
[ { "lease_id": "lease_test", "slug": "demo", "host": "demo.tunnel.example.com", "owner": "alice", "edge_bind_port": 21000, "created_at": "2026-05-05T12:00:00Z", "updated_at": "2026-05-05T12:00:00Z", "expires_at": "2026-05-05T12:02:00Z", "state": "active" }]mytunnel stop
Section titled “mytunnel stop”Usage:
mytunnel stop <lease_id|host> [flags]Releases an active lease.
Example:
mytunnel stop lease_test --edge mytunnel-edgeText output:
released lease_test (released-lease_test.invalid)mytunnel rm
Section titled “mytunnel rm”Usage:
mytunnel rm <lease_id|host|slug> [flags]Deletes a lease by ID, host, or slug.
Example:
mytunnel rm portal --edge mytunnel-edge --jsonmytunnel doctor
Section titled “mytunnel doctor”Usage:
mytunnel doctor [flags]Runs edge health and dry-run reconcile checks.
Example:
mytunnel doctor --edge mytunnel-edgemytunnel doctor --edge mytunnel-edge --jsonJSON shape:
{ "status": "ok", "edge": "mytunnel-edge", "checked_at": "2026-05-05T12:00:00Z", "findings": [], "health": { "status": "ok", "checked_at": "2026-05-05T12:00:00Z", "checks": [], "stats": {} }}mytunneld
Section titled “mytunneld”Top-level usage:
usage: mytunneld <serve|ctl> [args]ctl subcommands: allocate, heartbeat, release, delete, list, health, reconcile, statsVersion:
mytunneld --versionmytunneld -vmytunneld serve
Section titled “mytunneld serve”Runs the daemon loop. The systemd unit normally starts this command.
Required:
--base-domain <domain>orMYTUNNEL_BASE_DOMAIN
Config flags:
| Flag | Env key | Default |
|---|---|---|
--db-path | MYTUNNEL_DB_PATH | /var/lib/mytunneld/leases.db |
--base-domain | MYTUNNEL_BASE_DOMAIN | none |
--caddy-admin-url | MYTUNNEL_CADDY_ADMIN_URL | http://127.0.0.1:2019 |
--caddy-server | MYTUNNEL_CADDY_SERVER | srv0 |
--min-port | MYTUNNEL_MIN_PORT | 20000 |
--max-port | MYTUNNEL_MAX_PORT | 29999 |
--lease-ttl | MYTUNNEL_LEASE_TTL | 2m |
--cleanup-interval | MYTUNNEL_CLEANUP_INTERVAL | 30s |
--reconcile-interval | MYTUNNEL_RECONCILE_INTERVAL | 60s |
--health-timeout | MYTUNNEL_HEALTH_TIMEOUT | 5s |
--log-format | MYTUNNEL_LOG_FORMAT | text |
--max-leases-per-owner | MYTUNNEL_MAX_LEASES_PER_OWNER | 5 |
--admin-users | MYTUNNEL_ADMIN_USERS | empty |
mytunneld ctl allocate
Section titled “mytunneld ctl allocate”Usage shape:
mytunneld ctl allocate --local-port 3000 --name portalFlags:
| Flag | Meaning |
|---|---|
--local-port <port> | Required local port metadata. |
--name <slug> | Requested slug. |
--owner <owner> | Ignored; owner is SSH OS user. |
--force | Admin-only active slug takeover. |
--ttl <duration> | Lease TTL. |
Returns a TunnelLease JSON object.
mytunneld ctl heartbeat
Section titled “mytunneld ctl heartbeat”mytunneld ctl heartbeat --lease <lease_id|host> --ttl 2mRefreshes an owner-scoped lease.
mytunneld ctl release
Section titled “mytunneld ctl release”mytunneld ctl release --lease <lease_id|host>Removes the Caddy route and tombstones the lease.
mytunneld ctl delete
Section titled “mytunneld ctl delete”Exactly one of --lease or --slug is required.
mytunneld ctl delete --lease <lease_id|host>mytunneld ctl delete --slug portalmytunneld ctl list
Section titled “mytunneld ctl list”mytunneld ctl listReturns JSON leases owned by the caller.
mytunneld ctl health
Section titled “mytunneld ctl health”mytunneld ctl healthmytunneld ctl health --jsonText output includes one line per check.
mytunneld ctl reconcile
Section titled “mytunneld ctl reconcile”mytunneld ctl reconcile --dry-run --jsonmytunneld ctl reconcile --apply --json--apply and --dry-run are mutually exclusive.
Without either flag, the command reports dry-run mode.
mytunneld ctl stats
Section titled “mytunneld ctl stats”mytunneld ctl statsmytunneld ctl stats --jsonStats include cleanup and reconcile counters plus last-run timestamps when available.
Script reference
Section titled “Script reference”| Script | Mutates host | Purpose |
|---|---|---|
scripts/install-edge.sh | yes | apt-based edge install with optional Infomaniak Caddy bootstrap. |
scripts/bootstrap-edge.sh | yes | Install daemon binary, env file, data dir, and systemd service. |
scripts/install-edge-ssh-key.sh | yes | Install forced-command SSH key for a tunnel user. |
scripts/install-local.sh | yes | Install client binary to /usr/local/bin/mytunnel. |
scripts/install-client.sh | yes | Compatibility wrapper around install-local.sh. |
scripts/check-edge.sh | no | Read-only edge diagnostics. |
scripts/check-client.sh | no | Read-only client diagnostics. |
scripts/upgrade-edge.sh | yes | Edge binary upgrade with backup, verification, and rollback. |
scripts/upgrade-local.sh | yes | Client binary upgrade. |
scripts/uninstall-edge.sh | yes | Remove edge service/binary/config, optionally data. Supports dry-run. |
scripts/uninstall-local.sh | yes | Remove local client binary. Supports dry-run. |
scripts/test-ssh-gate.sh | no | Test forced-command gate behavior locally. |
scripts/real-system-validation.sh | yes on test lease | End-to-end tunnel validation against a real edge. |
Error codes
Section titled “Error codes”mytunneld writes JSON error envelopes to stderr:
{ "error_code": "permission_denied", "message": "permission denied", "details": {}}Known codes:
| Code | Meaning |
|---|---|
lease_not_found | Lease ID, host, or slug did not resolve. |
slug_in_use | Active lease already owns the slug. |
lease_limit_exceeded | Owner reached MYTUNNEL_MAX_LEASES_PER_OWNER. |
no_available_port | No bind port is available in the configured edge range. |
permission_denied | Caller does not own the lease or is not privileged for --force. |
edge_unreachable | Edge health failed. |
caddy_unreachable | Caddy Admin API failed. |
reconcile_failed | One or more reconcile apply actions failed. |
internal_error | Unmapped error. |