Skip to content

podnet v0.4.0-beta.4

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 11 Nov 21:59
· 73 commits to main since this release

A prerelease of podnet, for tests. It follows v0.4.0-beta.3.

A user of cfrs reads the notes of v0.4.0-beta.1 first. They give the
rename and the move from cfrs.

Binaries

File System
podnet-x86_64-unknown-linux-musl Linux x86-64
podnet-aarch64-unknown-linux-musl Linux ARM64
podnet-armv7-unknown-linux-musleabihf Linux ARMv7 (32-bit, hard float)
podnet-arm-unknown-linux-musleabihf Linux ARMv6 (32-bit, hard float)
podnet-i686-unknown-linux-musl Linux x86 (32-bit)
podnet-riscv64gc-unknown-linux-musl Linux RISC-V 64
podnet-loongarch64-unknown-linux-musl Linux LoongArch64
podnet-powerpc64le-unknown-linux-musl Linux POWER, little-endian

Each binary is static (musl). It needs no C library on the host.
podnet.1 is the manual page. llms.txt and llms-full.txt are the
manual and the documents as plain text (T-222). SHA256SUMS lists each
file.

The image is ghcr.io/podutils/podnet:v0.4.0-beta.4 (also :beta).

Check a download

sha256sum -c SHA256SUMS --ignore-missing
gh attestation verify podnet-x86_64-unknown-linux-musl --repo PodUtils/podnet
cosign verify-blob --bundle SHA256SUMS.sigstore.json \
  --certificate-identity https://github.com/PodUtils/podnet/.github/workflows/release.yml@refs/tags/v0.4.0-beta.4 \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com SHA256SUMS
sh scripts/rebuild.sh v0.4.0-beta.4   # rebuild and compare (x86_64, aarch64)

podnet update does the first three checks itself.

Breaking

A command or a script written for v0.4.0-beta.3 must change for each item
below.

  1. podnet pod -r stops with exit 64 when an earlier rule shadows a later
    reject rule. Give --allow-shadowed-rules to keep the old order. A rules
    file of the router with such a rule does not load. A shadowed rule of
    another action gives a warning only (T-242).
  2. scripts/install.sh stops before each download when the tag is not a
    release tag, or when PODNET_REPO is not OWNER/NAME. install.sh and
    podnet update need exactly one valid line of SHA256SUMS for the file
    (T-239).
  3. warp: a registration POST that got an HTTP answer (a 5xx too) is not
    sent to the second API host. The identity file can hold a device with
    state: "created" after a kill; the next run finishes it with a PATCH
    and makes no new device. A second registration of one identity file waits
    for the lock, and stops with exit 75 after 60 s (T-241).
  4. warp tun --default-route: a second warp tun on one state directory
    stops with "another warp tun runs". The new resolv.conf has the mode of
    the old file (0644 for a new file), not the mode of the umask (T-240).
  5. The netns backend makes a veth pair when the namespace cannot open
    /dev/net/tun. Before, the pod stopped there (T-174).

doctor --json is schema 1 with a fixed key set: keys are only added. It has
the new keys quick and lanes (T-216, T-217). docs/protocol.md section 9
lists each key; section 10 is the connector profile (T-218).

Changes for a tester

The router:

  • podnet route --config FILE: a YAML file of networks, groups,
    policies, health, control and doors. Each door is a SOCKS5 and HTTP
    CONNECT door on TCP or unix:, over a network, a group or a rules file. A
    door can have a DNS door (dns, dns_upstream). --detach --name N and
    autostart add take it (T-100, T-098).
  • route --check --to HOST:PORT [--door N]: a dry run that prints the rule,
    the way and the member of each door, with no dial (T-177).
  • route --status unix:/PATH [--json]: the state of a running router from
    its control socket: each group, the health, the round-trip time and its
    floor, the flows, the bytes and the head (T-097, T-178).
  • The key kernel of the router file writes policy routing with no ip
    program: a table, a default route and an fwmark rule for each WAN, and a
    weighted multipath route; it needs CAP_NET_ADMIN (T-119). The keys
    masquerade, mss_clamp, kill_switch and rp_filter (each on by
    default) add a masquerade and an MSS clamp through nf_tables, an
    unreachable route when each WAN is down, and rp_filter 0 on each WAN
    (T-120).
    route --config FILE --export mwan-json prints the WANs in the JSON form
    of the mwan director (T-121).
  • splits: GROUP: up=MEMBER down=MEMBER sends the UDP datagrams of a
    group by one member and receives them on another (off by default; TCP is
    not split) (T-179).
  • health takes down_after, up_after, cooldown, timeout and
    window (T-097, T-178). policies takes weighted, rr, minrtt,
    leastload and protect (T-178).

