Skip to content

podssh v1.1.0-beta.2

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 04 Nov 18:47
· 386 commits to main since this release

podssh v1.1.0-beta.2

The second beta of milestone M10: the relay as a role of podssh itself
(podssh relay serve) and the net of a user's own nodes grow by many
parts, and the default list of relay hosts takes a rank that this host
measured. A beta is a prerelease. Its tag never moves: a defect found in it
goes into the next beta.

What to test again

The relay role, podssh relay serve:

  • A proxy that refuses the WebSocket upgrade: the HTTP road carries the
    session in plain requests, where a probe found the upgrade refused
    (T-319, its first part; Q44).
  • HTTP/2: a host's sessions of one process are streams of one TLS
    connection, the WebSocket over extended CONNECT (RFC 8441), with
    HTTP/1.1's upgrade where the server does not offer it; PODSSH_H2
    chooses, doctor names the ALPN (T-321, its first part).
  • A cleartext road on port 443, tried after the TLS road fails (T-326).
  • A standard sshd's session across a drop of the client's link: podssh proxy and podssh ssh take the role's road in the resumable layer where
    the first host offers it, its offer kept for a day; PODSSH_RELAY_LAYER=yes
    reads the offer at each run and says each case, no turns the road off;
    --resume-budget, --resume-deadline and --resume-host bound and name
    it (T-173). On that road, the end of podssh proxy's stdin stops sending
    and keeps receiving until the target closes, as on the contract's road; a
    relay host that the user named, whose offer is not kept, costs the session
    one read of 1 s at most, once a day.
  • A connect token for each leg of a session, and a stop token that the node
    rotates (T-615); a pair that its owner renews in the role (T-592).
  • A planned stop that no session feels (T-255); a bound on what waits for a
    slow reader (T-336); the role's dials through the host's HTTPS_PROXY
    (T-457); its mint for the members of the net (T-455); its IPv6 targets,
    and doctor's line ipv6 (T-253).
  • Relay hosts outside the default domain from a list of deployments that a
    trusted key signs (T-346).
  • podssh doctor --stream: what the path does to a stream (T-325).
  • A name that the role does not dial (it does not resolve, or resolves to
    an address that is not public, or has none of the family asked for) gets
    one 403 that names no address; the role's line keeps the cause (T-628,
    GitHub #126).

