Netgrimoire/False Grimoire/Netgrimoire/Network/Security/OpnSense_Firewall.md
2026-04-12 09:39:57 -05:00

20 KiB
Raw Blame History

title description published date tags editor dateCreated
OpnSense Grimoire Firewall Configuration true 2026-02-23T21:31:26.008Z markdown 2026-02-23T21:31:15.244Z

OPNsense Firewall

Host: OPNsense.localdomain Timezone: America/Chicago Documented: February 23, 2026 Status: Active — AT&T migration in progress


Overview

The network perimeter is protected by an OPNsense firewall running on dedicated hardware with four physical Intel i226-V NICs (igc0igc3). The firewall operates in a dual-WAN configuration during the transition from the legacy ISP to AT&T fiber, with AT&T becoming the permanent primary WAN. CrowdSec threat intelligence, GeoIP blocking, and Spamhaus DROP/EDROP lists provide layered perimeter security.


Hardware & System

Parameter Value
Hostname OPNsense
Domain localdomain
Timezone America/Chicago
Language en_US
NAT Outbound Mode Hybrid
System DNS 8.8.8.8 (Google) — see DNS notes
DNS Allow Override Enabled
SSH Enabled (port 22)
Console Menu Disabled (hardened)

DNS Note: The system upstream DNS is set to 8.8.8.8. If dnscrypt-proxy or Unbound is configured, this should be updated to point to localhost or the internal DNS resolver (192.168.5.7). Review before enabling encrypted DNS.


Network Interfaces

Interface Label Physical NIC IP Address Role
wan WAN igc0 24.249.193.114/28 Legacy primary WAN — being retired
opt1 ATT igc1 107.133.34.145/28 New primary WAN — AT&T fiber
lan LAN igc3 192.168.3.4/29 Internal LAN management segment
opt3 OPT3 igc2 DHCP Unassigned — spare interface
opt2 / wg1 WG1 wg1 (virtual) WireGuard tunnel WireGuard VPN interface
openvpn OpenVPN virtual Tunnel only OpenVPN (server + client configured)
lo0 Loopback lo0 127.0.0.1/8 System loopback

OPT3 (igc2) is on DHCP and currently unassigned. Disable this interface or assign it a role to reduce unnecessary attack surface.


Gateways & Routing

Active Gateways

Gateway Name Interface IP Role
WAN_DefRoute wan (igc0) 24.249.193.114 Legacy default route — being retired
ATT opt1 (igc1) 107.133.34.145 AT&T — becoming primary
LAN_GWv4 lan (igc3) 192.168.3.4 LAN gateway

NAT Outbound Rules

Outbound NAT runs in Hybrid mode — automatic rules supplemented by manual overrides below.

Interface Source NAT Target Purpose
opt1 (ATT) ATT_Out_1 group opt1ip Dad's Laptop + 192.168.5.128/25 out ATT
wan MailCow_Ngnx (192.168.5.16) 24.249.193.115 Mail server — dedicated WAN IP
wan PNCHarris_Internal wanip Internal subnets egress
wan WireGuard (opt2) WireGuard outbound NAT

✓ The mail server already has a dedicated outbound IP (24.249.193.115) on WAN. This pattern should be replicated on ATT using a dedicated virtual IP from the static block.


Firewall Aliases

Host Aliases

Alias IP Address Used For
caddy 192.168.5.10 Caddy reverse proxy
MailCow_Ngnx 192.168.5.16 MailCow nginx container
JellyFin_Host 192.168.5.18 Jellyfin media server
ISPConfig_Host 192.168.4.11 ISPConfig control panel
Dads_Laptop 192.168.5.176 Routed out ATT interface

Network Aliases

Alias Value Used For
PNCHarris_Internal 192.168.5.0/25, 192.168.3.0/24 Primary internal subnets
Subnet_5_128_Mask_25 192.168.5.128/25 Upper half of 192.168.5.x
ATT_Out_1 Dads_Laptop + Subnet_5_128_Mask_25 Traffic routed out ATT interface
Family_Subnet (empty) Defined but unpopulated

Port Aliases

