Owl Gateway (Iowa)¶
Overview¶
| Attribute | Value |
|---|---|
| Location | Urbandale, Iowa |
| Hardware | DEC700 |
| OPNsense | 26.1_4 |
| FreeBSD | 14.3-RELEASE-p7 |
| ISP | Metronet |
| WAN IP | 46.110.77.34 (static) |
| LAN Subnet | 10.7.0.0/16 |
| Gateway IP | 10.7.0.1 |
| ZeroTier IP | 192.168.194.10 |
| IPv6 | Hurricane Electric tunnel |
Network Interfaces¶
| Interface | Device | IP Address | Notes |
|---|---|---|---|
| WAN | igb1 | 46.110.77.34/26 | Static IP, Metronet |
| WAN IPv6 | igb1 | 2001:470:1f11:b8::2/64 | HE Tunnel |
| LAN | igb0 | 10.7.0.1/16 | Main LAN |
| OPT1 | igb2 | - | Unused |
| ZEROTIER | zt6ldb571t4n4bn | 192.168.194.10 | ZeroTier overlay |
IPv6 Configuration¶
Owl uses a Hurricane Electric tunnel for IPv6 connectivity (Metronet doesn't provide native IPv6).
Tunnel Details¶
| Attribute | Value |
|---|---|
| Provider | Hurricane Electric (tunnelbroker.net) |
| Tunnel Type | 6in4 |
| Local IPv4 | 46.110.77.34 |
| Server IPv4 | (HE endpoint) |
| IPv6 Prefix | 2001:470:1f11:b8::/64 |
| Gateway IPv6 | 2001:470:1f11:b8::1 |
| Local IPv6 | 2001:470:1f11:b8::2 |
Benefits¶
- Static IPv6 prefix (doesn't change like DHCP-PD)
- Works with static IPv4 from Metronet
- Reliable ZeroTier connectivity via IPv6
DHCP Configuration¶
| Setting | Value |
|---|---|
| Server | Kea DHCPv4 (migrated from ISC dhcpd 2026-02-09) |
| Enabled | Yes |
| Domain | owl.scandora.net |
| Search List | owl.scandora.net; scandora.net |
| Range | 10.7.254.10 - 10.7.254.254 |
| Static Mappings | 28 devices |
Notable Static Devices¶
- TP-Link switches (SG108PE, SG105PE)
- TP-Link EAP610 access points (×2)
- Home Assistant (10.7.1.99)
Installed Plugins¶
| Plugin | Purpose |
|---|---|
| os-ddclient | Dynamic DNS client |
| os-git-backup | Git-based config backup |
| os-net-snmp | SNMP agent for monitoring |
| os-node_exporter | Prometheus metrics (v1.9.1) |
| os-theme-cicada | Dark theme |
| os-theme-rebellion | Dark theme |
| os-theme-tukan | Dark theme |
| os-zerotier | ZeroTier VPN (v1.16.0) |
Backup Configuration¶
| Method | Destination | Frequency | Retention |
|---|---|---|---|
| Git (os-git-backup) | github.com/scandora/opnsense-owl.git | Every config change | Full history |
| Google Drive | Built-in | Automatic | 3 backups |
| pull-config.sh | ~/.config/scandora/backups/owl/ |
Daily cron (03:00) | 90 days |
| Pre-run snapshot | ~/.config/scandora/backups/owl/ |
Every Ansible run | With backups |
| Milestone configs | gateways/owl/configs/ |
Manual | In git repo |
| Emergency restore | gateways/owl/emergency-restore/ |
Curated | 5 configs |
Backup & Recovery Tools¶
# Pull latest config via SSH
./scripts/backup/pull-config.sh owl
# List backups with sizes and checksums
./scripts/backup/pull-config.sh owl --list
# Diff latest vs previous backup
./scripts/backup/pull-config.sh owl --diff
# Detect manual changes (drift from Ansible-managed state)
./scripts/backup/check-config-drift.sh owl
See Disaster Recovery for full recovery procedures and OOB & Physical Access for serial console access.
Access¶
SSH¶
# Via ZeroTier (recommended)
ssh joe@192.168.194.10
# Via public IPv4
ssh joe@46.110.77.34
# Via IPv6
ssh joe@owl.scandora.net
Web Interface¶
Firewall Rules¶
WAN Inbound (Dual-Stack)¶
All WAN rules use IPv4+IPv6 dual-stack for simpler management:
| Protocol | Port | Source | Description |
|---|---|---|---|
| ICMP | - | any | Allow ICMP inbound |
| TCP | 22 | GeoIP_US | Allow SSH inbound |
| UDP | 9993 | any | Allow ZT inbound |
SSH Security
The SSH rule includes:
- GeoIP filtering: Only US-based IPs can connect
- Rate limiting: Max 15 connections per 60 seconds
- sshlockout table: Blocked IPs added automatically
- State limits: Max 100 states, 50 source nodes, 3 states per source
LAN Rules¶
- Default allow LAN to any (IPv4+IPv6, all protocols)
- ZeroTier interface rules for cross-site access
Sysctl Tunables¶
Owl has specific tunables for its hardware:
# Aquantia NIC optimization (if 10GbE present)
dev.ax.0.iflib.override_nrxds
dev.ax.1.iflib.override_nrxds
dev.ax.0.rss_enabled
dev.ax.1.rss_enabled
# Performance (disable Meltdown/Spectre mitigations)
vm.pmap.pti=0
hw.ibrs_disable=1
# Security
net.inet.icmp.drop_redirect=1
Configuration Files¶
- Production config:
gateways/owl/configs/config.xml - Milestone configs:
gateways/owl/configs/owl-config-YYYYMMDD-description.xml
Configuration Management (Ansible IaC)¶
Owl's configuration is managed via Ansible using the opnsense role (~78% of customized config). Deployed 2026-02-09, expanded 2026-02-10. Full validation against rebuilt golden image 2026-02-11.
For the full coverage audit, see OPNsense IaC Coverage.
Managed Subsystems¶
| Subsystem | Status | Notes |
|---|---|---|
| Firewall rules | Managed | 15 rules in Firewall → Automation (API-managed) |
| DHCP (Kea) | Managed | Subnet + 28 static reservations |
| DNS (Unbound) | Managed | General, advanced, forwarding, host overrides, DoT |
| DNS-over-TLS | Managed | Cloudflare + Quad9 upstreams via unbound_dot module |
| DNSBL | Manual | OPNsense 26.1 model change; configure via web UI |
| IDS/IPS (Suricata) | Managed | General config (raw API) + 11 rulesets |
| Syslog | Managed | Remote destination via syslog module |
| Gateways | Managed | WAN_GW + HE_TUNNELV6 via gateway module |
| Users/Groups | Managed | joe user + admins group (API keys still manual) |
| Monit | Managed | 1 alert, 11 tests, 4 services |
| ZeroTier | Managed | Network joined, local config applied |
| IPv6 tunnel | Partial | GIF interface params set; assignment is manual |
| SNMP + node_exporter | Managed | Listening on ZT IP for Prometheus scraping |
| System identity | Skipped | puzzle.opnsense doesn't support 26.1; pending Rosa-Luxemburg conversion |
Deployment¶
cd /Users/joe/src/scandora.net/cloud/ansible
# Full deployment (all tags)
./scripts/run-opnsense.sh owl
# Specific subsystems
./scripts/run-opnsense.sh owl --tags dhcp,dns
# Dry run
./scripts/run-opnsense.sh owl --check
# Deploy via WAN (when ZeroTier is down)
./scripts/run-opnsense.sh owl --wan
Key Files¶
| File | Purpose |
|---|---|
cloud/ansible/inventory/owl.yml |
Production inventory + variables |
cloud/ansible/roles/opnsense/ |
Role with 15 task files (14 subsystem tags) |
cloud/ansible/scripts/run-opnsense.sh |
Credential helper + API pre-check + pre-run snapshot |
scripts/backup/pull-config.sh |
SSH-based config backup (daily cron, 90-day retention) |
scripts/backup/check-config-drift.sh |
Detect manual changes made outside Ansible |
gateways/owl/docs/HANDOFF.md |
Deployment log and session handoff |
docs/gateways/owl-iac-coverage.md |
Full IaC coverage audit |
Development¶
See DEV-WORKFLOW.md for:
- Setting up the 4-NIC OPNsense dev VM (GCE + nested KVM)
- Testing Ansible changes safely before production
- Deploying to production Owl