The net and its nodes:

  • podssh net invite and podssh net join: a new device joins the net by
    a short code (T-616); pairing by a short one-time code given out of band
    (T-086); grants that are signed and used once (T-226, GitHub #35).
  • Routes: a node reaches its private networks for the net, --exit auto
    picks the exit whose routes hold the target, and an exit never dials its
    own addresses (T-432).
  • ssh, proxy and pipe take --exit beside --carrier (T-614,
    GitHub #124), the exit over a carrier (T-596), and podssh doctor --exit NAME (T-458).
  • --no-resume, a session to a node that ends with its link (T-612);
    --timeout and PODSSH_TIMEOUT on operator, proxy and pipe
    (T-613).
  • A copy to a node races the roads that podssh ssh races (T-551); the
    quick tunnel's node takes its net's members as its door (T-550);
    OpenTunnel's road at the node and the client (T-530, T-531).
  • A client's lost link during a node's bulk costs the node's other sessions
    no backoff (T-421).

Relay selection:

  • podssh relay rank measures each relay host from this host and keeps the
    rank (T-606); the default list takes it, with the samples of each race
    (T-607); RelayRank auto ranks in a session's background, at most once a
    day for each egress (T-608, Q89); relay info says that the pool's order
    is the relay's (T-610, GitHub #125), names podssh relay rank, and says
    the order that a run from this host takes (T-618).
  • A relay member of the net names its host, and each end of the net takes
    the role's signed list with no --relay-host (T-617); podssh ping NAME
    races a node's roads and says each one's time, podssh status --net lists
    each member, and doctor has the sections net and carriers (T-435).

Repairs:

  • An ECDSA key of P-256 whose scalar OpenSSH writes in 31 bytes is read
    (T-609); a roost on a host with no sshd says so, and doctor has a line
    for a roost (T-590, GitHub #116); doctor's diagnosis of the TLS
    handshakes counts the resolvers of DNS over HTTPS and n0's relays
    (T-604); on WARP's road, the end of a stream waits for the bytes that the
    far side has not acknowledged yet, so a large echo no longer stalls
    (T-599).
  • podssh pipe -v says, for each direction, when its input ended and how
    the other side took the shutdown (T-465).

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.1.0-beta.2; 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.1.0-beta.2 (the commit of the tag)

podssh update --version v1.1.0-beta.2 from v1.1.0-beta.1 or v1.0.1
takes it, checked by its signature; a build of a release follows releases
alone, so without --version it stays on v1.0.1. The provenance and the
signature are checked as for v1.0.0 (its notes),
with T=v1.1.0-beta.2.

How it was checked

By the operator's ruling Q88 (2026-11-03), until podssh is stable: the gate
green at the tag's commit, the release workflow by hand on it, and the short
form of its binary (scripts/release-short.sh BINARY --net); after the tag,
release-proofs.yml and update-live.yml. The whole release check and the
live runs of each road wait until then.

What a beta does not have yet

  • The whole check of a release from end to end with no human
    (scripts/release-check.sh, T-251): it waits (Q88).
  • Signatures of the platforms: the Mac binaries are not signed with an
    Apple Developer ID, and the Windows binaries carry no Authenticode
    signature, so SmartScreen may warn. The proofs above stand in for them.

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

Other

  • T-561: done, WARP's road tries the record's endpoint, then the API's peers (GitHub #108) (c5299c2)
  • GitHub #108 closed: T-561 done (c5299c2); warp-live.yml dispatched for its live step (365dbd1)
  • T-562: done, WARP's API by its routes in turn (GitHub #109); T-561's live run read and its step repaired (cde307f)
  • T-564: done, podssh raises its soft limit of open files at start, within the hard one (GitHub #111) (5b643b1)
  • T-489: done, chat --listen --linger stays for each peer after its stdin ended (GitHub #102) (ea2a70b)
  • WARP live at cde307f (run 41597035711): T-561's turn proved, T-562's second API name registers a device; GitHub #102, #109 and #111 closed (36d1f31)
  • T-483: done, http-listen: takes ssh:HOPS with no target, and pipe --help shows the proxy of an SSH server (GitHub #93) (7417676)
  • GitHub #93 closed: T-483 done (7417676) (5ff6809)
  • T-488: done, podssh mcp offers cp, job, health and session as tools, behind the gate of ssh_exec (GitHub #101) (f8eaeb4)
  • GitHub #101 closed: T-488 done (f8eaeb4) (9694d0c)
  • Drafts: T-561, T-562, T-564, T-489, T-483 and T-488 merged and closed; their worktrees removed (477b47c)
  • T-599: the stack's driver polls at once for packets in that smoltcp left while the queue out was full (partial: the loop under load runs) (02ece60)
  • T-590: done, a roost that the loopback refuses says whether this host has an sshd, and doctor's line sshd (GitHub #116); the manual's notes repaired; release-proofs reach a beta by --version (279a283)
  • GitHub #116 closed: T-590 done (279a283) (0d0c22c)
  • T-474: done, cp copies several files at once with no --parallel, 4 by default (GitHub #100) (f55c61d)
  • v1.1.0-beta.1 recorded under T-446 (partial: v1.1.0 waits for M10): published at 5d95e5f, update-live and proofs green; GitHub #100 closed (f55c61d) (15819f9)
  • Repair CI: T-488's tests on Windows and a write path with .., and T-564's line after mv's notice (14da1eb)
  • T-472: done, cp, mv and run say what they did in one summary line, and a long copy writes a plain line in a pipe (GitHub #90) (2e3dcec)
  • T-481: done, a host with no tmux is told the command that installs it, and job --no-tmux runs a job under nohup (GitHub #91) (f093299)
  • T-485: done, job log --follow gives a job's output as it comes, on one connection, then exits with its status (GitHub #96) (b7080bd)
  • T-587: done, podssh proxy node://NAME is the pipe of podssh operator NAME, the ProxyCommand form of a node (GitHub #113) (6887d97)
  • Repair CI: cp_get's operand on Windows (T-488) and mv --jsonl's summary in the interop (T-472) (2697813)
  • T-589: done, operator, proxy and pipe take --ConnectTimeout, a bound of their own on reaching the far end (GitHub #115) (801e346)
  • T-591: done, relay status reads an operator's file on a host that stores no pair, and relay pair says the way past the expiry (GitHub #117) (a4344a7)
  • T-595 (partial, first step): a carrier of the node's road on a stream that exists already, node --carrier and operator --carrier (GitHub #124) (38f424c)
  • Repair CI: the exit test reads T-587's refusal of --client-key (00266ad)
  • T-600: done, a resume that comes before the first link's task carries its session waits for it, and no longer ends the session (ac1ed74)
  • T-601: done, a node's serve that is dropped takes its socket with it; T-602 filed (38b5c47)
  • T-597: done, Dependabot's updates: the build image's new digest (rustc 1.99.1), Python 3.15 for the box's proxy, sha2 0.11.1; simple-dns 0.13 waits for iroh-dns (637daa9)
  • T-603 (partial): job log --follow tells a reader that went away from a write that failed, and its test names what the far end held (97327ef)
  • T-602: done, the relay role takes an operator's first frame after ready as the session's, and its test of 2 MiB keeps a window (2fae47e)
  • T-473: done, cp and mv take --no-clobber, --update and --backup with --suffix (GitHub #95) (7131713)
  • Repair CI: the test of a held lock waits a moment for its release, as a child that another test forks holds it (0383dd4)
  • T-482: done, health --preflight says what the far server allows from one login (GitHub #92); GitHub #95 closed (a92c2dd)
  • T-511: done, doctor runs its sections at once, --jobs N and DoctorJobs limit them, --quick checks the host, the egress and the relay alone; GitHub #92 closed (0d3b3a7)
  • Repair CI: T-473's tests of a dry run read the local name in this system's form (777b2b0)
  • T-487: done, doctor keeps the kind of each cut, makes a reference handshake with github.com, and says once after the counts what the TLS handshakes show (GitHub #99); T-604 filed (4cd833e)
  • T-508: done, scp and sftp take --timeout as a bound that is never required (Q72); GitHub #99 closed (fe224ea)
  • T-510: done, edit --no-terminal runs an editor that needs no terminal, within --timeout, and a kept copy names its directory (c674aa2)
  • T-594: done, docs/STATUS.md says that it reads main and names the newest release, and each row of work after v1.0.0 names the first release that holds it (GitHub #121) (c2c4f94)
  • T-512: done, the help and the manual say what the report of 2026-11-02 found by trial; GitHub #121 closed (d7e472c)
  • T-533: done, the manual names the public services that podssh tries when the user named none, and the kinds it never names (8e60436)
  • T-603: done, job log --follow reads once more after the job's status, so its last bytes are given (9e6fac3)
  • T-595: done, ssh, cp, mv, scp, sftp, proxy and pipe reach a node over a carrier, a stream that exists already (GitHub #124) (b02d8c4)
  • Record: the 148 citations that b02d8c4 left unmoved (5b3451b)
  • T-609, T-599, T-604 done; T-610 filed (GitHub #125) (5296e21)
  • Record: the operator's rulings Q89 to Q92, each asked on its own (ff77d9e)
  • T-475: done, run --dry-run and --no-ignore, and the paths that the excludes left out (GitHub #103) (535893e)
  • Record: GitHub #103 closed (T-475) (26e87a4)
  • T-484: done, each --json and each --result-file, each host's status, failure and streams in one object (GitHub #94) (8c2776b)
  • T-486: done, --result-file for cp, mv, scp, run and sftp, in the schema of ssh --result-file (GitHub #97) (096c2c1)
  • Record: GitHub #94 and #97 closed (T-484, T-486) (0efbbcf)
  • Secrets: allow the encrypted test keys of vendor/ssh-key and the research draft's made-up proxy URL (b3471c2)
  • T-530: partial, OpenTunnel, a blind TLS tunnel with no account, as a carrier of the reverse road (69df297)
  • T-530 done, T-531 partial: OpenTunnel's road at the node and at the client (54b124b)
  • T-592 done, T-531 done: a pair renewed in podssh's relay role; OpenTunnel's road live (5c14126)
  • T-596 done: the exit over a carrier, podssh node --exit --carrier and podssh exit --listen --carrier (aa31421)
  • Merge the research of the operator's relay archive: T-605 to T-608; T-605 partial (09f0c0d)
  • Secrets: allow the made-up proxy URL of the relay harness's self-test, as merged into main (f59db11)
  • Repair the chat test that failed at random in the gate; remove the duplicated rows of STATUS (9502aed)
  • T-605: the relay harness's workflow by hand, and its stage dest and roads measured (d629249)
  • T-610 done: relay info says that the pool's order is the relay's, from the edge that answered (GitHub #125) (2516f32)
  • T-605 done: the relay harness's run from GitHub's network, 37 hosts in 2 rounds (d06c5f5)
  • T-606 done: podssh relay rank, each relay host measured from this host and the rank kept (e892246)
  • T-614 done: ssh, proxy and pipe take --exit beside --carrier, the exit at the stream's other end (GitHub #124) (e0a2496)
  • T-612 done: --no-resume, a session to a node that ends with its link (5f0165b)
  • T-613 done: --timeout and PODSSH_TIMEOUT, other names of --ConnectTimeout on operator, proxy and pipe (a29abfc)
  • T-455 done: the relay role mints for the members of the net (--mint net, relay:NODE and relay:*) (3c30ce2)
  • T-457 done: the relay role dials its targets through the host's HTTPS_PROXY, by each checked address (63fe406)
  • Repair the gate: the interop check of relay info reads the pool's new line (T-610) (5f79906)
  • T-607 done: the default list of relay hosts takes the rank, and the samples of each race (11295ef)
  • Repair the gate: a closed port stays held, and Windows names the proxy by https_proxy (d262613)
  • T-336 done: podssh's relay role bounds what waits for a slow reader (8c2d59e)
  • T-336's record: the backpressure test has 3 tests, and the role's lib 34 (d947f9f)
  • T-550 done: the quick tunnel's node takes its net's members as its door (36fa5aa)
  • T-253 partial: the relay role refuses an IPv6 target that its host cannot route, and ssh takes the direct road after a relay that reached no IPv6 host (5d0db76)
  • PROGRESS: the fifth round of drafts, and where each waits (3c18f21)
  • T-226 done: grants used once, signed OpenSSH certificates in the place of a bearer token (1397310)
  • T-255 done: a planned stop of the relay role that no session feels, and a node that comes back at once (8e1f03c)
  • T-325 done: podssh doctor --stream measures what the path does to a stream, and the relay role serves the probes (a797b78)
  • Repair T-325's test: the default relay by its constant, not a second literal (4de7e71)
  • T-608 done: a rank in a session's background, with RelayRank auto alone (Q89) (6060558)
  • Repair the job secrets: T-325's made-up URL at n.example is allowed, by its commits (990981e)
  • T-253 done: doctor's line ipv6, through the relay and direct (6a62cdc)
  • T-421 done: a client's lost link during a node's bulk costs the node's other sessions no backoff (6e4539b)
  • T-458 done: podssh doctor --exit NAME, the exit, its verdict and the road that reached it (a3d698c)
  • T-326 done: a cleartext road on port 443, probed after the TLS road fails (Q45) (fddabaa)
  • T-319 partial: the HTTP road, for a proxy that refuses the WebSocket upgrade (Q44) (e6ff19d)
  • T-173 partial: the relay role's forward road in the resumable layer, for a standard sshd (2ef9566)
  • T-551 done: a copy to a node races the roads that podssh ssh races, not the pair's road alone (14b7943)
  • T-086 done: pairing by a short one-time code, given out of band (1ca77a1)
  • T-432 done: the net's routes, --exit auto, and an exit's own host (2b5dbba)
  • Repair the gate: T-086's help row, a dead fn without code, a Linux test on macOS; T-608's tie (7a70e6c)
  • T-616 done: podssh net invite and net join, a new device in the net by a short code (dbde47e)
  • T-346 done: relay hosts outside the default domain from a signed list of deployments (5ed6a51)
  • Repair the gate at dbde47e: net_invite is Linux's; T-465's test says where the bytes stopped (9c80274)
  • suite-repeat.yml runs on Windows too, with the gate's NASM step (T-465) (e5eb6cf)
  • T-173 partial: podssh ssh on the role's resumable road, each process named, a budget and a deadline (537a156)
  • T-321 partial: the WebSocket over HTTP/2's extended CONNECT (RFC 8441), client and role (53f3dbc)
  • T-615 done: a connect token for each leg of a session, and a stop token that the node rotates (1f47e11)
  • Triage: the export of GitHub #125 (deleted): known, but for T-618 and T-619 (a39d625)
  • Repair the gate at 537a156: the signed list's tests remove their cache directories (11d2561)
  • Move the citation of T-610's line in T-618, which the note of T-346 moved (ef92b3f)
  • T-465: podssh pipe -v says where each direction's input ended (d7e4985)
  • Research: the forward carriers of the operator's ff-relay archive (2026-11-04) (41fdac2)
  • T-173: its live run passed: 48 MiB each way through 6 resumes, by OpenSSH's client and podssh ssh (366f511)
  • v1.1.0-beta.2 made ready (T-446): the version 1.1.0-beta.2 and the notes (22da36c)
  • T-173 done: the resumable layer by default where the first relay host offers it; two tests that read T-321's http2 line; T-465's words timed; T-627 filed (501999f)
  • T-435 done: status, ping and doctor for the net (57faf83)
  • T-465: a probe of Windows' AF_UNIX end of input, beside podssh's road; the repeat workflow runs ignored tests (a6f3351)
  • T-617 done: the net's document names each relay member's host, for its signed list (00ba332)
  • T-173: the layer's end of stdin keeps receiving; the read of an offer before the session waits 1 s; T-465's probe found no loss (3988c8c)
  • T-618 and T-619 done: relay info names relay rank and the order that a run takes; the note to the relay's operator asks for a rank that two calls can compare (b750af3)
  • T-620 done: a node's stop token rotates and its pair renews at the next pair it goes on with; the session's checkpoint (4623638)
  • The record: a citation of TODO/PROGRESS.md moved with the checkpoint above it (909e4f5)
  • The operator's rulings of 2026-11-04 (Q93 to Q100); the scan of secrets lists each test key of the vendored copies (2042200)
  • T-628 done: the relay role answers each name that it does not dial with one 403 that names no address (GitHub #126) (45a3447)
  • The record: GitHub #126 closed with T-628 (45a3447) (d7debd3)
  • v1.1.0-beta.2's notes name T-628 (GitHub #126) (dbd0fac)