Skip to main content

Network Edge & Security (OPNsense)

Source: Anshin Engineering, Rev 1.0, 2026-03-22

This document covers the OPNsense high-availability firewall pair that forms the secure perimeter of the Anshin Health network. All ingress and egress traffic passes through this layer before reaching internal infrastructure.

No License Fees โ€” Ever

OPNsense is free and open-source (BSD license). Every feature โ€” IDS/IPS, VPN, HAProxy, HA failover, REST API โ€” is included at zero cost. There are no subscription tiers, no feature paywalls, and no vendor lock-in. This is a deliberate policy: Anshin will not pay recurring firewall/security licensing fees.


Why OPNsenseโ€‹

RequirementOPNsense
HIPAA-compliant audit loggingโœ… Full flow logging โ†’ syslog โ†’ Graylog
IDS/IPSโœ… Suricata + ET Open rules (free)
Dual WAN / multi-WAN failoverโœ… Gateway Groups (built-in)
HA failover (zero downtime)โœ… CARP โ€” sub-2-second failover
VPN (WireGuard + OpenVPN)โœ… Built-in, zero config UI
Load balancingโœ… HAProxy plugin (free)
REST API for automationโœ… Full JSON API on all settings
Web GUI accessible to non-DevOps usersโœ… Excellent UI, wizard-driven
Infrastructure-as-Code (Claude Code)โœ… Ansible + REST API + git XML backup
License costโœ… $0 forever

Two identical nodes run in a CARP high-availability pair. If the primary fails, the secondary takes over automatically in under 2 seconds โ€” no manual intervention, no session drops for existing TCP connections.

SpecValue
ModelBeelink EQ12 Pro
CPUIntel N100 (4-core, 3.4 GHz, 6W TDP)
RAM16GB DDR5
NIC 1Intel i226-V 2.5GbE (WAN)
NIC 2Intel i226-V 2.5GbE (LAN trunk to switches)
Storage500GB NVMe (OPNsense OS + logs)
Power~12โ€“20W at idle
Cost$170โ€“180 each ($350 for the pair)
Intel NICs Required

OPNsense requires Intel network interface chipsets (i226, i225, i350, etc.) for production stability. Realtek NICs (found in cheaper mini-PCs) cause packet drops and instability under load. The Beelink EQ12 Pro ships with Intel i226-V NICs โ€” verify this before ordering.

Why not the TP-Link ER7412-M2? The ER7412-M2 is a Layer 3 SDN routing appliance โ€” suitable for inter-VLAN routing inside a trusted network. It is not a stateful security firewall. It lacks IDS/IPS, full audit logging, HA failover (CARP), and API depth. OPNsense provides all of this at lower total cost (~$350 for the HA pair vs. $399 for a single ER7412-M2 with no HA). The Omada SDN switches (SX3008F, SG3428, SG3452) are retained โ€” only the ER router is dropped.


Network Topologyโ€‹

Internet
โ”‚
โ”œโ”€โ”€ Fiber WAN A (primary) e.g. 65.182.226.97/29
โ””โ”€โ”€ Fiber WAN B (secondary) e.g. second fiber circuit
โ”‚
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ OPNsense HA Pair (CARP Virtual IPs) โ”‚
โ”‚ โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ opnsense-01 PRIMARY โ”‚ 10.10.96.51 โ”‚
โ”‚ โ”‚ BeeLink EQ12 Pro #1 โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ”‚ CARP sync link (dedicated cat6)โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ opnsense-02 STANDBY โ”‚ 10.10.96.52 โ”‚
โ”‚ โ”‚ BeeLink EQ12 Pro #2 โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ”‚
โ”‚ CARP VIP (LAN gateway): 10.10.96.1 โ”‚
โ”‚ CARP VIP (WAN): 65.182.226.97 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚ 2.5GbE โ†’ TL-SX3008F-01 (network plane)
โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Omada Switch Fabric โ”‚
โ”‚ SX3008F-01 (10G network) โ”‚
โ”‚ SX3008F-02 (10G storage) โ”‚
โ”‚ SG3428-01 (1G access) โ”‚
โ”‚ SG3428-02 (1G access) โ”‚
โ”‚ SG3452 (homestead) โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

