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 --helpfor 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.confand the anchor file are world-readable. - Writing configuration and reloading PF (
block,unblock,set,allow,deny,icmp) requires sudo. The CLI commands invokesudoas 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).