Fixes:

  • The tests that need a namespace, a loopback or a TUN skip on hosts that
    do not allow them (GitHub runners): the veth wire, the register tests of
    WARP, the kernel mode of the router.

  • Each probe child of pod doctor closes the descriptors that it inherits.

  • ci runs the netns tests as root on a GitHub runner (T-250); live
    probes the hosted mailboxes and relays through a proxy for TCP 443 only
    (T-253).

  • The documents name the former name once, in a footnote of the README
    (T-254).

Forwards and tools:

  • podnet forward -L udp:LISTEN=HOST:PORT over the datagrams of a network,
    and --dns ADDR:PORT --dns-upstream HOST:PORT (T-099).
  • podnet expose TARGET --via tunnel|relay|switch (T-099).
  • podnet ssh-relay --server HOST:PORT --user USER --url-match TEXT
    runs the SSH forward-relay leg and keeps its session: it reconnects with
    a backoff and records the new URL (T-165).
  • podnet bench URL [--json]: requests, errors, rate and latency over the
    way out (T-221).
  • The network netbird:[PORT] (default 1080) dials an address through the
    SOCKS5 listener of NetBird in netstack mode; a name target fails, as that
    mode has no DNS. net doctor has a row for the listener (T-246).
  • NetBird, Firezone and ZeroTier are studied as networks
    (docs/research/podnet/overlays.md, T-118).
  • --help --json on each command prints the manual of that command as JSON
    (T-222).

Overlays:

  • net tailscale --tailnet NAME (or PODNET_TAILNET) opens the door only
    when tailscaled is Running in that tailnet: exit 78 in another
    tailnet, exit 69 when the daemon is not ready. net doctor has a row for
    tailscaled (T-243).

Library and crates:

  • warp (the WireGuard leg): the handshake, the cookie, the session and
    the timers are the crate pod-wg of podcrates. It fixes these defects:
    a bad response reset the times of a rekey; the age of a session was read
    from the system clock; a TAI64N timestamp could go back or repeat; a
    responder under load refused each handshake (no mac2 of a cookie); a
    failure of the random bytes was a panic. The keys are wiped on drop
    (T-137).
  • podnet takes the crates of PodUtils/podcrates at v0.22.0. The
    measurement of the edge of Cloudflare's tunnels moved to
    PodUtils/podcrates:scripts/services/edge-facts.sh (T-137).

What to report

Open an issue in PodUtils/podnet with the output of podnet doctor --json
and podnet pod doctor --json, the command, and the stderr of the command
with -v.

Limits

  • This is a beta. Each item of Breaking can change again before the stable
    release.
  • No crates.io release of podnet exists.
  • The Rekor inclusion proof is not checked by podnet update.
  • warp --cc reno|cubic is slow on a link that gives one ACK for each round
    trip (smoltcp 0.14; PodUtils/podcrates#66). Keep the default (no
    controller).
  • The door of the router has no UDP ASSOCIATE (T-098). The byte meter of a
    member counts TCP flows only, not UDP datagrams (T-178).
  • warp forward is not yet an alias of podnet forward (T-099).

The licenses of the crates in the binaries, with their texts: THIRD-PARTY-LICENSES.md.

The commits of this release

Documents

  • docs: the hand-off names podcrates v0.16.0 (514a765)
  • docs: the hand-off names the takes and T-231 (821e061)