Alias Ports Used For
Web_Services 80, 443 HTTP/HTTPS
MailCow 25, 110, 143, 465, 587, 993, 995, 4190 Full MailCow mail protocol suite
ISPConfig 25, 53, 143, 465, 587, 993, 995, 8080 ISPConfig mail + DNS + admin
JellyFin_Port 8096, 7096 Jellyfin HTTP + HTTPS
Plex_Port_2 (empty) Defined but unpopulated

Security & Threat Intelligence Aliases

Alias Type Source Status
SpamHaus_Drop URL Table https://www.spamhaus.org/drop/drop.txt ⚠ Rule DISABLED
Spamhaus_edrop URL Table https://www.spamhaus.org/drop/edrop.txt ⚠ Rule DISABLED
Blocked_Countries GeoIP 70 countries — see GeoIP section ⚠ Rule DISABLED
crowdsec_blacklists External CrowdSec IPv4 decisions ✓ Active
crowdsec6_blacklists External CrowdSec IPv6 decisions ✓ Active
crowdsec_blocklists External CrowdSec IPv4 (duplicate) ✓ Active
crowdsec6_blocklists External CrowdSec IPv6 decisions (duplicate) ✓ Active

Critical: Spamhaus DROP, Spamhaus EDROP, and GeoIP country blocking are all defined and populated but their firewall rules are disabled. These are not currently being enforced. Re-enable these rules as an immediate priority.

⚠ There are duplicate CrowdSec alias pairs (crowdsec_blacklists and crowdsec_blocklists both handle IPv4). Review and consolidate to avoid confusion.


Firewall Rules

WAN Rules

Action Protocol Source Destination Port(s) Enabled Description
BLOCK Any SpamHaus_Drop Any Any No Block Spamhaus DROP list
BLOCK Any Spamhaus_edrop Any Any No Block Spamhaus EDROP list
BLOCK Any Blocked_Countries Any Any No GeoIP country block
PASS TCP Any MailCow_Ngnx MailCow ports ✓ Yes Inbound mail
PASS TCP Any JellyFin_Host 8096, 7096 ✓ Yes Jellyfin access
PASS UDP Any WAN IP 51820 ✓ Yes WireGuard VPN ingress
PASS TCP Any MailCow_Ngnx 80, 443 ✓ Yes MailCow webmail
PASS TCP Any caddy (192.168.5.10) 80, 443 ✓ Yes Caddy reverse proxy

⚠ All three block rules at the top of the WAN ruleset are disabled. The firewall is currently not enforcing Spamhaus or GeoIP blocking despite the aliases being populated.

LAN Rules

Action Protocol Source Destination Description
PASS Any ATT_Out_1 group Any Dad's Laptop + upper subnet out ATT
PASS Any LAN subnet Any Default allow LAN to any
PASS Any PNCHarris_Internal Any Internal subnets to any
PASS Any LAN subnet Any Default allow LAN IPv6 to any
PASS TCP PNCHarris_Internal ISPConfig_Host:ISPConfig LAN → ISPConfig redirect
PASS TCP PNCHarris_Internal ISPConfig_Host:80/443 LAN → ISPConfig web redirect
PASS TCP PNCHarris_Internal caddy:80/443 LAN → Caddy redirect
PASS TCP PNCHarris_Internal MailCow_Ngnx:MailCow LAN → MailCow redirect

WireGuard Interface Rules

Action Protocol Source Destination Description
PASS Any Any Any Allow all from WireGuard peers — unrestricted

⚠ The WireGuard interface allows all traffic from all peers with no restrictions. Consider scoping rules per peer as needs are better understood — some remote sites may only need access to specific services.


NAT Port Forwards

WAN Inbound

Protocol Public Port(s) Internal Target Internal Port(s) Service
TCP MailCow ports 192.168.5.16 (MailCow_Ngnx) MailCow ports Mail (SMTP/IMAP/POP3/Sieve)
TCP 80, 443 192.168.5.16 (MailCow_Ngnx) 80, 443 MailCow webmail
TCP 8096, 7096 192.168.5.18 (JellyFin_Host) 8096, 7096 Jellyfin
TCP 80, 443 192.168.5.10 (caddy) 80, 443 Caddy (all web services)

LAN Hairpin (Internal Redirect)

Protocol Port(s) Internal Target Description
TCP MailCow ports 192.168.5.16 Internal mail access
TCP 80, 443 192.168.5.10 (caddy) Internal web via Caddy
TCP ISPConfig ports 192.168.4.11 Internal ISPConfig access
TCP 80, 443 192.168.4.11 Internal ISPConfig web

