Skip to content

FreeSnitch 0.3.0

Choose a tag to compare

@isaaclins isaaclins released this 13 Aug 18:17
· 92 commits to main since this release

FreeSnitch is an open-source macOS application firewall. It shows you which processes reach the network, where they connect, and lets you decide what happens next. Everything stays on your Mac: no account, no telemetry, no phone-home.

This is the first public release.

Install

  1. Download FreeSnitch.dmg below, open it, and drag FreeSnitch to Applications.
  2. Launch FreeSnitch and approve the system extension when macOS asks. Approval happens in System Settings, under Login Items and Extensions, Network Extensions.
  3. Approve the privileged helper once. The helper is what enforces policy, including before you log in.

The app is signed with a Developer ID and notarized by Apple, so Gatekeeper accepts it without any right-click workaround. Verify that yourself before trusting it:

spctl --assess --type execute --verbose /Applications/FreeSnitch.app
codesign --verify --strict --deep --verbose=2 /Applications/FreeSnitch.app
xcrun stapler validate /Applications/FreeSnitch.app

Requires macOS 13 Ventura or later.

What you get

  • A live map of outbound connections, grouped by process, with byte counts, destination, country, and port.
  • Alert mode, which asks before a new connection is allowed, and Silent Allow, which records without interrupting you.
  • Rules by process, hostname, IP, CIDR range, and port, with priorities, temporary rules, and groups.
  • A DNS proxy with DNS-over-HTTPS upstreams and domain blocklists.
  • Kernel-level enforcement through a pfctl anchor for IP, CIDR, and port rules, alongside the per-flow network extension.
  • A full command line interface, freesnitch, covering rules, status, diagnostics, and import/export.
  • Policy at boot, so rules apply between startup and your first login instead of leaving a gap.

Safety model

A firewall that fails badly is worse than no firewall, so the failure behavior is explicit and tested:

  • The filter fails open. If it cannot reach policy, traffic is allowed rather than silently cutting your machine off the network.
  • Loopback, the app's own traffic, DHCP, and your configured DNS resolvers are never blocked, so a bad rule cannot lock you out of your own network stack.
  • XPC channels carrying policy validate the peer's code signature, so an unsigned local process cannot inject rules.
  • Rule payloads are bounded before they are decoded in privileged processes, by byte count, rule count, and per-field length, and the transport, boot, and import limits are consistent with each other.
  • The helper owns the authoritative policy snapshot, so the GUI cannot overwrite a CLI change with stale state.
  • DNS policy is published as one atomic snapshot, so a query is never judged against a mixture of old and new rules, and is verified race-free under ThreadSanitizer.
  • Rule backups use one versioned file contract shared by the GUI and CLI, validated as a whole before anything is written, so an import is all-or-nothing.
  • The helper reports the build it is actually running, separately from the build installed on disk, so an update that leaves a stale privileged daemon behind is surfaced with its exact fix instead of being hidden.

All of this is enforced by a safety audit and four verification harnesses that must pass before a release can be built.

Known limitations

Read these before relying on it:

  • Blocklists filter DNS names only, and only while Enforcement is on. Software that connects to hardcoded IP addresses, or resolves names through its own encrypted DNS such as Chrome or Firefox DoH, is not stopped by a blocklist. Per-process, IP, CIDR, and port rules still apply. See #22 and #51.
  • No traffic history view yet. Grouping who talks to what over time, and proposing rules from it, is designed but not shipped: #23.
  • The CLI cannot answer pending connection alerts yet: #25.
  • Profiles are not implemented yet: #31.
  • Rule policy is bounded at 4096 rules for live delivery and 800 rules for the pre-login boot snapshot. Exceeding the boot limit is reported rather than silently truncated.

Uninstall

FreeSnitch installs a privileged helper and a system extension, so dragging the app to the Trash is not enough. From a checkout of this tag:

sudo Scripts/uninstall_freesnitch.sh --yes

That deactivates the system extension, unloads and removes the helper, flushes the pfctl anchor, and removes the app.

Verify what you are running

FreeSnitch is auditable on purpose. The source for this build is the v0.3.0 tag, and you can build and sign it yourself with Scripts/release.sh. The safety properties above live in Scripts/audit_firewall_safety.sh, which you can run against the source to confirm the claims in this document are actually enforced.