Skip to content

NetPilot daemon 1.2.2 - Linux and macOS (release candidate)

Pre-release
Pre-release

Choose a tag to compare

@Ekkh1300 Ekkh1300 released this 03 Oct 11:59
· 17 commits to master since this release

NetPilot daemon 1.2.2 — Linux and macOS

A separate netpilotd binary for Linux and macOS. The desktop app is WPF, which does not exist
on those platforms, so this shares its logic with the Windows build through NetPilot.Core.

What has actually been verified

These are release candidates, not a preview: the binaries here are the ones that passed
continuous testing on real Linux and real macOS machines (GitHub Actions runners with a real
kernel, real nftables, real networksetup). Every commit that goes into master runs that
suite.

Verified on a real Linux kernel (ubuntu-24.04, full root):

  • the daemon starts, serves /api/v1/*, and detects the machine's own interfaces and counters
  • an unprivileged run reports that it cannot enforce rules rather than pretending
  • nft accepts the ruleset the backend generates, and the drop rule appears in the kernel
  • blocking a uid measurably cuts that uid off while the host keeps working — tested against
    a listener on the machine, with setpriv, in both directions (block, then unblock)
  • tc installs the HTB qdisc and the per-uid flower filter, and the daemon verifies the qdisc
    is really there instead of trusting the exit code
  • the runner's firewall is left clean afterwards

Verified on a real Mac (macos-14 arm64):

  • link detection, with correct interface names and byte counters
  • the VPN state reads off on a machine with no VPN, and never falsely claims active
  • per-app blocking and shaping refuse, with the real reason — checked where pf exists
  • DNS is read through the same networksetup path the app drives
  • 71 tests of the shared logic, run on macOS as well as Linux and Windows

Not verified: anything that needs real hardware or a real user — a USB-tethered phone, a
Wi-Fi hotspot, a second machine actually sharing over the tunnel, and bandwidth shaping under
real load. If you try those, this is a release candidate, not a finished product.

Feature reality

Feature Linux macOS
Link detection + traffic counters yes yes
DNS control yes yes
System proxy (phone tunnel) yes (GNOME) yes
PC VPN state (3-way) yes yes
Snapshot / restore DNS + proxy DNS + proxy
Per-app blocking yes (nftables, by uid) no
Per-app upload limit yes (tc, by uid) no
Per-app download limit no no
Per-process traffic no no
Graphical interface no no

macOS cannot block or throttle a single application: pf has no process matcher, and per-flow
shaping needs a Network Extension with Apple's approval. The daemon refuses with that reason
instead of offering a switch that does nothing.

On Linux, rules apply per user (uid) — that is what the kernel's matchers can do — not per
executable path.

Install

tar -xzf netpilotd-<rid>.tar.gz
./netpilotd            # status only
sudo ./netpilotd       # firewall rules and bandwidth limits become available

nft and tc need root. Without it the daemon starts, says so plainly, and serves status — it
does not pretend to enforce anything.

curl -s http://localhost:8787/api/v1/ping
curl -s http://localhost:8787/api/v1/status | jq

Pairing with the Android app

The phone speaks the same ten endpoints as on Windows, so no Android change is needed. Open
Phone Tunnel → PC on the phone, point it at this machine's address and port 8787, and pair
with the code the daemon prints. The phone cannot tell a daemon from the Windows app apart.

Known gaps

  • No graphical interface. Everything is the API; docs/PORTING.md explains what a GUI port
    would involve and why it is a separate project.
  • Per-process traffic attribution: unavailable on both platforms (/proc has no per-process
    network counter, and lsof reports open sockets rather than bytes).
  • Per-target download shaping: not implemented on either.
  • Only the gsettings path for the Linux system proxy is wired up; KDE and XFCE sessions need
    the environment variable instead.
  • Hotspot detection on Linux needs the driver to expose it. Where none does, the phone link is
    classified as lan, which still works.

Full detail: docs/LINUX-MACOS.md ·
docs/PORTING.md

Licence: MIT.