CARP behavior: The two OPNsense nodes share a Virtual IP (VIP) via CARP (Common Address Redundancy Protocol, RFC 3768). All downstream devices use the VIP as their gateway โ€” they never need to know which physical node is active. Failover is automatic and sub-2-second.


OPNsense Features in Useโ€‹

Dual WAN โ€” Failover and Load Balancingโ€‹

OPNsense Gateway Groups handle multi-WAN natively:

Gateway Group: WAN_FAILOVER
Tier 1: Fiber WAN A (primary โ€” lowest latency, full bandwidth)
Tier 2: Fiber WAN B (failover โ€” activates if Fiber A fails)

Gateway Group: WAN_LOADBALANCE (optional)
Tier 1: Fiber WAN A (equal weight)
Tier 1: Fiber WAN B (equal weight โ€” round-robin across both circuits)

Health monitoring: OPNsense pings configurable targets (e.g., 8.8.8.8, 1.1.1.1) every 500ms per WAN. If a gateway fails its health check, traffic automatically shifts to the next tier โ€” no manual intervention.

A third WAN (cable broadband) can be added later as Tier 3 by configuring a USB โ†’ Ethernet adapter on each BeeLink node.

IDS/IPS โ€” Suricata with ET Open Rulesโ€‹

Inline IDS/IPS powered by Suricata with Emerging Threats Open ruleset (free, updated daily):

SettingValue
EngineSuricata
RulesetET Open (free)
ModeInline IPS (block mode)
InterfaceWAN (inspect inbound before routing)
Update scheduleDaily auto-update

HIPAA relevance: All IDS alerts are logged with source IP, destination, rule name, and timestamp. Forwarded to Graylog for 90-day retention and search.

VPN โ€” WireGuard (Primary) + OpenVPN (Legacy)โ€‹

WireGuard for all new VPN clients (Bryan, Marc, remote staff):

  • Sub-100ms setup per new peer
  • Apps available: Windows, macOS, iOS, Android
  • QR code provisioning: scan and connected in 30 seconds
  • HIPAA-compliant: all traffic encrypted (ChaCha20-Poly1305)

OpenVPN available for legacy devices or clients that cannot run WireGuard.

Split tunneling optional: configure so only lab traffic routes through VPN, internet stays local.

Load Balancing โ€” HAProxy (Built-In)โ€‹

HAProxy is available as a free OPNsense plugin. It can:

  • Load balance HTTP/HTTPS to multiple backends (e.g., multiple K8s ingress replicas)
  • Health check backends and automatically remove failed nodes
  • Terminate SSL (using the ZeroSSL wildcard certs)
  • Replace a dedicated load-balancer pair (the "2 BeeLinks as LBs" idea is not needed if HAProxy handles it)

Firewall Rules โ€” Zone-Based Policyโ€‹

OPNsense uses interfaces + rules, equivalent to zone-based firewall:

ZoneInterfaceDefault Policy
WANFiber WAN A/BBlock all inbound (allowlist only)
LANInternal VLAN trunkPermit internal, inspect with IDS
VLAN_MGMT (100)OOB managementBlock from other VLANs; iLO/UPS only
VLAN_STORAGE (300/400)Storage planesBlock from all except compute VLANs
PHI_ISOLATEDDedicated VLAN (TBD)Strict egress, full logging, no internet
VPNWireGuard/OpenVPNLimited access per user group

HIPAA Compliance Implementationโ€‹

Audit Logging Pipelineโ€‹

