Skip to main content

macOS PF (Packet Filter) firewall configuration TUI

Project description

wj-firewall

A macOS PF (Packet Filter) firewall configuration tool with both an interactive terminal UI and a command-line interface.

wj-firewall is not a firewall itself — it configures macOS's built-in PF packet filter. It makes it easy to block incoming traffic on specific network interfaces while keeping others open. The typical use case is blocking incoming connections on Wi-Fi while keeping Tailscale or other trusted networks open, so services listening on 0.0.0.0 are only reachable from trusted networks.

Features

  • Interactive TUI — curses-based terminal UI for visual interface management
  • CLI — scriptable command-line interface for automation and quick changes
  • Per-interface blocking — block incoming traffic on selected interfaces
  • Port exceptions — allow specific ports through on blocked interfaces (TCP + UDP)
  • ICMP control — optionally block ICMP (ping, traceroute) on blocked interfaces
  • PF anchors — rules stored in /etc/pf.anchors/wj-firewall, surviving OS updates
  • Zero dependencies — Python 3.12+ stdlib only

Requirements

  • Python 3.12+
  • macOS (uses PF and pfctl)
  • Administrator privileges (sudo) for applying firewall rules

Installation

pip install wj-firewall

Or run directly with uv:

uvx wj-firewall

Quick Start

Interactive TUI

wj-firewall

You will be prompted for your password (sudo). The TUI shows all network interfaces and lets you:

  • Space — toggle "block incoming" on the selected interface
  • p — open port editing mode (add/remove port exceptions)
  • i — toggle ICMP blocking on a blocked interface
  • a — apply changes (writes anchor file and reloads PF)
  • r — revert to last applied state
  • q — quit (confirms if unsaved changes)

Command-Line Interface

# Show current firewall status
wj-firewall status

# Block incoming traffic on Wi-Fi
wj-firewall block en0

# Allow SSH and HTTP through on a blocked interface
wj-firewall allow en0 22 80

# Block ICMP (ping) on an interface
wj-firewall icmp en0 block

# Remove a port exception
wj-firewall deny en0 80

# Unblock an interface
wj-firewall unblock en0

How It Works

wj-firewall uses macOS PF anchors to manage firewall rules without touching the rest of your pf.conf. Rules are stored in /etc/pf.anchors/wj-firewall and referenced from pf.conf via anchor declarations. The tool automatically adds the anchor references if they are missing.

For each blocked interface, the following PF rules are generated:

  1. Pass outgoing — all outbound traffic and return traffic is allowed
  2. Pass DHCP — DHCP discovery is always allowed (so you can get an IP address)
  3. Pass ICMP — ping, traceroute, and PMTU discovery are allowed (unless ICMP is blocked)
  4. Pass ports — any port exceptions are allowed through (both TCP and UDP)
  5. Block everything else — all other incoming traffic is silently dropped

Rules use quick for first-match-wins evaluation and block drop (silent discard) to avoid triggering macOS Private Relay issues.

Development

# Set up development environment
make dev

# Run linting and type checking
make check

# Auto-format code
make format

# Build wheel and docs
make build

Licence

Released under the Unlicense — public domain.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wj_firewall-1.0.0b5-py3-none-any.whl (41.4 kB view details)

Uploaded Python 3

File details

Details for the file wj_firewall-1.0.0b5-py3-none-any.whl.

File metadata

  • Download URL: wj_firewall-1.0.0b5-py3-none-any.whl
  • Upload date:
  • Size: 41.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for wj_firewall-1.0.0b5-py3-none-any.whl
Algorithm Hash digest
SHA256 37cf5a2f2c235e9e83eeee74f3b47d87f3f92c89ae71f0c4f3e635baf58fcaad
MD5 a2d6ebf78bd2d078a95eb16fc967c6b6
BLAKE2b-256 db8243899a76128b2ee240a2026d3602c23ef2b7e42244fd483d2eca006fccb8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page