VPN

WireGuard

Server: pncharris

Parameter Value
Tunnel Address 192.168.32.1/24
Listen Port 51820 (UDP)
DNS for Peers 192.168.5.7 (internal DNS)
Interface wg1 (OPT2)
Status Enabled

Peers

Peer Tunnel IP Status Notes
Obie 192.168.32.2/32 ✓ Enabled
pncfishandmore 192.168.32.3/32 ✓ Enabled Business location
GLNet (1) 192.168.32.4/32 ✓ Enabled GL.iNet travel router
PortaPotty 192.168.32.5/32 ✓ Enabled Remote site
GLNet (2) 192.168.32.6/32 ✓ Enabled Second GL.iNet device

✓ WireGuard peers use the internal DNS server (192.168.5.7) — internal hostnames resolve correctly over VPN.

OpenVPN

An OpenVPN server and client are configured but details were not populated in the backup. Verify status in VPN → OpenVPN in the OPNsense UI.


Security Features

CrowdSec

CrowdSec is installed and fully operational at the firewall level.

Parameter Value
Agent Enabled
Local API (LAPI) Enabled — 127.0.0.1:8080
Firewall Bouncer Enabled
Rules Enabled with logging
Firewall Bouncer Verbose Disabled
Manual LAPI Config Disabled (auto)

CrowdSec decisions are fed into two alias pairs used in firewall rules:

  • crowdsec_blacklists / crowdsec6_blacklists — IPv4 and IPv6 block lists
  • crowdsec_blocklists / crowdsec6_blocklists — duplicate set (consolidate)

GeoIP Blocking

GeoIP uses the MaxMind GeoLite2 database with a configured license key. The blocking rule is currently disabled — the alias is populated but not enforced.

70 countries are blocked across four regions:

Region Countries
Africa (49) AO, BF, BI, BJ, BW, CD, CF, CG, CI, CM, DJ, DZ, EG, EH, ER, ET, GA, GH, GM, GN, GQ, GW, KE, LR, LS, LY, MA, ML, MR, MW, MZ, NA, NE, NG, RW, SD, SL, SN, SO, SS, ST, SZ, TD, TG, TN, TZ, UG, ZA, ZM, ZW
Middle East / Asia (12) AF, BN, BT, CN, IQ, IR, KG, KP, KW, PH, QA, SA
Eastern Europe (4) BG, RS, RU, RO
Latin America (4) BR, EC, GT, HN

Spamhaus Blocklists

Both lists are configured as URL table aliases that auto-refresh, but both blocking rules are currently disabled.

List URL Update
Spamhaus DROP https://www.spamhaus.org/drop/drop.txt Auto (URL table)
Spamhaus EDROP https://www.spamhaus.org/drop/edrop.txt Auto (URL table)

Internal Network Layout

Known Subnets

Subnet Alias Purpose
192.168.3.0/24 PNCHarris_Internal LAN management segment
192.168.5.0/25 PNCHarris_Internal Primary server subnet
192.168.5.128/25 Subnet_5_128_Mask_25 Secondary server subnet / ATT routing
192.168.32.0/24 WireGuard tunnel network

Key Internal Hosts

Hostname / Alias IP Role
caddy 192.168.5.10 Caddy reverse proxy (all web services)
MailCow_Ngnx 192.168.5.16 MailCow nginx container
JellyFin_Host 192.168.5.18 Jellyfin media server
ISPConfig_Host 192.168.4.11 ISPConfig control panel
Dads_Laptop 192.168.5.176 Routed via ATT interface
Internal DNS 192.168.5.7 DNS server (served to WireGuard peers)

DHCP

DHCP on the LAN interface (192.168.3.0/24) is currently disabled. No KEA or ISC DHCP ranges are active on the firewall. Devices likely use static IPs or a separate DHCP server downstream.


Installed Plugins & Services

The following OPNsense components are present in the configuration:

