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) orhttps://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 # Full system overview
python3 .claude/pfsense.py uptime # Uptime
python3 .claude/pfsense.py cpu # CPU info and load
python3 .claude/pfsense.py memory # Memory breakdown
python3 .claude/pfsense.py disk # Disk usage
python3 .claude/pfsense.py temp # CPU temperature
python3 .claude/pfsense.py pkg-list # Installed packages
Network & Interfaces
python3 .claude/pfsense.py interfaces # Interface list with IPs
python3 .claude/pfsense.py gateways # Gateway status
python3 .claude/pfsense.py arp # ARP table
python3 .claude/pfsense.py routes # Routing table
python3 .claude/pfsense.py dns-resolve <host> # DNS lookup via pfSense
python3 .claude/pfsense.py diag <host> # Ping test
Firewall
python3 .claude/pfsense.py rules # All firewall rules
python3 .claude/pfsense.py rules opt1 # Rules for Kubernetes interface
python3 .claude/pfsense.py nat # NAT / port forwarding rules
python3 .claude/pfsense.py aliases # List all aliases
python3 .claude/pfsense.py alias <name> # Show alias members
python3 .claude/pfsense.py states # State table summary
python3 .claude/pfsense.py states-top 20 # Top 20 IPs by connection count
DHCP
python3 .claude/pfsense.py dhcp-leases # All DHCP leases
python3 .claude/pfsense.py dhcp-leases opt1 # Kubernetes network leases only
Services
python3 .claude/pfsense.py services # List all services + status
python3 .claude/pfsense.py service restart snort # Restart a service
python3 .claude/pfsense.py service stop wireguard # Stop a service
python3 .claude/pfsense.py service start wireguard # Start a service
VPN & Routing
python3 .claude/pfsense.py wireguard # WireGuard tunnel status
python3 .claude/pfsense.py tailscale # Tailscale/Headscale status
python3 .claude/pfsense.py bgp # BGP summary (FRR)
python3 .claude/pfsense.py ospf # OSPF neighbors (FRR)
Security
python3 .claude/pfsense.py snort # Snort IDS status + recent alerts
python3 .claude/pfsense.py logs # Last 50 firewall log entries
python3 .claude/pfsense.py logs 200 # Last 200 entries
python3 .claude/pfsense.py logs-filter "blocked" # Search logs
Advanced
python3 .claude/pfsense.py pfctl "-sr" # Raw pfctl command
python3 .claude/pfsense.py php "echo phpversion();" # Run PHP on pfSense
python3 .claude/pfsense.py raw "ls /tmp" # Run arbitrary shell command
python3 .claude/pfsense.py backup # Dump config.xml to stdout
Direct SSH Access
For tasks not covered by the script, SSH directly:
ssh admin@10.0.20.1 "<command>"
Useful Direct Commands
# pfSense PHP shell (interactive config access)
ssh admin@10.0.20.1 "php -r 'require_once(\"config.inc\"); \$cfg = parse_config(true); echo json_encode(\$cfg[\"nat\"], JSON_PRETTY_PRINT);'"
# pfSsh.php playback commands
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"
# Config sections via PHP
ssh admin@10.0.20.1 "php -r 'require_once(\"config.inc\"); \$cfg = parse_config(true); print_r(\$cfg[\"filter\"][\"rule\"][0]);'"
# FRR/vtysh for routing
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, useifconfig,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.incloads 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>