OPNsense (firewall logs, IDS alerts, auth events)
โ”‚
โ”‚ syslog/UDP to Graylog input (10.10.x.x:5514)
โ–ผ
Graylog (K8s โ€” infra namespace)
โ”‚
โ”œโ”€โ”€ Index: firewall-logs (90-day retention)
โ”œโ”€โ”€ Index: ids-alerts (90-day retention)
โ””โ”€โ”€ Index: vpn-auth (90-day retention)
โ”‚
โ–ผ
QNAP NFS (qnap-01) โ€” long-term archive (1-year retention)

What is logged:

  • Every connection allowed/denied (source IP, destination, port, protocol, bytes, timestamp)
  • Every IDS/IPS alert (rule triggered, severity, action taken)
  • Every VPN authentication (user, timestamp, source IP, session duration)
  • OPNsense admin logins and configuration changes

HIPAA audit control (ยง164.312(b)): Logs are write-once to Graylog + NFS. Admin cannot delete individual log entries without MongoDB access. All access to Graylog is VPN-only.

PHI Network Isolationโ€‹

When PHI-processing systems come online, they will be placed on a dedicated PHI_ISOLATED VLAN with:

  • No direct internet access (all egress through a proxy)
  • Full firewall logging (every packet)
  • Encrypted at rest (Ceph encryption for block volumes)
  • Encrypted in transit (mTLS between services, TLS 1.3 only)
  • IDS in inline mode on the VLAN interface

Encryption Standardsโ€‹

ConnectionProtocolMinimum TLS
WAN (external clients)TLS 1.3 (ZeroSSL ECDSA certs)1.3
VPN (remote access)WireGuard ChaCha20-Poly1305N/A
Inter-service (K8s)mTLS (SPIFFE/SPIRE, planned)1.3
Admin accessSSH key-only, TOTP on web UIN/A

Infrastructure-as-Code & Claude Code Integrationโ€‹

Configuration Backup in Gitโ€‹

OPNsense exports its entire configuration as a single XML file. This is committed to sre-iac (Ansible Vault encrypted) after every change:

# Export config from running node (via API)
curl -k -u admin:$OPNSENSE_KEY https://opnsense-01/api/core/backup/download/this \
> opnsense-01-$(date +%Y%m%d).xml

# Encrypt and commit
ansible-vault encrypt opnsense-01-$(date +%Y%m%d).xml
git add opnsense-01-$(date +%Y%m%d).xml
git commit -m "chore(network): OPNsense config backup $(date +%Y-%m-%d)"

This means the entire firewall config is version-controlled, reviewable in git, and can be restored from scratch in minutes.

OPNsense REST APIโ€‹

Every OPNsense setting is configurable via REST API (JSON over HTTPS). No GUI click required for any operation:

# Add a firewall rule
curl -k -u $API_KEY:$API_SECRET \
-X POST https://opnsense-01/api/firewall/filter/addRule \
-H "Content-Type: application/json" \
-d '{"rule": {"interface": "lan", "type": "pass", "source_net": "10.10.97.0/24", "destination_net": "10.10.98.0/24", "description": "K8s worker to K8s service subnet"}}'

# Apply changes
curl -k -u $API_KEY:$API_SECRET \
-X POST https://opnsense-01/api/firewall/filter/apply

MCP Server for Claude Code (Planned)โ€‹

A lightweight mcp-opnsense MCP server (Bun/TypeScript, hosted in K8s mcp-servers namespace) will expose the OPNsense API as Claude tools:

MCP ToolAction
add_firewall_rule(description)Bryan describes the rule in plain English, Claude constructs and applies it
block_ip(ip, reason)Instant IP block โ€” threat response in seconds
show_active_ids_alerts()See what Suricata is detecting right now
provision_vpn_user(name)New employee gets WireGuard config + QR code
show_traffic_summary(hours)See top talkers, bandwidth by host
get_firewall_logs(filter)Search audit logs for HIPAA investigations
check_wan_status()Which WAN is active, latency, packet loss