Plugin / Service Status
WireGuard ✓ Active — 1 server, 5 peers
CrowdSec ✓ Active — agent + bouncer + LAPI
OpenVPN Configured — verify in UI
IPsec / Swanctl Present — verify in UI
Unbound Plus Present — verify DNS configuration
Kea DHCP Present — not active on LAN
DHCP Relay Present
Netflow Present
IDS/IPS (Suricata) Not configured — see hardening plan
Proxy Present — not actively used
Traffic Shaper Present
Monit Present
SNMP Present
Syslog Not configured — see hardening plan
Git Backup Not installed — see hardening plan

AT&T Migration & Static IP Plan

Current AT&T Interface

Interface: opt1 (igc1) Current IP: 107.133.34.145/28 Block: /28 — up to 14 usable addresses, 5 static IPs allocated for use

IP Slot Dedicated To Justification
IP 1 Mail (MailCow) Dedicated mail IP protects sender reputation. Never share with web services. Only ports 25/465/587/993/995/4190 NAT to 192.168.5.16.
IP 2 Web / Caddy All reverse-proxied services via Caddy. Keeps web and mail reputation independent. Replace current WAN NAT for ports 80/443 → 192.168.5.10.
IP 3 WireGuard VPN Dedicated IP for UDP/51820 only. Cleaner peer configs, stable endpoint, easy to firewall tightly — that IP accepts nothing else.
IP 4 Spare / Jellyfin Hold in reserve. Best candidate: dedicated Jellyfin IP (currently on WAN with ports 8096/7096). Media servers benefit from a clean IP separate from your main web presence.
IP 5 Admin / Out-of-band A locked-down IP for emergency remote OPNsense access. Firewall tightly — accept only from WireGuard peers or specific trusted source IPs. Never advertise publicly.

Implementation Steps

Step 1 — Add Virtual IPs

In OPNsense: Firewall → Virtual IPs → Add

For each additional static IP (IPs 15 excluding the interface IP):

  • Type: IP Alias
  • Interface: ATT (opt1)
  • Address: <static IP>/28
  • Description: e.g. ATT_Mail, ATT_Web, ATT_WireGuard

Step 2 — Create NAT Rules Per Virtual IP

In Firewall → NAT → Port Forward, create new rules on the ATT interface using the virtual IPs as the destination. Example for mail:

Interface:       ATT (opt1)
Protocol:        TCP
Destination:     ATT_Mail virtual IP
Destination Port: MailCow alias
Redirect Target: 192.168.5.16 (MailCow_Ngnx)
Redirect Port:   MailCow alias

Repeat for web (→ caddy 192.168.5.10) and WireGuard (UDP/51820).

Step 3 — Update Outbound NAT

Add manual outbound NAT rules so that each internal service exits through its dedicated virtual IP:

Interface:  ATT (opt1)
Source:     192.168.5.16 (MailCow_Ngnx)
Target:     ATT_Mail virtual IP

Interface:  ATT (opt1)
Source:     192.168.5.10 (caddy)
Target:     ATT_Web virtual IP

Step 4 — Migrate WireGuard Endpoint

Update peer configs to point to the ATT_WireGuard virtual IP on port 51820. Move the WAN WireGuard rule to ATT interface. Update DNS records if you have a hostname for the WireGuard endpoint.

Step 5 — Update Firewall Block Rules

Re-enable the Spamhaus and GeoIP block rules on the ATT interface. Apply them to the ATT WAN rules the same way they are (currently disabled) on WAN.

Step 6 — DNS Updates

Update all public DNS records to point to the new ATT static IPs:

  • mail.* domains → ATT_Mail IP
  • *.netgrimoire.com, *.wasted-bandwidth.net, etc. → ATT_Web IP
  • WireGuard endpoint hostname → ATT_WireGuard IP

Step 7 — Retire WAN (igc0)

Once all services are verified on ATT, disable WAN NAT rules, remove port forward rules on WAN, and eventually disable the interface.


Hardening Plan

The following items are recommended improvements, ordered by priority.

Priority 1 — Re-enable Disabled Security Rules (Immediate)

All three security block rules on the WAN interface are currently disabled. These should be re-enabled immediately as they represent threat intelligence you have already configured but are not using.

  1. Navigate to Firewall → Rules → WAN
  2. Find rules: Block DROP, Block EDROP, and the GeoIP block rule
  3. Click the enable toggle on each rule
  4. Click Apply Changes

Repeat on the ATT interface once migrated.

Priority 2 — Suricata IDS/IPS

