Skip to content

Usage

wj-firewall provides two interfaces: an interactive terminal UI (TUI) and a command-line interface (CLI). Both read from and write to the same PF anchor file, so changes made in one are visible in the other.

Interactive TUI

Launch the TUI by running wj-firewall with no arguments:

wj-firewall

Or via module:

python -m wj_firewall

You will be prompted for your password (sudo) before the TUI appears.

Layout

The TUI displays:

  • Title bar — application name, version, and a hint to run wj-firewall --help for CLI usage
  • Status indicators — whether PF is enabled and whether the anchor is configured in pf.conf
  • Interface table — all detected network interfaces with their IP addresses and firewall state
  • Help bar — available key bindings
  • Status area — feedback messages after actions

Interface Table Columns

Column Description
Interface System name and description (e.g. en0 (Wi-Fi))
IP Address IPv4 address, or [IPv6] if only IPv6 is assigned
Incoming BLOCKED (red) or allowed (dim)
ICMP block (red) if ICMP is blocked on a blocked interface
Open Ports Comma-separated list of allowed port numbers

Key Bindings

Key Action
/ k Move cursor up
/ j Move cursor down
Space Toggle block incoming on the selected interface
p Enter port editing mode (only on blocked interfaces)
i Toggle ICMP blocking (only on blocked interfaces)
a Apply changes — write anchor file and reload PF
r Revert — discard changes and restore last applied state
q Quit (prompts for confirmation if there are unsaved changes)

Port Editing Mode

Press p on a blocked interface to enter port editing mode. The help bar changes to a port input prompt:

Port: ___█  (Enter=toggle  i=ICMP  Esc=cancel)
  • Type a port number (1–65535) and press Enter to toggle it (add if absent, remove if present)
  • Press i to toggle ICMP blocking without leaving port editing mode
  • Press Esc to exit port editing mode
  • The mode stays open after each port toggle for quick multi-port entry

Applying Changes

Changes in the TUI are not written to disk until you press a (Apply). This writes the anchor file, ensures pf.conf references the anchor, enables PF if needed, and reloads the ruleset.

If PF is disabled or the anchor is missing from pf.conf, pressing a will fix both automatically.

Command-Line Interface

The CLI provides subcommands for scripting and quick one-off changes. All commands that modify rules require sudo.

status — Show current state

wj-firewall status

Displays a table of all network interfaces with their block state, ICMP state, and open ports. Also shows whether PF is enabled and whether the anchor is configured.

block — Block incoming traffic

wj-firewall block en0
wj-firewall block en0 en1

Blocks incoming traffic on one or more interfaces. If the interface is already blocked, no change is made. Applies immediately.

unblock — Remove blocking

wj-firewall unblock en0

Removes blocking from an interface. Also clears any port exceptions and ICMP settings for that interface. Applies immediately.

set — Set exact blocked list

wj-firewall set en0 en1    # Block exactly en0 and en1
wj-firewall set             # Unblock everything

Sets the blocked interface list to exactly the given interfaces. Any previously blocked interfaces not in the list are unblocked. Preserves port exceptions and ICMP settings for interfaces that remain blocked.

allow — Open ports

wj-firewall allow en0 22
wj-firewall allow en0 22 80 443

Opens specific ports on a blocked interface. If the interface is not already blocked, it will be blocked first. Both TCP and UDP pass rules are generated for each port. Applies immediately.

deny — Close ports

wj-firewall deny en0 80
wj-firewall deny en0 80 443

Removes port exceptions from a blocked interface. Applies immediately.

icmp — Control ICMP

wj-firewall icmp en0 block    # Block ICMP (ping, traceroute)
wj-firewall icmp en0 allow    # Allow ICMP (default)

By default, blocked interfaces allow ICMP through (ping, traceroute, PMTU discovery). Use icmp block to suppress all ICMP on an interface.

Common Options

All subcommands support:

  • --no-colour / --no-color — disable coloured terminal output
  • --help — show help for the subcommand

Privilege Requirements

  • Reading configuration (status) does not require elevated privileges — pf.conf and the anchor file are world-readable.
  • Writing configuration and reloading PF (block, unblock, set, allow, deny, icmp) requires sudo. The CLI commands invoke sudo as needed.
  • TUI prompts for sudo credentials before entering curses mode, so the password prompt appears in the normal terminal.

Generated PF Rules

For a blocked interface en0 with ports 22 and 80 allowed and ICMP permitted (default), the generated anchor file contains:

# en0 — block incoming (22, 80)
pass out quick on en0 all keep state
pass in quick on en0 proto udp from any port 67 to any port 68 keep state
pass in quick on en0 proto icmp all keep state
pass in quick on en0 proto tcp from any to any port 22 keep state
pass in quick on en0 proto udp from any to any port 22 keep state
pass in quick on en0 proto tcp from any to any port 80 keep state
pass in quick on en0 proto udp from any to any port 80 keep state
block drop in quick on en0 all

If ICMP is blocked, the pass in ... proto icmp line is omitted. The comment changes to (no ICMP, 22, 80).