Repository navigation
NetPilot 1.2.2 for Linux - graphical build (release candidate)
Pre-releaseNetPilot 1.2.2 for Linux — graphical build
The Windows desktop app is WPF, which does not exist on Linux, so this is a separate program:
written in Avalonia, drawing the same interface and sharing the same logic with the Windows
build through NetPilot.Core.
What has actually been verified
Verified on a real Linux kernel (ubuntu-24.04, full root): the shared logic's 107 tests pass
there, and the daemon's privileged paths — nftables rules, per-uid blocking measured with
setpriv, tc shaping — are exercised on every push by .github/workflows/daemon.yml.
Verified by running this window: it was launched, screenshotted and driven on a Windows
machine. Avalonia renders the same interface on all three platforms, so the screenshots show the
real thing — layout, bindings, live charts, the diagnostics page — rather than a promise. Every
defect listed below was found that way.
Not verified: that this window opens on a real Linux desktop. No Linux machine was available
to run it on. The only untested part is the native windowing underneath, which is Avalonia's own
code rather than ours — but "Avalonia is well tested" is not "we watched it work here". Treat
this as a release candidate.
Install
tar -xzf netpilot-linux-x64.tar.gz # or linux-arm64
cd netpilot-linux-x64
./NetPilot # start the window
sudo ./NetPilot # needed for firewall rules and bandwidth limitslinux-x64 for Intel/AMD, linux-arm64 for Raspberry Pi 4/5 and other 64-bit ARM.
One executable and its runtime; nothing to install. There is no .desktop entry or icon yet, so
the first launch is from a terminal.
What it does here
| Feature | Linux |
|---|---|
| Dashboard with live throughput and per-adapter counters | yes |
| Phone Tunnel → PC — pair the Android app with this machine | yes |
| DNS servers per interface | read |
| Adapters | yes |
| What this machine can do — the honest capability list | yes |
| Diagnostics — the log, and a one-click support report | yes |
| Block one application | yes, with root (nftables, by uid) |
| Bandwidth limit per application | yes, with root (tc, upload only) |
| Per-application traffic attribution | no |
| Per-application download limiting | no |
The two root-only rows apply per user, not per executable: meta skuid is what the kernel
can match on, so a rule covers everything running as that account. The app says so rather than
implying something finer-grained than the kernel can deliver.
The diagnostics page
Everything the app knows about itself in one place: the log, whether it is trustworthy (written /
dropped / queued), and a Copy for support button that puts the lot on the clipboard.
Pairing codes, bearer tokens and hardware addresses are replaced before anything reaches the
file, so the log can be pasted into a thread as it is. That is not a promise — redaction happens
before any sink sees the text, in one place, and there are tests asserting a bearer token and a
six-digit code never appear in the output.
Bugs this build found, by being run
Every one of these compiled cleanly and started cleanly:
System.Text.Jsondrops public fields.MvLinkwas declared with fields, so/status
answered with an array of empty objects while the process printed a healthy banner.- XAML cannot bind to a field. The same type change made every adapter render as a blank tile.
Fixed at the root: the shared contract types are properties now. - A custom-drawn Avalonia control is not re-rendered when a bound property changes. The
throughput number updated every two seconds and the chart stayed an empty baseline. - Double-encoded UTF-8. "Phone Tunnel → PC" rendered as mojibake, because an edit had read a
BOM-less file as Latin-1. Every non-ASCII character in the sources is a\uescape now, which
cannot be misread. - A log file cannot be read while it is being written.
File.ReadAllLinesopens with
FileShare.Read, which forbids other handles from writing — and the app's own writer holds the
file for exactly that. The diagnostics page would have failed on the log it exists to show. - A per-category log level could only make things quieter. The global threshold was checked
first, so "trace this subsystem while everything else stays at Info" silently did nothing. Shutdownpermanently killed logging. Disposing the queue made every later entry throw and
be swallowed, so the log simply stopped after the first call — which is what happens on a
settings change.
Not in this release
- 12 of the Windows app's 18 pages (DNS benchmark, Smart DNS, scheduled limits, history,
profiles, tools, settings). - Per-application download limiting, on either platform.
- Per-process traffic attribution — no base system offers it without eBPF.
- A desktop entry, an icon, and any package format (.deb, AppImage, Flatpak).
Licence: MIT.