Files
claudetools/wiki/systems/pfsense.md

6.2 KiB
Raw Blame History

type, name, display_name, last_compiled, compiled_by, sources, backlinks
type name display_name last_compiled compiled_by sources backlinks
system pfsense pfsense (ACG Gateway/Firewall) 2026-06-21 HOWARD-HOME/claude-main
session-logs/2026-05-25-session.md
session-logs/2026-06/2026-06-21-howard-unifi-pfsense-control-verbs.md
systems/gururmm-build
systems/jupiter
systems/uos-server
clients/cascades-tucson

pfsense (ACG Gateway/Firewall)

Two things live under this article: (1) the ACG office pfSense gateway (172.16.0.1), and (2) the fleet-wide pfSense management tooling that now ships in the unifi-wifi skill — an SSH backend that audits and controls ANY client pfSense, not just the office box. See systems/uos-server for the UniFi side of the same skill.

Identity (ACG office gateway)

Field Value
Role Primary gateway, firewall, and router for ACG office LAN
LAN IP 172.16.0.1
SSH port 2248
Tailscale IP 100.119.153.74
OS FreeBSD (pfSense)

Network

Interface Subnet Notes
LAN 172.16.0.0/22 ACG office LAN (172.16.0.x 172.16.3.x)
WAN (DHCP/static from ISP) External IP 98.181.90.163 (as seen from Tailscale)
Tailscale 100.119.153.74 Active peer, direct connection

pfsense is the default gateway for all ACG LAN devices. The build server (172.16.3.30) has via 172.16.0.1 as its default route.


Tailscale

pfsense is a Tailscale peer (active; direct 98.181.90.163:41641). It serves as the Tailscale subnet router for the ACG LAN. LAN machines route Tailscale traffic (100.0.0.0/8) through pfsense.

Build server static route (added 2026-05-25):

172.16.3.30 → 100.0.0.0/8 via 172.16.0.1

Persisted in /etc/netplan/00-installer-config.yaml on the build server. This allows the GuruRMM server to reach Beast's Ollama at 100.101.122.4:11434.


SSH Access (office box)

ssh -p 2248 <user>@172.16.0.1
# From outside LAN, use Tailscale IP:
ssh -p 2248 <user>@100.119.153.74

Management Tooling — unifi-wifi pfSense SSH backend

The unifi-wifi skill includes a pfSense gateway compatibility layer: the same gateway verbs it exposes for UniFi gateways (gw-audit / gw-control) now route to a pfSense over SSH when a site has no UniFi gateway. Decision (Mike, 2026-06-16): SSH only — no RESTAPI package needed. The REST backend (pfsense-backend.sh, clients/<slug>/pfsense-api) is a dormant fallback.

Scripts (in .claude/skills/unifi-wifi/scripts/):

  • pfsense-ssh.sh <slug> <verb> — entry point; talks to the box over system OpenSSH via askpass.
  • pfsense-gwc.php — argv-driven config helper, shipped to the box per-call (base64 over the wire) and run under php, which bootstraps $config + write_config() + filter_configure() via require_once("config.inc").

Cred convention: clients/<slug>/pfsense-firewall in the vault — top-level host, credentials.username, credentials.password.

Verbs:

  • Reads (no gate): audit (WAN/DHCP/states/DNS/NIC health), dhcp (pool pressure), pf-list (NAT port-forwards), fw-list (filter rules), showblock [--if wan], run "<cmd>".
  • Writes (DRY-RUN default; add --apply to commit — backs up config.xml, then write_config + filter reload):
    • fw-disable|fw-enable <tracker|descr> — toggle a filter rule. Validated live.
    • block-ips|unblock <ip[,ip,...]> [--if wan] — via easyrule. Validated live.
    • pf-disable|pf-enable|pf-delete <tracker|descr>, pf-set-ports <dst> [<local>], pf-set-src <cidr|any> — port-forwards (+ associated filter rule). Built; live-verify pending (needs a box that has port-forwards).
  • Filter rules are matched by tracker (the id field is empty on pf25.07) or exact descr.

Dispatch: gw-audit.sh / gw-control.sh prefer this SSH backend (keyed on the pfsense-firewall cred) and run the dispatch BEFORE UOS site resolution, so a pfSense-only client slug works without a matching UOS site name (pass --pfsense <slug> if the names differ).

Caveat for THIS office box: pfsense-ssh.sh currently assumes SSH port 22; the ACG office pfSense listens on 2248, so the skill needs a port option before it can manage the office gateway. Cred for it is vaulted at infrastructure/pfsense-firewall (verify).

pfSense PHP gotchas (baked into the scripts; carry forward to any new helper):

  • Bootstrap with require_once("config.inc") ONLY — re-requiring util/functions/filter → "cannot redeclare" fatal. It already provides write_config()/filter_configure().
  • display_errors is Off — php fatals are silent (rc=255, no message). Run php with 2>&1 and ini_set("display_errors","1").
  • pfSense already defines backup_config() (and many generic names) → prefix helper functions.
  • pfSsh.php does NOT eval piped ad-hoc code (only its built-in playback scripts) — use php <file>.
  • Ship the helper with base64 | openssl base64 -A -d (both present on FreeBSD).

Known Issues & Quirks

  • easyrule leaves residue: once used, it persists a 'Blocked via EasyRule' WAN rule + an EasyRuleBlockHostsWAN alias even after unblock empties the alias. Inert (empty alias blocks nothing) but visible in fw-list. One such artifact was left on Cascades pfSense by the 2026-06-21 validation (pending operator decision to remove).
  • Office box is on SSH port 2248, not 22 — see the tooling caveat above.

Key Rules

  • Do not restart or apply firewall rules without user confirmation — the office pfsense is the single point of failure for the entire ACG LAN.
  • Any changes to NAT, firewall rules, or routing should be confirmed before applying.
  • The unifi-wifi write verbs are DRY-RUN by default; --apply is required to commit and each write backs up config.xml first. pfSense also keeps its own config history.