Repository navigation
feat: UDP through method=tproxy - #11
Merged
Merged
Conversation
dennisklein
force-pushed
the
claude/project-thread-kmxtqs-tproxy
branch
from
October 11, 2026 12:18
13f415e to
93f0896
Compare
dennisklein
force-pushed
the
claude/project-thread-kmxtqs-tproxy
branch
8 times, most recently
from
October 11, 2026 13:39
e17aa47 to
59520ce
Compare
dennisklein
force-pushed
the
claude/project-thread-kmxtqs-tproxy
branch
5 times, most recently
from
October 11, 2026 14:30
2a1d8c1 to
d120c8d
Compare
dennisklein
marked this pull request as ready for review
October 11, 2026 14:45
dennisklein
force-pushed
the
claude/project-thread-kmxtqs-tproxy
branch
from
October 11, 2026 19:52
d120c8d to
afcadfd
Compare
- Fedora has no package named libnm-devel (it is NetworkManager-libnm-devel), so preparing the VM failed - Ask dnf for pkgconfig(gtk4), pkgconfig(libnm) and pkgconfig(json-glib-1.0), as the RPM spec does
- sshuttle logs "Connected to server" before it installs its rules, so a request right after could miss the redirect and hang until its timeout - wait_connected now also waits for sshuttle's systemd READY, which comes after the rules; with nothing on NOTIFY_SOCKET it shows in the log
- Accept method=tproxy; pass sshuttle the mark 0x4e530000 with --tmark - Route marked packets to lo with a rule and a local route of the plugin's own, installed with the guard for the families the tunnel carries and removed by their exact values - Let the guard accept packets with that mark ahead of the dnat rules - Sweep stale sshuttle-[mtd]-PORT chains from iptables' mangle table - Check health per method: a live mark chain per family for tproxy, and put back a missing rule or route - Fail at Connect, and in check, when iptables or ip6tables is missing; remove the routing in cleanup; offer tproxy in add --method
- Recommends iptables in the deb and iptables-nft in the RPM; sshuttle's tproxy method runs iptables and ip6tables
- Add a UDP echo server and client for the lab - Run sshuttle's tproxy method behind the plugin's own guard, policy routing and sweep, with a route to the internal network and a counter on the uplink so that a leak would show - T15 DNS pinned with IP_UNICAST_IF, T16 UDP and TCP, T17 tunnel down, T18 stale chains after SIGKILL, T19 a UDP flow silent for 40 s - Install iptables in CI's lab job
- Run a UDP echo server on the internal network - TP-01: UDP, TCP and split DNS through the tunnel, fail closed in a gap, nothing left after the disconnect - TP-02: a killed sshuttle and nft flush ruleset while up - TP-03: NM's reload and a roam leave the rule and route alone - Install iptables-nft in the VM and count mangle chains and the routing as leftovers
- Add the method to the profile table, the guard and the health check, and list lab tests T15 to T19 in the design - Mark the tproxy design as implemented and record the T15 result and what differs - Document --method tproxy and its limits in the user guide
- Fedora's agetty is sometimes denied reading the console issue file that NetworkManager's dispatcher writes; M2-15 no longer fails on it - Record the denial in the design, where its record was missing
- Fresh journal reads, by unit, after a cursor or since a time, at times missed the plugin's newest entries, which a later read showed; syncing the journal before each read did not change that - One journalctl --follow runs from the start of the run into a file; log_mark records the file's size, and plog keeps the lines after it whose syslog identifier is nm-sshuttle-service - The DNS server and the IPv6 web server log under their own identifiers, and their checks read the same file since log_mark; M2-29 counts the tunnel's pinning lines in it - journald tells followers about new entries in batches; a check that reads the log once first logs a marker and waits for it in the file - Drop the journal syncs before each read - A failing check prints 70 lines of state, so the run's log shows the plugin's journal tail too
dennisklein
force-pushed
the
claude/project-thread-kmxtqs-tproxy
branch
from
October 11, 2026 19:56
afcadfd to
a0f435f
Compare
Owner
Author
|
The This PR now carries the fix as its first commit, Generated by Claude Code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Dennis · project thread
Before: only TCP and DNS went through the tunnel. Other UDP to a tunnelled network (QUIC, NTP, a DNS server queried directly) was refused by the guard.
After: a profile with
method=tproxysends TCP and UDP through the tunnel, keeps failing closed while it is down, and leaves nothing behind.nftstays the default. The GNOME editor offerstproxyin its method drop-down and accepts it.It implements docs/later/tproxy.md. Merge it before #12, which is stacked on it.
How: sshuttle gets
--tmark 0x4e530000. The plugin installs its own policy routing (ip rule … fwmark 0x4e530000 lookup 20051at priority 100, pluslocal default dev lo table 20051) together with the guard, for the families the tunnel carries. It removes the rule and route by their exact values. The guard accepts packets with that mark ahead of itsdnatrules. The sweep removes stalesshuttle-[mtd]-PORTchains through iptables. For tproxy, the health check wants a live mark chain per family, and it puts back a missing rule or route. If iptables or ip6tables is missing, Connect andnm-sshuttle checkfail. The packages recommend iptables. The shared profile cases, the editor's C validator and its drop-down now allowtproxy.Also in this PR:
libnm-devel, which Fedora does not have. The first commit installs the editor's build dependencies by theirpkgconfig(...)names, as the RPM spec does.journalctl --followfor the whole run, M2-29 included. Fresh reads after a cursor or by unit at times missed the plugin's newest lines.Results:
iptablesuses the legacy backend, which Fedora's sshuttle package pulls in. Therenft flush rulesetleaves sshuttle's mark chain, so only the guard comes back and the tunnel stays up. TP-02 checks that, and the design records it.IP_UNICAST_IFis captured, sodns=splitstays allowed.Profile keys: none change.
methodtakestproxy, as the design says.🤖 Generated with Claude Code