Per-application network isolation, capture, shaping and NIC diagnostics for Linux (POSIX sh), with a guaranteed undo.
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
dev cb32af3e0f Initial commit
POSIX sh toolkit for per-application network isolation, capture, shaping and
diagnostics on Linux, with a guaranteed undo:

- netns-lanes  give one command exclusive use of a NIC via a network namespace
- lane-capture packet capture scoped to one application, with a tcpdump-free fallback
- lane-shaping inject latency/loss for one application, or take it offline
- cgroup-route reroute an already-running process without a namespace
- nic-doctor   end-to-end diagnosis of one NIC — link, DHCP, ARP, DNS, MTU
- safe-mode    find and undo everything the above ever changed, even if state
               files are gone or the folder itself was deleted

No shared library between tools, no daemons, nothing installed outside
~/.local/share/net-lane-scripts/. Verified under bash, dash and busybox ash.
2026-08-08 17:13:05 -04:00
cgroup-route Initial commit 2026-08-08 17:13:05 -04:00
lane-capture Initial commit 2026-08-08 17:13:05 -04:00
lane-shaping Initial commit 2026-08-08 17:13:05 -04:00
netns-lanes Initial commit 2026-08-08 17:13:05 -04:00
nic-doctor Initial commit 2026-08-08 17:13:05 -04:00
safe-mode Initial commit 2026-08-08 17:13:05 -04:00
CHEATSHEET.md Initial commit 2026-08-08 17:13:05 -04:00
LICENSE Initial commit 2026-08-08 17:13:05 -04:00
README.md Initial commit 2026-08-08 17:13:05 -04:00
run.sh Initial commit 2026-08-08 17:13:05 -04:00
TROUBLESHOOTING.md Initial commit 2026-08-08 17:13:05 -04:00

net-lane-scripts

Small, self-contained tools for isolating, capturing, shaping and diagnosing this machine's networking. One folder per purpose, each with its own run.sh.

./run.sh                     # menu of every tool
./run.sh --list              # one line each
./run.sh nic-doctor -i eth0  # run one directly, with arguments

⛑ Emergency exit — undo everything

If anything ever looks wrong, this puts the machine back exactly as it was:

./run.sh --panic             # or: ./safe-mode/run.sh --panic

It does not rely on the other scripts' bookkeeping. It hunts for this toolkit's fingerprints directly in the kernel — namespaces, veth devices, routing tables, ip rules, firewall rules and chains, cgroups, qdiscs, state files, stray processes — and removes what it finds, restoring the two sysctls the tools change. It works even if a script was killed halfway, its state files were deleted, or the folder itself is gone.

./safe-mode/run.sh              # what has been changed, right now
./safe-mode/run.sh --dry-run    # exactly what --panic would remove
./safe-mode/run.sh --verify     # exit 0 only if the machine is clean
./safe-mode/run.sh --snapshot   # save a baseline of your network state
./safe-mode/run.sh --diff       # compare the machine against that baseline

Take a baseline before you start (--snapshot, ideally while nothing is claimed). Afterwards --diff shows, line by line, that the machine matches it again. See safe-mode/README.md.


Getting started

There is nothing to install. Clone it and run a run.sh — from the root to get a menu, or straight from the folder you want:

git clone https://git.gui.icu/dev/net-lane-scripts.git && cd net-lane-scripts
./run.sh --check                    # does this machine have what the tools need?
./safe-mode/run.sh --snapshot       # baseline your network state first

cd netns-lanes && ./run.sh          # a browser that can only use the Wi-Fi NIC
./run.sh                            # run it again: NIC handed back to the host

Each tool escalates to root by itself when it needs to (sudo from a terminal, pkexec otherwise) — do not run the scripts as root yourself.

More recipes in CHEATSHEET.md; when something misbehaves, see TROUBLESHOOTING.md.

Requirements

Linux with network namespace support, plus:

