| name | pfsense |
| description | Manage the pfSense firewall at 10.0.20.1 via SSH. Use when:
(1) User asks about firewall rules, NAT, port forwarding,
(2) User asks about network diagnostics (ARP, routing, DNS, ping),
(3) User asks about DHCP leases or static mappings,
(4) User asks about VPN status (WireGuard, Tailscale),
(5) User asks about pfSense services (Snort, FRR/BGP/OSPF, etc.),
(6) User asks about firewall states, connections, or traffic,
(7) User mentions "pfsense", "firewall", "gateway", or network troubleshooting,
(8) User wants to check system health (CPU, memory, disk, temp) of pfSense.
pfSense CE 2.7.2 on FreeBSD 14.0, VMID 101 on Proxmox.
|
| author | Claude Code |
| version | 1.0.0 |
| date | "2026-02-14T00:00:00.000Z" |
pfSense Firewall Management
Overview
- Host:
10.0.20.1 (Kubernetes VLAN gateway)
- SSH:
ssh admin@10.0.20.1
- Version: pfSense CE 2.7.2, FreeBSD 14.0
- Proxmox VMID: 101 (8 CPU, 16GB RAM, 32G disk)
- Web UI:
https://pfsense.viktorbarzin.me (via reverse proxy) or https://10.0.20.1
- Installed packages: FRR (BGP/OSPF), Tailscale, Snort, WireGuard, REST API, FreeRADIUS
Interfaces
| Name | Description | Physical | IP | Network |
|---|
| wan | WAN | vtnet0 | 192.168.1.2/24 | Physical network |
| lan | Management VMs | vtnet1 | 10.0.10.1/24 | VLAN 10 |
| opt1 | Kubernetes | vtnet2 | 10.0.20.1/24 | VLAN 20 |
| opt2 | WireGuard | tun_wg0 | 10.3.2.1/24 | VPN tunnel |
| tailscale0 | Tailscale | tailscale0 | 100.64.0.x | Headscale mesh |
CLI Script
Script: .claude/pfsense.py
Execution Pattern
cd ~/code/infra && python3 .claude/pfsense.py <command> [options]
Available Commands
System Information
python3 .claude/pfsense.py status
python3 .claude/pfsense.py uptime
python3 .claude/pfsense.py cpu
python3 .claude/pfsense.py memory
python3 .claude/pfsense.py disk
python3 .claude/pfsense.py temp
python3 .claude/pfsense.py pkg-list
Network & Interfaces
python3 .claude/pfsense.py interfaces
python3 .claude/pfsense.py gateways
python3 .claude/pfsense.py arp
python3 .claude/pfsense.py routes
python3 .claude/pfsense.py dns-resolve <host>
python3 .claude/pfsense.py diag <host>
Firewall
python3 .claude/pfsense.py rules
python3 .claude/pfsense.py rules opt1
python3 .claude/pfsense.py nat
python3 .claude/pfsense.py aliases
python3 .claude/pfsense.py alias <name>
python3 .claude/pfsense.py states
python3 .claude/pfsense.py states-top 20
DHCP
python3 .claude/pfsense.py dhcp-leases
python3 .claude/pfsense.py dhcp-leases opt1
Services
python3 .claude/pfsense.py services
python3 .claude/pfsense.py service restart snort
python3 .claude/pfsense.py service stop wireguard
python3 .claude/pfsense.py service start wireguard
VPN & Routing
python3 .claude/pfsense.py wireguard
python3 .claude/pfsense.py tailscale
python3 .claude/pfsense.py bgp
python3 .claude/pfsense.py ospf
Security
python3 .claude/pfsense.py snort
python3 .claude/pfsense.py logs
python3 .claude/pfsense.py logs 200
python3 .claude/pfsense.py logs-filter "blocked"
Advanced
python3 .claude/pfsense.py pfctl "-sr"
python3 .claude/pfsense.py php "echo phpversion();"
python3 .claude/pfsense.py raw "ls /tmp"
python3 .claude/pfsense.py backup
Direct SSH Access
For tasks not covered by the script, SSH directly:
ssh admin@10.0.20.1 "<command>"
Useful Direct Commands
ssh admin@10.0.20.1 "php -r 'require_once(\"config.inc\"); \$cfg = parse_config(true); echo json_encode(\$cfg[\"nat\"], JSON_PRETTY_PRINT);'"
ssh admin@10.0.20.1 "pfSsh.php playback gatewaystatus"
ssh admin@10.0.20.1 "pfSsh.php playback svc restart snort"
ssh admin@10.0.20.1 "pfSsh.php playback listpkg"
ssh admin@10.0.20.1 "php -r 'require_once(\"config.inc\"); \$cfg = parse_config(true); print_r(\$cfg[\"filter\"][\"rule\"][0]);'"
ssh admin@10.0.20.1 "/usr/local/bin/vtysh -c 'show ip route'"
ssh admin@10.0.20.1 "/usr/local/bin/vtysh -c 'show bgp ipv4 unicast'"
REST API (pfSense-pkg-RESTAPI v2.2)
The REST API package is installed but no API keys are configured. To use it:
- Create an API key in pfSense Web UI: System > REST API > Settings > Keys
- Use Bearer token auth:
curl -sk https://10.0.20.1/api/v2/status/system -H 'Authorization: Bearer <key>'
Until API keys are set up, use SSH for all operations.
Key Services
| Service | Status | Notes |
|---|
| FRR (BGP/OSPF) | Running | Routing daemon |
| Snort | Running | IDS/IPS |
| WireGuard | Running | VPN tunnel (10.3.2.0/24) |
| Tailscale | Running | Mesh VPN via Headscale |
| FreeRADIUS | Running | RADIUS auth |
| DHCP (Kea) | Running | kea-dhcp4 |
| SSH | Running | Admin access |
| NTP | Running | Time sync |
Firewall Stats
- 167 firewall rules (pfctl -sr)
- 154 NAT rules (pfctl -sn)
- ~784 active states (varies)
- 10 aliases (LAN, OPT1, OPT2, WAN networks + custom)
NFS Backup
Config backups stored at NFS: /mnt/main/pfsense-backup
Troubleshooting
| Issue | Command |
|---|
| Can't reach internet from K8s | python3 .claude/pfsense.py gateways + python3 .claude/pfsense.py diag 8.8.8.8 |
| K8s pod can't reach external | python3 .claude/pfsense.py rules opt1 + check NAT |
| DHCP not working | python3 .claude/pfsense.py dhcp-leases opt1 + python3 .claude/pfsense.py service restart kea-dhcp4 |
| High connection count | python3 .claude/pfsense.py states-top 20 |
| Snort blocking traffic | python3 .claude/pfsense.py snort + check alerts |
| DNS resolution failing | python3 .claude/pfsense.py dns-resolve <host> |
| BGP/OSPF routes missing | python3 .claude/pfsense.py bgp or python3 .claude/pfsense.py ospf |
| WireGuard tunnel down | python3 .claude/pfsense.py wireguard |
Notes
- FreeBSD-based: Commands differ from Linux (no
ip, use ifconfig, netstat, arp)
- pfctl is the firewall: Rules loaded from config.xml via PHP, managed by pfctl
- Config file:
/cf/conf/config.xml — all pfSense config in one XML file
- PHP shell: pfSense uses PHP for all config management;
config.inc loads the config
- Do NOT edit config.xml directly — use the Web UI or PHP functions that properly reload services
- Logs: Binary circular logs, read with
clog -f /var/log/<logfile>