Other

  • record: T-235 done (v0.4.0-beta.3 at 649c8e3; release 42949492119, release-proofs 42952184194) (d3fad49)
  • T-137: take podcrates v0.17.0 (dd04b36)
  • record: map #426 (COORD-017, the take of v0.17.0) (90428ed)
  • T-137: take pod_hold::connect and pod_hold::packet (e4d4049)
  • T-231: podnet pod --loopback-rules applies the rules to a loopback connect (8dd7776)
  • record: T-231 done (4aef13c)
  • record: #426 closed (podcrates recorded taken e4d4049) (da6705f)
  • record: the cut of pod-netstack (COORD-018, #427) (f7ed86b)
  • T-098: the rules of the router to a network, a group or a refusal (02c4bec)
  • record: T-098 partial (the rules of the router) (b5dfc29)
  • record: T-098 names its commit after the rebase (02c4bec) (54281d2)
  • T-099: podnet forward -L LISTEN=HOST:PORT over a network of the registry (1058f08)
  • record: T-099 partial (podnet forward over a network) (8877f29)
  • record: file the donor review (#428 to #443): T-237 to T-244, comments on #375 and #359, COORD-019 to COORD-025 (5e16f6d)
  • record: #438 closed (podssh recorded the proposals, PodUtils/podssh#188) (a3d0db8)
  • T-238: bind_private never shows the socket at the mode of the umask (3c6173f)
  • record: T-238 done (32c2b53)
  • record: #429 closed (T-238); map #444 (COORD-026) (193bd36)
  • T-137: take pod-netstack of podcrates v0.20.0 (d23ce4e)
  • record: #427 closed (the take of pod-netstack); map #445 (COORD-027) (b626d2f)
  • record: #445 closed (podcrates recorded taken d23ce4e) (0ec2225)
  • record: T-025 done (the image is public: anonymous pull of :beta and :v0.4.0-beta.3); the crate names of T-007 are reserved; no owner action is left (d6f4079)
  • T-100: podnet route with a config file of networks, groups, health and doors (5c9c9e6)
  • T-100: record done (5c9c9e6) (6a665db)
  • T-075: the shim datagram test kills its server when it ends; a server of a failed run held port 19998 (54d7ed4)
  • T-243: net tailscale --tailnet guard, tailscaled doctor row, TS_FORCE_NOISE_443 hint (d65b676)
  • T-243: done (78f2660)
  • T-243: cite the rebased commit d65b676 (c726265)
  • T-242: lint shadowed rules of podnet pod -r and the router file; a shadowed reject is an error (e7ec95c)
  • record: T-242 partial (pod and router halves done; WARP half waits for pod-warp) (f508db3)
  • T-242: cite the rebased commit e7ec95c (246a904)
  • T-075: the shim datagram test takes a port of its run; parallel runs shared port 19998 (84deb60)
  • T-177: route --check --to HOST:PORT, a dry run of the rules and the groups of each door (f56826c)
  • T-177: record done (e1153ac)
  • T-177: one error text for one refused door; cite the rebased commit f56826c (236c145)
  • T-239: check the release tag and read SHA256SUMS strictly in install.sh and podnet update; install tests assert the downloader flags (be5259e)
  • T-239: record: done, Done section, work order (83b0da8)
  • T-239: cite the rebased commit be5259e (f7775af)
  • T-174: netns: a veth wire when the namespace cannot open /dev/net/tun (295a41d)
  • record: T-174 done (the veth wire, d346d16) (0fc2604)
  • T-174: cite the rebased commit 295a41d (09d0ca9)
  • T-174: each probe child of pod doctor closes the descriptors that it inherits; a child held the sockets of parallel tests open (96cd1b7)
  • T-241: warp: register under a lock, save the device before the enrolment step, fail over the registration POST only with no answer (f08840c)
  • T-241: done (467941a)
  • T-241: cite the rebased commit f08840c (701296e)
  • T-240: warp tun --default-route keeps the resolver record on disk, restores it after a kill, sets the mode (57eaa34)
  • T-240: done (bbad0a2)
  • T-240: cite the rebased commit 57eaa34 (a3276b2)
  • T-174: the veth test skips when the namespace cannot set up lo (GitHub runners) (fc97ef9)
  • record: map #446 (COORD-028) (5895622)
  • T-222: --help --json, llms.txt and llms-full.txt (981ee40)
  • record: T-222 done (622450d) (a450801)
  • T-222: cite the rebased commit 981ee40 (c3e1ac5)
  • T-241: the register tests skip with no loopback; T-174: the claim test makes its stale socket with mknod (a fork of a parallel test held a closed listener) (8e726b0)
  • T-216: doctor --json is schema 1 with a fixed key set; --quick makes one sample for each path and ends in 15 s (7045593)
  • T-217: doctor --json has the key lanes with the seven egress lanes (78c1e6a)
  • record: T-216 and T-217 done (b02e057, 489f3c8) (fabc312)
  • T-216, T-217: cite the rebased commits 7045593 and 78c1e6a; the llms files take --quick (09b98ed)
  • record: #446 closed (podcrates answered: no port); map #447 (COORD-029, pod-wg) (d8d63f2)
  • T-097: the thresholds of health in the router file; route --status over the control socket of the router (10831a3)
  • T-097: record the thresholds and route --status (partial) (8641b56)
  • T-099: UDP forwards and a DNS door over the datagrams of a network (cc28071)
  • T-099: podnet expose, one word for tunnel, relay node and net proxy --forward (81a3ecd)
  • T-099: record the UDP forwards, the DNS door and expose; the warp forward alias is left (19efb21)
  • T-099: cite the rebased commits cc28071 and 81a3ecd; the llms files take forward udp and expose (972b580)
  • T-218: the connector profile (docs/protocol.md, section 10) and the test that pins it (47f289a)
  • record: T-218 done (14bad0a) (f6b778d)
  • T-218: cite the rebased commit 47f289a (16ea6cf)
  • record: #430 (T-239) and #434 (T-243) closed (ci runs 43004948719, 43004399077) (dc2712a)
  • T-098: a DNS door for each door of the router file, over the dial of the door (463aecd)
  • T-098: record the DNS door of the router (partial: UDP ASSOCIATE waits for T-061) (25f615f)
  • T-178: named group policies (rr, minrtt, leastload, protect); the window of probe times and rtt_floor (184fa71)
  • T-178: record the group policies (partial); T-097: the floor of the round-trip time is done (2e4ef75)
  • T-178: cite the rebased commit 184fa71; the call to start was the lead's (a094d7f)
  • T-178: the pinned keys of the group status take policy, head, opens and rtt_floor_ms; a doc link names a public path (420715f)
  • T-221: podnet bench URL --json (861ebc4)
  • record: T-221 partial (bench done in e33350f, live step waits) (14cdbb0)
  • T-221: cite the rebased commit 861ebc4 (0a2b2a8)
  • handoff: the state of the session after the merges of 2026-11-11 (42bd74b)
  • T-126: record that pod-egress does not exist yet, no code change (cb80aca)
  • T-137: take the watches of pod-services of podcrates v0.21.0: the edge facts leave live.yml and tools/ for podcrates (0b945a3)
  • T-137: the crates of podcrates at v0.21.0; docs/protocol.md names the edge-facts script with its repository (the path check of tests/docs.rs) (54bd958)
  • record: map #448 (COORD-030, the take of v0.21.0) (3f2fab6)
  • handoff: T-126 waits for pod-egress; #448 (eb1647b)
  • T-245: the entry of the cut of v0.4.0-beta.4, and the draft of its notes (a05fc71)
  • T-242: a door of the router file takes allow_shadowed_rules (dc5d221)
  • T-242: record the door key of the router (9183c15)
  • T-118: research note on NetBird, Firezone and ZeroTier as networks (e501467)
  • T-118: record done, proposed entries in the Done section (ff8ca1e)
  • T-118: cite e501467; open T-246 and T-247 (NetBird) (52cd473)
  • handoff: T-118, T-245 and the agents in flight (95fc46a)
  • T-101: record that the live step waits for the network warp of the registry (T-057) (186f862)
  • T-119: router kernel mode: tables, fwmark rules and a multipath route through rtnetlink (2a8f121)
  • record: T-119 done (router kernel mode, d373600) (5db57a4)
  • T-119: cite the rebased commit 2a8f121 (c23b8a9)
  • T-121: route --export mwan-json prints the kernel section in the JSON form of the mwan director (12fbc95)
  • T-121: record done (c5515d5)
  • T-245: the notes of v0.4.0-beta.4 take T-118, T-119 and T-121 (69f8b2b)
  • T-246: the network spec netbird:[PORT] over the SOCKS5 listener of NetBird netstack mode, a doctor row, README (aebf853)
  • T-246: done; the record and the work order (bacabb2)
  • T-246: cite the rebased commit aebf853 (1a7643b)
  • T-245: the notes of v0.4.0-beta.4 take T-246 (8f13ce9)
  • T-222: the secrets allowlist takes the README example that llms-full.txt copies (ff4d245)
  • T-120: router kernel mode: masquerade and MSS clamp through nf_tables netlink, an unreachable kill switch, rp_filter 0 (84320e4)
  • T-120: record partial, part 4 left (cdf081f)
  • T-120: cite the rebased commit 84320e4 (fa7f4de)
  • T-245: the notes of v0.4.0-beta.4 take T-120 (94bb4d9)
  • record: #431 (T-240), #432 (T-241) and #369 (T-174) closed (ci run 43015605616) (82489e5)
  • T-130: research note on the iroh road, and a relay and mailbox of podnet's own (6a62104)
  • T-130: the record, done with the note of the iroh road and the relay (f18c052)
  • T-130: cite 662ba0c; the call on the proposed entries (e757f6b)
  • T-130: cite the commit 6a62104 of main (10a586c)
  • T-119: the kernel tests skip when unshare cannot write the uid map (GitHub runners) (ef17570)
  • T-245: version 0.4.0-beta.4 (Cargo.toml, the crates, Cargo.lock, fuzz/Cargo.lock at podcrates v0.21.0, the llms files); T-236 done (live runs 43012672866, 43016924769, 43021850166) (70946b3)
  • T-137: take pod-wg of podcrates v0.22.0: the handshake, the cookie, the session and the timers of src/warp/wg.rs move to pod_wg::Tunnel; each podcrates tag at v0.22.0 (089e1c9)
  • T-245: the notes of v0.4.0-beta.4 take pod-wg (fbe9cd2)
  • handoff: the cut of beta.4 and the take of pod-wg (936714a)
  • handoff: podnet is at podcrates v0.22.0 (fd65bce)
  • T-122: research note: a native git server with no installed git (027537b)
  • T-122: the record, done with the note and the proposed entries (958a2da)
  • T-122: the call on the proposed entries; handoff: no agent in flight (7f83e25)
  • session-start: the repository does not sign commits (the key of the cloud session is not the key of this identity) (008483f)
  • decisions: the rulings of the owner of 2026-11-11 (account work blocked, #89 a guide, SSH leg CLI, direction split as an option, guest-wire router, T-178 finished, crates.io stands, relays and mailbox… (45cf001)
  • record: T-248 (guest-wire router), T-249 (netns router on pod-netstack), T-250 (root CI step for the netns tests); the work order takes the owner's rulings (e6590b2)
  • record: the work order names the issue of podcrates, not its id (7c5f87e)
  • record: map #449 to #451 (COORD-031 to COORD-033); the freeze of pod-relay, pod-warp and pod-cloudflare at 7c5f87e (69aaf01)
  • T-250: ci runs the netns tests that skip for a user (the veth wire, the kernel mode of the router) as root, and fails on a skip line (1ee0cae)
  • T-250: record partial (the step is in; the first passing run of ci is left) (e3144c9)
  • T-001: GitHub #89 is the test guide of a new client (the owner's ruling of 2026-11-11) (dd14c7c)
  • research: the hosted relays and mailboxes (docs/research/podnet/hosted-relays.md); T-251 to T-253 (ca9a5fc)
  • decisions: the freeze row names the design file of podcrates with its repository (the path check of tests/docs.rs) (480e848)
  • decisions: the native git server goes to a crate pod-git of podcrates (#453); the update of the git study; map #452 and #453 (0a5d4dc)
  • record: T-254 (housekeeping); #447, #452 and #453 closed; handoff: the night queue (bf8ebd7)
  • T-249: Correction: pod-netstack v0.22.0 lacks any_ip, a listener on any destination and a checksum setting (7423536)
  • T-249: blocked on four APIs of pod-netstack (#454, COORD-036) (b1c7290)
  • T-178: byte meter of the group members; leastload reads the bytes of the flows (3b83bcd)
  • record: T-178 done (the byte meter of the doors); out of the work order (f6fc324)
  • T-178: cite the rebased commit 3b83bcd (b1750bd)
  • T-245: the notes of v0.4.0-beta.4 take the byte meter (T-178) (752790d)
  • T-254: one footnote for cfrs; drop the cfrs fixture, the beta.6 A/B and dated fix notes (fbfd6da)
  • T-254: remove dead keep-alive functions, a dead constant and two stale comments (32a66e5)
  • T-254: record the first pass (partial: docs/research is left) (f1cebc2)
  • record: #449 and #450 closed (podcrates recorded them, its #74) (db34bae)
  • T-250: shellcheck takes the redirect of the root test step (the log file belongs to the runner user) (e17d4f9)
  • T-250: done (ci run 43062916833: the netns tests as root on a runner, no skip) (2f6f35a)
  • T-254: docs/research names podnet for the old name; rename.md keeps only the current names; the second pass is recorded (2bcde91)
  • T-254: done (the counts) (70c21dc)
  • T-179: the key splits: UDP datagrams leave by up and are received on down (off by default) (56b3027)
  • record: T-179 partial (the UDP split is built; the TCP split waits for a far end) (a794cda)
  • T-179: cite the rebased commit 56b3027 (7d34d8e)
  • T-253: live step that probes the hosted mailboxes and relays through a proxy for TCP 443 only (614740c)
  • T-253: set done, write the Done section (bbe8aff)
  • T-253: cite the rebased commit 614740c (43005cc)
  • T-165: podnet ssh-relay: supervise the SSH forward-relay leg (6126bf6)
  • T-165: record done (podnet ssh-relay); T-166 Correction: the data of pod-services stays (cf16ba5)
  • T-165: partial (the row of doctor is left); cite the rebased commit 6126bf6 (b1f6546)
  • T-245: the notes of v0.4.0-beta.4 take T-165, T-179, T-250, T-253 and T-254; map #455 (9df5438)