This means Bryan can type in Claude: "Block all traffic from 192.0.2.0/24 โ€” suspicious scan" and it happens. No GUI needed.


Initial Setup Procedureโ€‹

# Download OPNsense ISO from opnsense.org (verify SHA256)
# Flash to USB: dd if=OPNsense-24.x-dvd-amd64.iso of=/dev/sdX bs=4M

# Boot each BeeLink from USB
# Run installer โ†’ target: NVMe drive
# Repeat for both nodes

2. Configure opnsense-01 (Primary)โ€‹

Via console or direct browser to https://192.168.1.1 (default):

  1. System โ†’ General: Set hostname opnsense-01.anshinhealth.net, domain, DNS
  2. Interfaces โ†’ WAN: Assign NIC 1 โ†’ Fiber WAN A (static or DHCP per ISP)
  3. Interfaces โ†’ LAN: Assign NIC 2 โ†’ 2.5GbE to Omada switch fabric
  4. Interfaces โ†’ WAN2: Add second WAN for Fiber B (USB Ethernet or additional NIC)
  5. Firewall โ†’ NAT: Configure outbound masquerade for all VLANs
  6. VPN โ†’ WireGuard: Generate server keypair, configure peer for each VPN client
  7. Services โ†’ Intrusion Detection: Enable Suricata, select ET Open, enable inline mode
  8. System โ†’ High Availability: Enable CARP, configure sync interface and pre-shared key

3. Configure opnsense-02 (Standby)โ€‹

On opnsense-01: System โ†’ High Availability โ†’ Settings โ†’ configure synchronization to opnsense-02 IP. Select all items to sync (firewall rules, aliases, VPN, certs, etc.).

OPNsense will automatically push the full config to opnsense-02. The standby node needs only network connectivity โ€” it does not need separate manual configuration.

4. Verify HAโ€‹

# On opnsense-01 console:
ifconfig | grep carp # Should show MASTER state

# On opnsense-02 console:
ifconfig | grep carp # Should show BACKUP state

# Test failover (on opnsense-01):
service carp stop # opnsense-02 takes over in ~2 seconds
service carp start # opnsense-01 reclaims MASTER role

5. Connect to Omada Switch Fabricโ€‹

opnsense-01 and opnsense-02 LAN ports both connect to TL-SX3008F-01 (network plane). Configure the switch port as a VLAN trunk (all VLANs tagged). OPNsense sees one physical interface (igc1) with VLAN sub-interfaces per segment.


Omada Integrationโ€‹

The Omada SDN controller (OC200) manages all TP-Link switches. OPNsense handles routing and firewall policy; Omada handles switch-level VLAN assignment, port profiles, and QoS.

Separation of duties:

  • OPNsense: WAN, firewall rules, IDS/IPS, VPN, inter-VLAN routing, logging
  • Omada: Switch port assignments, VLAN tagging, 10G link aggregation, SDN dashboard

No TP-Link ER router is needed. The ER-series routers in the Omada lineup are redundant when OPNsense handles routing. Connecting OPNsense's LAN interface directly to the SX3008F (as the upstream gateway) is the correct architecture.


Secrets Managementโ€‹

All OPNsense credentials follow the Infisical-first policy:

SecretInfisical PathUsed By
opnsense-api-key/network/opnsenseAnsible, MCP server
opnsense-api-secret/network/opnsenseAnsible, MCP server
opnsense-admin-password/network/opnsenseBreak-glass access only
carp-preSharedKey/network/opnsenseCARP sync authentication
wireguard-server-private-key/network/vpnOPNsense WireGuard config

See Infisical Secrets Management for the full secrets workflow.


Document Controlโ€‹

RevDateAuthorDescription
1.02026-03-22Anshin EngineeringInitial release โ€” OPNsense HA pair on Beelink EQ12 Pro; replaces TP-Link ER router