Repository navigation
podssh v1.0.1
The repairs of the defects that the testers of v1.0.0 found (GitHub #83 to
#111, and the report of the operator's testing agents of 2026-11-02), with the
work of milestone M10 that main holds since v1.0.0: podssh's own relay
role, the net of an owner's nodes, and more roads. Its tag never moves: a
defect found in it goes into the next release.
The repairs
- SSH to a server of Go's x/crypto/ssh: a reply to a keepalive or to
-R
that carries data no longer ends the connection (T-460, #83, #85). podssh sshexits 255, not the far command's status, when the link ends
after the status and before the output's end (T-461, #84).- A
-Jhop whose channel opens and carries nothing is named, within
ConnectTimeout (T-462, #86). - A connection that ends right after the login is no longer read as a
refused session; a refusal gives OpenSSH's words of its reason (T-464,
#104). sftp'slsgives OpenSSH's long form, and its switches act (T-471, #89).cp --deltasays why it sends a whole file, and makes the temporary file
by one command where the server has nocopy-data(T-470, #87).cp -rsays each failure once, and a device, FIFO or socket is a skip with
exit 0, not 66 (T-476, #105).healthgives a container's CPUs and memory from its cgroup beside the
host's (T-480, #88).- The login name comes from the user database when
USER,LOGNAMEand
USERNAMEare unset (T-500). --suends su's read when its password cannot be given (T-501).-o ProxyCommand=nonegoes past a file'sProxyCommand, and the first
value of a file holds (T-502).- Each host that is dialed,
-J's hops among them, is checked before
anything connects, on each road (T-503). eachrefuses a blank that would part two hosts of the command line (T-504).- The keywords of a restriction (
Ciphers,MACs,KexAlgorithms,
HostKeyAlgorithms,PubkeyAcceptedAlgorithms,CASignatureAlgorithms,
RequiredRSASize) apply (T-505). session listanddetached listsay on stderr that none is there, and
take--json(T-506).updatenames the move of the kept file as the way back, and--rollback
only for a release that has it (T-507).- The fallback to other products' forwarders follows only a failure where no
relay host answered about the target (T-509, #106). - The relay's record keeps a host that opens, rests one cut short twice, and
keeps each road apart (T-563, #110). - WARP's road proves a packet through its tunnel before it is open (T-560,
#107). - A warning before the relay's idle cut, and
--idle-warn SECONDS(T-463,
#98).
The files
| File | For |
|---|---|
podssh-x86_64-unknown-linux-musl |
Linux on x86-64, static: no library and no loader needed |
podssh-aarch64-unknown-linux-musl |
Linux on aarch64, static |
podssh-armv7-unknown-linux-musleabihf |
Linux on 32-bit ARM with hard float, static |
podssh-riscv64gc-unknown-linux-musl |
Linux on 64-bit RISC-V, static |
podssh-aarch64-apple-darwin |
macOS on Apple silicon; it links the system's libraries only |
podssh-x86_64-apple-darwin |
macOS on Intel |
podssh-x86_64-pc-windows-msvc.exe |
Windows on x86-64, with a static C runtime |
podssh-aarch64-pc-windows-msvc.exe |
Windows on ARM64, with a static C runtime |
SHA256SUMS |
The SHA-256 of each binary |
SHA256SUMS.sigstore.json |
The signature of SHA256SUMS: Sigstore's keyless signing, by the release workflow at this tag |
provenance.sigstore.json |
The provenance of each binary (SLSA), signed the same way: the workflow, the tag and its commit |
THIRD-PARTY-LICENSES.md |
The licenses of the crates in the binaries, with their texts |
Check a download
T=v1.0.1; B=podssh-x86_64-unknown-linux-musl # or another file of the table
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/$B"
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/SHA256SUMS"
grep " $B\$" SHA256SUMS | sha256sum -c - && chmod +x "$B"
./"$B" --version # podssh 1.0.1 (the commit of the tag)podssh update from v1.0.0 takes it, checked by its signature. The
provenance and the signature are checked as for v1.0.0
(its notes),
with T=v1.0.1.
The sizes
The sizes of the release's dry run of 2026-11-03 (at 3bb42ea, the code of this tag: the commits
after it change tests and the record alone, run 41563962586), beside v1.0.0's published files.
They grew with the work of M10 that main holds: podssh's relay role, the net of nodes, and the
new roads.
| Binary | v1.0.0 | v1.0.1 |
|---|---|---|
| Linux x86-64 | 15.7 MiB | 17.2 MiB |
| Linux aarch64 | 12.1 MiB | 13.2 MiB |
| Linux armv7 | 9.1 MiB | 10.0 MiB |
| Linux riscv64 | 12.1 MiB | 13.3 MiB |
| macOS, Apple silicon | 9.5 MiB | 10.4 MiB |
| macOS, Intel | 12.6 MiB | 13.9 MiB |
| Windows x86-64 | 12.3 MiB | 13.6 MiB |
| Windows ARM64 | 10.8 MiB | 11.9 MiB |
How it was checked
As v1.0.0: the release check of T-251 (scripts/release-check.sh) ran before the tag on the
release's dry run and a build of its own, and runs again on the published files, the checksums,
the signature of SHA256SUMS and the provenance of each binary first; then the README's first
steps, doctor, proxy and ssh through the live relay, the reverse road with two sessions at
once, cp of 200 MiB each way through a node, pipe, the iroh road through n0's relays, the
static binary in a fresh container and in a box like the target sandbox, the Tailscale runs
against headscale, the throughput run, IRC against ngircd, and the planted defect of each check.
GitHub's runners ran the rest: Windows and macOS, the box, WARP's road, Cloudflare's edge, the
public forwarders, DNS over HTTPS, a node as a unit of systemd, podssh update, 200 MiB each way
through a node with its moves, and the servers of the repairs: Go's x/crypto/ssh, wstunnel, the
via forwarders, and containers of cgroup limits for health. docs/STATUS.md, "The release
check", holds the table of each run.
What is not in it
As in v1.0.0: the entries that wait for the relay's operator, the work that
the operator holds (Q32), the imports of T-328, the live runs of T-376, the
outside services that turn the relay's address away, the platforms'
signatures, and Tailscale and the Tor road, which need their features.
Report a defect
Open an issue at https://github.com/Azathothas/podssh/issues with the
output of podssh --version and podssh doctor --json. Read that output
before you post it: it names this host's proxy and addresses, and never a
token or a password.
The licenses of the crates in the binaries, with their texts: THIRD-PARTY-LICENSES.md.
The commits of this release
Build and CI
- CI: the gate red since 0b6fcdb: the net tests remove their scratch directories; the DERP stand-in registers a client before its answer (a2c418e)
- CI: the gate red at b76548c: the keyed mint's unit tests remove their scratch directories (60b3070)
- CI: allow the draft of T-460's russh test keys; exit-live meets GitHub's key with no global file (94be1bb)
Other
- T-251: done, the whole release check before the tag of v1.0.0 passed at 35a0d19 (80a6407)
- Q63 to Q66: milestone M10, the mesh at parity with Tailscale and the relay as a role of podssh; v1.0.0 tagged (6b6174f)
- M10: the Corrections of the 15 entries that waited for the relay's operator; relay-operator.md and carriers.md for Q63 to Q65 (d8cc0d6)
- T-169: podssh relay serve, the relay's forward road served by podssh itself (partial: the live run on a runner closes it); T-447, T-448 filed (00197d5)
- T-169: the citations of the files that its commit changed, moved against its parent (cargo todo remap --base HEAD~1) (2d847e8)
- T-443, T-444: the layer's window on the pair's road under the relay's bound; one TLS configuration for each trust, so that TLS resumes; T-449 filed; the relay role's Date header (bd4c576)
- T-439 (partial): --via, HTTP CONNECT to a second proxy over TLS, HTTP/1.1 and HTTP/2; the run against Caddy and squid follows in Actions (a253c8a)
- T-169: done, its live run on a runner passed; tls_resume removes its scratch directories (the gate's libs step at bd4c576) (8899450)
- T-436: the magic-wormhole transit relay as a carrier of a pair's road (Q65); T-450 filed (84eb45e)
- T-439 (partial): via-interop's first run failed on its script: Caddy is built as xcaddy builds it, each proxy must answer TLS, banners keep stdin open (5b62f4e)
- T-439: done, via-interop.yml passed against Caddy and squid (12 of 12) (95563f1)
- T-437: the Piping Server road (Q65) for a proxy that refuses the WebSocket upgrade; T-451 filed (b4817cb)
- T-438: Wisp: the protocol's client,
wisp+wss://forwarders, and the demo server as a fallback (Q65) (f22efab) - T-429: the net: an owner's signed list of its nodes, and their names; T-452 and T-453 filed (0b6fcdb)
- record: a citation of AGENTS.md's sentence of exit code 70 follows its two new lines (fd4cbbe)
- T-427: the relay's reverse road in podssh's relay role; the transit relay takes the host's trust; T-454 filed (d5a700b)
- T-448: the relay role mints tokens, and makes pairs, for the keys of a list; T-455 filed (b76548c)
- T-440 (partial): VLESS over a WebSocket and over XHTTP on HTTP/2, in place of the relay; Q67 and T-456 filed (33ccb11)
- T-441 (partial): wstunnel's protocol, --wstunnel URL in place of the relay, its secret in a 0600 file (e077220)
- T-440 (partial): its interop's first run: Xray-core blackholes a private target unless a final rule allows it (28cba8a)
- T-449 (partial): suite-repeat.yml, a suite run after run on a runner, each failure counted by its test's name (aca3a35)
- T-430: the net's policy: who may reach which node, route, exit and range, checked at the node (f85ced1)
- T-440 and T-441: done, each interop passed against its servers' own projects (f8d15bf)
- T-428 (partial): the relay role behind a node's quick tunnel, with no listener; T-457 filed (1a38dfa)
- T-449: done, the relay suite's test that failed at random is named, repaired and held 50 runs (168eedb)
- Triage of GitHub #83 to #105, a tester's issues of v1.0.0: T-460 to T-464, T-470 to T-476, T-480 to T-489 (cf4d7ce)
- T-465 filed: pipe's unix-connect test waited past its 10 s once on macOS; suite-repeat.yml takes a runner, a test and a filter (7316e18)
- T-447: podssh relay serve reads its certificate again on SIGHUP, and takes one from ACME by TLS-ALPN-01 (37e0fe5)
- T-428 (partial): quick-tunnel-live.yml waits until the tunnel's name answers before the old client (da323a3)
- T-465: suite-repeat.yml's features default to none, as an empty input takes its default (01e371e)
- T-454: the relay role brakes /v1/mint and /v1/pair for each address (2ba9e5c)
- T-465: 50 runs of pipe on macOS passed; the test says podssh's stderr at its limit (67a233f)
- T-428: the relay role behind a quick tunnel passed live through Cloudflare's edge (413f4c7)
- The testers' entries wait for the operator's go-ahead (2eb994a)
- T-431 (partial): exit mode, a node's egress for its net (0b07025)
- flags.rs: the verbs by purpose in flags/groups.rs, as T-431's verb took it to 501 lines (23a40b4)
- The operator's rulings Q67 to Q84, and the triages of the bundle, #106 and the relay sweep (239058c)
- T-442: done, the research of more public services and protocols; T-490 to T-499 filed (582b1bf)
- T-445: a node's record of pkarr names each of its roads, and a member's client races them (27029ee)
- The operator's rulings Q85 to Q87: the testers' features go too, overnight forks are decided and listed, v1.0.1 goes out unattended (0a3726f)
- Triage of GitHub #107 to #111: T-560 to T-564 (WARP's road and registration, the relay's record, the open-file limit) (373ac6c)
- settings: allow each shell command by an explicit wildcard rule too (244f0d6)
- T-452: a DERP node whose key is a member of the net starts with no --allow, the net's members its whole door (a88524b)
- The record keeps a deleted issue: #15 to #17 and #28 to #36 are gone from GitHub (e25b870)
- T-431: done, exit mode passed live from GitHub Actions (exit-live.yml, run 41479877820) (7f860e0)
- T-453: podssh cp and podssh sftp reach a member of the net by its name alone (2dd2056)
- plants: t155, t289 and t430 made again for today's code (6c69078)
- Entries for the rulings Q74, Q75, Q77, Q78 and Q82: T-534 to T-549 and T-565 to T-582 (1769d79)
- T-460 (partial): a reply to a global request that carries data no longer ends the connection (b026d58)
- secrets: allow russh 0.65.0's own test keys, vendored again by T-460 (8d0f909)
- T-461: a link that ends after the exit status and before the output's end exits 255, not that status (5b2468a)
- T-462: a -J hop's channel opens within ConnectTimeout, and a silent one names the hop (f460dcf)
- T-464: a connection that ends right after the login is no refused session (772275c)
- T-463: a warning before the relay's idle cut, and --idle-warn SECONDS (b39a29d)
- T-461 to T-464: the whole suites of podssh-cli and podssh-ssh at their merge (7f31fef)
- GitHub #84, #86, #98 and #104 closed: T-461 to T-464 are done (1211458)
- T-471: sftp's ls as OpenSSH's, its long form and its switches (57fd523)
- T-470: cp --delta says why it sends the whole file, and copies the old file by a command (9679787)
- T-460: done, Go's x/crypto/ssh 8 of 8 in Actions and its plants caught; GitHub #83 and #85 closed (e1fe6c1)
- T-476: cp -r says each failure once, and a device, FIFO or socket is a skip, not a failure (a383ce9)
- GitHub #87, #89 and #105 closed: T-470, T-471 and T-476 are done (daae0d4)
- T-500: the login name from PODSSH_USER, the variables, then the user database (Q68) (eabd3bc)
- T-501: --su ends su's read when its password cannot be given (48347dc)
- T-503: one rule for the host names of each road, checked before anything connects (b3e49f9)
- T-502: the first ProxyCommand holds, so -o ProxyCommand=none goes past a file's (aab4a21)
- T-505: the keywords of a restriction apply, and the others are said (02c30ed)
- T-504: each refuses a blank that would part two hosts of the command line (2ae75a7)
- T-509: the fallback to other products' forwarders follows only a failure where no relay host answered about the target (Q69) (b32ecef)
- T-480 (partial): health reads the cgroup of its shell, and gives a container's CPUs and memory beside the host's (0ce6745)
- T-506: session list and detached list say on stderr that none is there; a session that does not answer is listed no-answer; --json for both (43a8aa5)
- T-507: update names the move of the kept file as the way back, and --rollback only for a release that has it (21209d5)
- T-503: the whole suite of podssh-cli at the merge of T-500 to T-509: 1448 passed (a003af3)
- GitHub #106 closed: T-509 is done (2c8ecdc)
- T-560 (partial): WARP's road proves a packet through the tunnel before it is open (12520f2)
- T-563: the relay's record keeps a host that opens, rests one cut short twice, and keeps each road apart (7abebd2)
- plants: t147 and t503 made again for today's code (5b369be)
- T-480: done, cgroup-interop.yml 5 of 5 against containers of the limits; GitHub #88 and #110 closed (9d3f401)
- T-480: its Done names the run of cgroup-interop.yml that closed it (2b7ecbe)
- T-584 filed: publish v1.0.1, the repairs of the testers' defects (Q87) (c726d16)
- T-560: done, warp-live.yml passed each step with the probe answered; T-585 filed (df4f1b4)
- v1.0.1 made ready (T-584): the version 1.0.1, the README's install line, and the notes (3bb42ea)
- T-465: 50 more runs of pipe on macOS passed (run 41560477021), 100 in a row (8a4c9f2)
- T-501: the ssh-pty plants on a runner, run 41560470075: 5 caught, 0 missed (f542a13)
- T-309: v1.0.0-beta.4's publication in its Done; T-584: the issues after #111 go into the next release (2246fd7)
- T-585: a Correction, the same certificate through the box's proxy at 3bb42ea (warp-live run 41563996906) (371d485)
- Triage of GitHub #112 to #124: T-586 to T-597 filed, verified against the code (e176606)
- T-563: the three fault tests that lean on the list's order each take an empty record; v1.0.1's notes: the sizes and how it was checked (90182bf)
- T-227: the stuck write's file is larger than the host's TCP buffers; the drafts of T-586, T-588 and T-593 wait (26459cd)
- T-250: done, v1.0.0's published files pass the release check (43 passed, 6 skipped); T-598 filed (9cc1372)
- Plants t430, t431 and t453 install Python and openssl in the build image (8b9e7d8)
- T-430, T-431, T-453: their plants caught in the build image once they install Python (3 caught, 0 missed) (6ece1f9)