required iproute2 (ip), iptables
recommended tc, curl, python3, procps (pgrep), util-linux (setpriv, flock, findmnt)
optional tcpdump (lane-capture has a built-in fallback), arping, iw/nmcli (Wi-Fi), cgroup v2 (for cgroup-route)

./run.sh --check reports what is missing and prints the install command for your distro. Everything degrades gracefully: a missing optional tool disables one probe, never the whole script.

Portability

POSIX sh — no bashisms — verified against busybox ash as well as bash, so it runs under dash, ash or bash as /bin/sh. Nothing is hard-coded to a path, a user or a distro: interfaces are discovered at runtime, lane subnets and routing tables are collision-checked against the live machine before use, and every external tool is probed with a fallback. Clone it anywhere, as any user.

The tools

folder what it does
netns-lanes/ Give a browser — or any command — exclusive use of one NIC, via a per-NIC network namespace. Toggle on/off, multi-lane, kill switch.
lane-capture/ Packet capture for exactly one application, with DNS + TLS SNI summary. Works without tcpdump.
lane-shaping/ Give one application 200 ms and 3 % loss (or take it offline) while the machine stays fast.
cgroup-route/ Route an already-running process out of another NIC — the one thing namespaces cannot do.
nic-doctor/ Diagnose one NIC end to end — link, DHCP, ARP, DNS, captive portal, MTU black holes — even when it is not the default route.
safe-mode/ The emergency exit above: find and undo everything the others did.

How they fit together

netns-lanes is the foundation: it puts an application behind its own veth pair. Once that exists the veth is a perfect chokepoint — lane-capture reads it, lane-shaping degrades it. cgroup-route is the escape hatch for processes that are already running and cannot be restarted. nic-doctor answers the question that usually comes first: is this NIC even working? And safe-mode guarantees you can walk away from all of it.

What gets changed, and how it is undone

Everything these tools do is additive. They never edit your existing routes, firewall rules, NetworkManager profiles or /etc/resolv.conf, so removing what they added is a complete restoration rather than a best effort.

tool adds undone by
netns-lanes netns wb-<nic>, veth pair, routing table + ip rule 7707+, 4 firewall rules tagged wb:<nic>, /etc/netns/wb-<nic> run.sh again, or --release --all
netns-lanes 2 sysctls per NIC (forwarding, rp_filter) — previous values recorded restored on release
lane-shaping netem qdisc on each end of a lane's veth --clear
cgroup-route cgroup route-<nic>, chains CGROUP_ROUTE/CGROUP_SNAT, table + rule 7720+ --clear
lane-capture .pcap files under ~/.local/share/net-lane-scripts/captures/ delete them, or safe-mode --panic --purge
nic-doctor nothing — every probe is read-only n/a

Anything risky asks first: claiming a NIC that carries an SSH session, a network mount or your only default route requires a typed yes, and adopting live processes into a cgroup lists them for confirmation.

House rules

  • POSIX sh, no bashisms. Verified against busybox ash, not just bash.
  • Each folder is copyable on its own — no shared library, no imports between tools. run.sh in each folder is the entry point; the top-level run.sh only lists and dispatches. There are no launchers, daemons or install steps.
  • The repo is static: nothing is ever written inside it. Generated files — browser profiles, captures, the baseline — live in ~/.local/share/net-lane-scripts/, and system state in /run and /var/lib.
  • Every tool escalates on its own (sudo in a terminal, pkexec from the desktop) and says what it touched.
  • Nothing is silently permanent: every change is either self-expiring or has an explicit undo, and safe-mode catches whatever is left.

License

MIT — see LICENSE. Every script carries an SPDX-License-Identifier: MIT tag, so a single folder lifted out of this repo still says what it is licensed under.

Ideas not built yet

  • proc-netns — namespace forensics: for any PID or regex, which network namespace it is in, which NIC its traffic would use, whether it is leaking.
  • service-lane — systemd drop-in generator using NetworkNamespacePath=/run/netns/wb-<nic> so a unit starts inside a lane.
  • dns-lane — force DoH/DoT inside a lane and audit the resolver path.