Suricata is built into OPNsense but not yet configured. This is the most significant security gap — without it, there is no deep packet inspection or content-based threat detection.

Setup steps:

  1. Go to Services → Intrusion Detection → Administration
  2. Enable IDS/IPS, set interface to ATT (and WAN while active)
  3. Set mode to IPS (inline blocking, not just alerting)
  4. Under Download, enable the following rulesets:
    • ET Open — Proofpoint Emerging Threats (free, comprehensive)
    • Abuse.ch SSL Blacklist — malicious SSL certificate detection
    • Feodo Tracker — botnet C2 blocking
  5. Under Policies, set default action to drop for high-severity rules
  6. Click Download & Update Rules, then Apply

✓ Suricata complements CrowdSec well. CrowdSec handles IP reputation; Suricata handles traffic content inspection. They do not overlap.

Priority 3 — Additional Blocklists

Add these URL table aliases to supplement Spamhaus DROP/EDROP:

List URL Purpose
Feodo Tracker https://feodotracker.abuse.ch/downloads/ipblocklist.txt Botnet C2 IPs
Abuse.ch SSLBL https://sslbl.abuse.ch/blacklist/sslipblacklist.txt Malicious SSL IPs
Emerging Threats https://rules.emergingthreats.net/fwrules/emerging-Block-IPs.txt ET block list

For each: Firewall → Aliases → Add, type URL Table, set refresh to 1 day. Then add a WAN block rule using each alias as the source.

Priority 4 — dnscrypt-proxy (Encrypted DNS)

Encrypts DNS queries leaving the firewall and adds DNS-level malware/tracking blocklists.

  1. Go to System → Firmware → Plugins, install os-dnscrypt-proxy
  2. Navigate to Services → DNSCrypt-Proxy
  3. Enable, set listen port to 5353
  4. Select resolvers: cloudflare, quad9-dnscrypt-ip4-nofilter-pri (or similar)
  5. Enable DNSSEC validation
  6. Update System → Settings → General — set DNS server to 127.0.0.1:5353
  7. Disable DNS Allow Override so the ISP cannot push DNS changes

Priority 5 — os-git-backup

Automatically commits every OPNsense config change to a Git repository. Invaluable for auditing changes after an incident and for rapid recovery.

  1. Go to System → Firmware → Plugins, install os-git-backup
  2. Navigate to System → Configuration → Git Backup
  3. Configure a Forgejo repository on Netgrimoire as the remote
  4. Set SSH key for authentication
  5. Enable automatic backup on config change

Priority 6 — Syslog to Graylog

Syslog is not currently configured. Sending firewall logs to Graylog (already running at http://graylog:9000) enables centralized log analysis and alerting.

  1. Go to System → Settings → Logging → Remote
  2. Add a syslog destination: graylog:514 (UDP) or use GELF input on Graylog
  3. Enable logging for: Firewall, DHCP, VPN, Authentication, CrowdSec

Known Issues & Action Items

Item Priority Notes
Spamhaus DROP rule disabled 🔴 High Re-enable in Firewall → Rules → WAN
Spamhaus EDROP rule disabled 🔴 High Re-enable in Firewall → Rules → WAN
GeoIP block rule disabled 🔴 High Re-enable in Firewall → Rules → WAN
Suricata not configured 🔴 High Most significant security gap — configure with ET Open rules
Duplicate CrowdSec aliases 🟡 Medium crowdsec_blacklists and crowdsec_blocklists both do IPv4 — consolidate
WireGuard rule too permissive 🟡 Medium Allow-all from peers — scope per peer when needs are known
OPT3 interface unassigned 🟡 Medium Disable or assign a role
System DNS points to Google 🟡 Medium Should point to internal resolver or localhost after dnscrypt-proxy setup
No syslog configured 🟡 Medium Forward to Graylog for centralized logging
os-git-backup not installed 🟡 Medium Install for config change auditing
OpenVPN config unpopulated 🟢 Low Verify status — backup shows server+client but no details
ATT migration incomplete 🟢 Low In progress — see migration plan above
Family_Subnet alias empty 🟢 Low Populate or remove
Plex_Port_2 alias empty 🟢 Low Populate or remove
DHCP disabled on LAN 🟢 Info Intentional if using static IPs — verify