--- type: system name: pfsense display_name: pfsense (ACG Gateway/Firewall) last_compiled: 2026-06-21 compiled_by: HOWARD-HOME/claude-main sources: - session-logs/2026-05-25-session.md - session-logs/2026-06/2026-06-21-howard-unifi-pfsense-control-verbs.md backlinks: - 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) ```bash ssh -p 2248 @172.16.0.1 # From outside LAN, use Tailscale IP: ssh -p 2248 @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//pfsense-api`) is a dormant fallback. **Scripts** (in `.claude/skills/unifi-wifi/scripts/`): - `pfsense-ssh.sh ` — 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//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 ""`. - Writes (DRY-RUN default; add `--apply` to commit — backs up `config.xml`, then `write_config` + filter reload): - `fw-disable|fw-enable ` — toggle a filter rule. **Validated live.** - `block-ips|unblock [--if wan]` — via `easyrule`. **Validated live.** - `pf-disable|pf-enable|pf-delete `, `pf-set-ports []`, `pf-set-src ` — 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 ` 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 `. - 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. --- ## Backlinks - [[systems/uos-server]] — the UniFi side of the `unifi-wifi` skill (controller + WiFi/switch tooling). - [[clients/cascades-tucson]] — pfSense Plus 25.07; the box the SSH gateway-control layer was validated against. - [[systems/jupiter]], [[systems/gururmm-build]] — depend on this gateway for routing.