· 5 min read ·

The Kernel Plumbing Behind Little Snitch's Linux Debut

Source: hackernews

Little Snitch has been a staple of security-conscious macOS setups since 2002. Objective Development, the Austrian software company behind it, has spent over two decades refining a deceptively simple idea: intercept outbound network connections at the process level and let the user decide what to allow. The Linux version, now available in beta, lands in an ecosystem where free alternatives already exist, which makes the engineering choices and the product positioning both worth examining carefully.

What the product does

Little Snitch operates at a layer above traditional firewalls. Tools like ufw, firewalld, and nftables filter traffic by IP address, port, and protocol. Little Snitch filters by the answer to a different question: which executable initiated this connection?

When an application attempts a new outbound connection, Little Snitch surfaces an alert showing the process name, the destination hostname or IP, and the port. The user can allow once, allow permanently, deny once, or deny permanently. Rules accumulate into a per-application policy over time. The connection map, Little Snitch’s most visually recognizable feature since version 4, renders live connections as arcs over a globe annotated with geographic destination data. The Linux version carries all of this over from the macOS product.

How macOS solved this

On macOS, Objective Development’s original approach used kernel extensions (kexts), which gave the software deep access to the network stack but required kernel-level code maintained against every macOS update. When Apple deprecated kexts ahead of macOS 11 Big Sur, the company migrated Little Snitch to the Network Extension framework, Apple’s first-party API for network filtering applications.

The Network Extension framework provides a clean, sandboxed interface. An application implements NEFilterDataProvider, and macOS calls it for each new network flow before any data passes. Process attribution is built into the API: the framework delivers the connecting process’s audit token with every flow. There is no guesswork, no /proc walking, no race conditions. Apple owns the mechanism, and third-party tools consume the result.

That infrastructure does not exist on Linux.

What Linux offers instead

Linux’s kernel has no single blessed API for intercepting outbound connections by process. What it has is a collection of lower-level primitives, each with different tradeoffs, that compose into something equivalent with more engineering effort.

The established approach, used by OpenSnitch, is Netfilter NFQUEUE. Netfilter is the packet-filtering framework at the heart of the Linux kernel; NFQUEUE is a target rule that diverts packets to a userspace queue, where a daemon can inspect and verdict them. The flow looks roughly like this:

outbound packet
  → iptables NFQUEUE rule
  → libnetfilter_queue (userspace)
  → /proc/net/tcp lookup (find socket inode by source port)
  → /proc/<pid>/fd walk (find process that owns the inode)
  → allow/drop verdict returned to kernel

The procfs walk is the expensive part. Every new connection requires scanning /proc/net/tcp or /proc/net/tcp6 to find the socket inode, then iterating over /proc/<pid>/fd symlinks for each running process until one matches. At high connection rates this becomes a performance concern, and the lookup is inherently racy: a short-lived process can establish a connection and exit before the daemon finishes attributing it.

eBPF provides a substantially cleaner path. The BPF_PROG_TYPE_SOCK_OPS program type attaches to the kernel’s socket lifecycle, and its BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB callback fires at the moment a TCP connection completes the three-way handshake from the local side. At that point, the eBPF program runs inside the kernel’s execution context for the connecting process, so bpf_get_current_pid_tgid() and bpf_get_current_comm() return unambiguous attribution without any procfs lookup:

SEC("sockops")
int track_established(struct bpf_sock_ops *skops) {
    if (skops->op != BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB)
        return 0;

    __u64 pid_tgid = bpf_get_current_pid_tgid();
    char comm[16];
    bpf_get_current_comm(comm, sizeof(comm));

    // record destination, pid, comm in a BPF map
    // for the userspace daemon to read and apply policy
    return 0;
}

There is no race condition here. The connection cannot proceed past the eBPF program’s return, and the process is necessarily live at the callback’s execution point by definition.

A third option, increasingly relevant on systemd-based distributions, is cgroup-aware Netfilter matching. Under cgroup v2, systemd assigns every process, service, and user session to a predictable cgroup hierarchy. The cgroup match extension for iptables and nftables can route packets from a specific cgroup to a specific queue or chain. A running Firefox session ends up at something like /sys/fs/cgroup/user.slice/user-1000.slice/user@1000.service/app.slice/app-org.mozilla.firefox.scope, which is an unambiguous identifier that avoids per-packet procfs lookups entirely.

Objective Development has not published detailed technical documentation for the Linux version’s internals, but a product targeting modern kernels in 2025, written by a company that made the correct architectural call on the macOS kext-to-Network-Extension transition, is most likely using eBPF for attribution combined with either cgroup-aware Netfilter or eBPF-based socket policy for enforcement.

OpenSnitch was here first

Discussing Little Snitch for Linux without acknowledging OpenSnitch would be incomplete. OpenSnitch has existed since around 2017, created by security researcher Andrea Fabrizi as a deliberate Linux implementation of the Little Snitch concept. It is GPL-licensed, written in Go with a Python/Qt frontend, and handles the NFQUEUE attribution loop correctly. Newer versions incorporate eBPF for faster process lookups. It has thousands of GitHub stars and active maintenance.

Portmaster by Safing covers similar ground with additional scope: DNS-over-TLS, tracker blocking at the DNS layer, and a proprietary network privacy layer called SPN. It is AGPLv3-licensed, free for core features, and maintained by a company rather than individual contributors. Portmaster is also Austrian, which is an odd coincidence given Objective Development’s origin.

The market Little Snitch enters on Linux is not empty. The bet Objective Development is making is that commercial-grade UX, built on twenty-three years of iteration on a macOS product used by hundreds of thousands of people, is worth a paid license to a segment of Linux users who currently use OpenSnitch and find the interface adequate but not excellent.

That bet is a reasonable one. The alert design, rule management interface, connection map, and performance profile are things that take years of user feedback and engineering investment to get right. Objective Development has done that work already on macOS. Porting the resulting product to Linux involves non-trivial kernel engineering, but it also means bringing a mature interaction model to a platform where the open-source alternatives have historically prioritized function over form.

The threat model is worth taking seriously

There is a recurring argument that per-process outbound firewalls are security theater: sophisticated malware routes around them, and legitimate software deserves its network access. The argument is not entirely wrong, but it addresses only part of the use case.

The more relevant scenario in 2025 is visibility into software behavior that is technically legitimate but not what a user would explicitly authorize. AI coding assistants, telemetry-heavy IDEs, package managers with analytics reporting, and a growing catalog of Electron applications all make network connections that are not always visible or documented. A per-process firewall does not stop a determined attacker; it does surface the difference between “this tool downloaded a model update” and “this tool sent your project files to an analytics endpoint.” For a developer who installs new tooling regularly, that visibility has independent value regardless of its limits against adversarial scenarios.

Little Snitch on Linux means this category of tool now has a commercial option with a credible track record behind it. OpenSnitch remains the right choice for users who want open source and are comfortable with its interface. For users who have migrated from macOS and already know Little Snitch’s interaction model, the Linux version will feel immediately familiar, which is precisely the point.

Was this interesting?