TechEarl

OpenSnitch: An Application Firewall for Linux

OpenSnitch is an application firewall for Linux that asks per process before any program talks to the network. Install it, answer the prompts, and write rules that stick.

Ishan Karunaratne⏱️ 9 min readUpdated
Share thisCopied
OpenSnitch application firewall for Linux: install opensnitchd, answer the per-process connection prompts, and store allow/deny rules under /etc/opensnitchd/rules.

A normal Linux firewall like iptables or nftables filters on ports and addresses. It does not know or care which program opened the socket. OpenSnitch is an application firewall: it intercepts outbound connections and, the first time a given process tries to reach the network, pops a prompt asking whether to allow it. Answer once, save the decision as a rule, and that program is either trusted or blocked from then on.

That is the whole idea, the same one behind Little Snitch on macOS. The difference is what it buys you on a Linux box: you find out that a closed-source updater phones home on launch, that a font helper opens a socket to an analytics host, or that some package you installed last week is beaconing. Port-based firewalls never show you any of that, because the traffic is on port 443 to a normal-looking host and looks identical to everything else.

Install OpenSnitch

OpenSnitch ships as two pieces: opensnitchd, the root daemon that does the interception and rule enforcement, and opensnitch-ui, the desktop GUI that shows the prompts and lets you browse what is connecting. The daemon catches new connections through the kernel (older builds via an nftables/NFQUEUE hook, current builds via eBPF), pauses each one, and asks before it lets the packet out. On Debian and Ubuntu, grab the .deb files from the releases page and install both:

bash
sudo apt install ./opensnitch_*.deb ./python3-opensnitch-ui_*.deb

The daemon installs as a systemd service. Enable and start it:

bash
sudo systemctl enable --now opensnitchd

Then launch the GUI from your desktop session (it runs as your normal user, not root, and talks to the daemon over a local gRPC socket):

bash
opensnitch-ui

On Arch the daemon and UI are in the AUR (opensnitch and opensnitch-ui); Fedora and other RPM distros have .rpm builds on the same releases page. Whatever the distro, the split is the same: a privileged daemon plus an unprivileged UI.

What happens the first time something connects

With the daemon running and the UI open, the moment a process makes an outbound connection that no existing rule covers, you get a dialog. It shows the destination host, the port, the full path to the binary, and the command line that launched it. You pick an action and a scope, and that is the rule.

Three things you are deciding in that prompt:

  • Action: allow, deny, or reject. allow lets it through. deny silently drops the packet (the app sees a connection that never completes). reject actively refuses, so the app gets an immediate failure instead of a hang. Reach for reject when you want the program to fail fast rather than sit there retrying.
  • Duration: once (just this connection), a timed window (30s, 1h, 5h, 12h), or always. Only always is written to disk and survives a restart; the timed and once choices live in memory and expire.
  • Scope: match just this exact destination, or everything from this binary regardless of where it connects, or by the process path, by the destination port, and so on. Narrow scope is safer; broad scope means fewer future prompts.

The first hour after install is noisy because every program you touch is generating its first prompt. That settles fast. After a day of normal use the prompts mostly stop, and the ones that do appear are the interesting ones: something you did not expect, reaching somewhere you did not expect.

Where rules live

Persistent rules are JSON files under /etc/opensnitchd/rules. You can read and edit them directly, which is the part that makes OpenSnitch pleasant to operate. A rule looks like this:

json
{
  "created": "2026-04-25T10:00:00Z",
  "name": "deny-telemetry-example",
  "enabled": true,
  "precedence": false,
  "action": "deny",
  "duration": "always",
  "operator": {
    "type": "simple",
    "operand": "dest.host",
    "data": "telemetry.example.com"
  }
}

The operator block is the matcher. type can be simple (exact equality), regexp (pattern match), network (CIDR containment), or list (combine several conditions). operand is what you match on: dest.host, dest.port, process.path, and similar fields. precedence: true makes a rule win over others that also match, which is how you write a broad allow plus a narrow deny carve-out.

Because rules are plain files in a known directory, you can version them in a config repo, drop the same set onto a fleet of machines, or grep them when you are trying to remember why some app cannot reach a host. Editing a file is picked up by the daemon without a manual reload.

Default action: the choice that defines your setup

The daemon config at /etc/opensnitchd/default-config.json has a DefaultAction field that decides what happens to a connection no rule matches. Two sane choices, and they give you two very different firewalls:

DefaultActionBehaviorWho it suits
allowUnmatched connections go through; you only block things you explicitly denyDefault-allow monitoring. Low friction. You see what connects and pick off the bad ones.
denyUnmatched connections are blocked until you write an allow ruleDefault-deny lockdown. High friction at first, much tighter. Nothing reaches the network unless you said so.

One gotcha that trips people up: the GUI has its own default action, and while it is connected it overrides whatever DefaultAction is in the daemon config (the file on disk is left untouched). So if you set deny in default-config.json but see connections sailing through, check the GUI's setting first; the daemon only falls back to its own DefaultAction when no GUI is attached. There is also a third value, reject, but the project warns it can put some services (dnsmasq, sshd, tinyproxy) into a retry loop, so I leave the default at allow or deny.

Most people start with allow to learn what their system actually does, then flip to deny once they have built up a rule set they trust. Flipping to deny cold, on a desktop you use all day, means a wall of prompts and a fair chance of breaking something mid-task. Build the rules first.

When OpenSnitch is the wrong tool

It is an outbound, per-process firewall for interactive machines. That framing carries its limits:

  • It is not an inbound firewall. OpenSnitch is about what your processes reach out to, not what reaches in. You still want nftables/ufw (or a perimeter firewall) for inbound. The two are complementary, not substitutes.
  • Headless servers are a poor fit for the GUI flow. The prompt model assumes a human at a desktop. On a server with no display you would pre-author the rule files and run DefaultAction: deny, but at that point a tighter egress policy in nftables or your cloud security groups is often the better fit. OpenSnitch shines on workstations.
  • A compromised root can disable it. It is a root daemon. Malware already running as root can stop the service or rewrite the rules. It raises the bar and gives you visibility; it is not a containment boundary against an attacker who already owns the box.
  • Process attribution has edges. Short-lived processes, or connections proxied through another local process, can attribute to something other than the real origin. The eBPF-based detection in modern builds is much better at this than the old /proc polling, but it is worth knowing the seam exists.

For locking down what plugs into the machine rather than what it talks to, that is a different layer: see blocking USB devices with USBGuard.

FAQ

See also

Sources

Authoritative references this article was fact-checked against.

TagsOpenSnitchApplication FirewallLinuxSecurityFirewallnftablesNetwork Security

Found this useful? Pass it on.

Copied

Ishan Karunaratne

Tech Architect · Software Engineer · AI/DevOps

Tech architect and software engineer with 20+ years building software, Linux systems, and DevOps infrastructure, and lately working AI into the stack. Currently Chief Technology Officer at a healthcare tech startup, which is where most of these field notes come from.

Keep reading

Related posts

nvtop: Monitor NVIDIA, AMD, and Intel GPUs on Linux

nvtop is an htop-style GPU monitor for Linux. One install (sudo apt install nvtop), one command, and you get live per-GPU utilization, memory, temperature, and a sortable per-process list across NVIDIA, AMD, and Intel cards.

iftop: See Bandwidth by Connection in Real Time

sudo iftop -i eth0 shows a live, per-connection bandwidth table: which host pairs are moving traffic and at what rate. The interface flag people forget, the -n and -P switches that make the output readable, the 2s/10s/40s columns, the filter syntax, and when nload or iftop is the right tool.