Send chosen devices and sites through NordVPN, fall back to IPVanish when NordVPN fails, and never leak outside the VPN when both are down. Then bring over a pfSense setup: aliases, schedules, LAN rules, and gateway groups. The screenshots are from a test firewall with two WireGuard provider tunnels, wgnord and wgipv.
How pfSense maps to Korthveil:
| pfSense | Korthveil | Where |
|---|---|---|
WireGuard tunnel to a provider (tun_wg3 NordVPN) |
WireGuard client tunnel (wgnord) |
VPN › WireGuard |
Gateway (NORDGW, monitor IP) |
A member of a gateway group, with its monitor IP | Network › Policy routing |
Gateway group with tiers (WG_ONLY) |
Gateway group: members in tier order | Network › Policy routing |
| Floating "kill switch" block rule | The group's Kill switch check box | Network › Policy routing |
Pass rule with a gateway (… via APPL_VPN) |
Policy route to a group, plus an allow rule | Network › Policy routing, Firewall › Rules |
| Alias (host, network, port, host names) | Alias (address or service object) | Firewall › Aliases |
| Schedule | Schedule | Firewall › Schedules |
Invert match (! RFC_1918) |
Not check box under Source or Destination | Rule and policy route editors |
Source port (Crypted_PC : 51413) |
Source ports next to the ports | Service of a rule or policy route |
| Automatic outbound NAT on the tunnel | Source NAT (masquerade) on each tunnel | Firewall › NAT |
Every change goes into pending changes until you Commit. Commit with Safety rollback on: if a change cuts you off, it undoes itself after five minutes.
Each firewall needs its own WireGuard configuration from each provider. Do not copy the private keys from pfSense; a key used by two devices drops both connections.
Go to VPN › WireGuard › Import configuration and paste or upload the .conf file (a QR code image works too).

Korthveil detects a client tunnel. Check these settings:
| Field | Set to | Why |
|---|---|---|
| Name | wgnord, then wgipv for IPVanish |
Short names; wg + up to 10 letters and digits |
| Role | Client | It connects out to the provider |
| Zone | vpn |
Traffic into the tunnel is checked as going to this zone |
| Accept connections from zones | none | A provider tunnel only connects out |
| Peer › Allowed networks | 0.0.0.0/0 (and ::/0 if the provider gives IPv6) |
Anything may go through it |
| Peer › Routes | No routes (dynamic routing or policy) | The firewall keeps its own default route; policy routes choose what goes in |
| Keepalive | 25 | Keeps the tunnel alive through NAT |

Tunnel status at the bottom shows each provider online after its first handshake.
Open Firewall › Aliases and recreate the pfSense aliases with the same names. Each entry can be:
192.168.2.11);10.0.0.0/8, fd00::/64);192.168.2.80-192.168.2.89);discord.com).Host names are kept as fqdn:discord.com. The firewall resolves them for IPv4 and IPv6 and follows their DNS TTL (checked again between 30 seconds and an hour), so changes need no commit. Like pfSense, wildcards (*.discord.com) are not supported; list each name.
Networks written with host bits set, such as pfSense's 192.168.2.61/30, are accepted and match the whole network (192.168.2.60/30), with a hint.
Port aliases become service objects. A port alias used with TCP/UDP becomes two objects and a group:
STUN_Ports_TCP and STUN_Ports_UDP, with ports 3478, 3479, 5349, 19302-19309 (pfSense's 19302:19309 is written with a dash);STUN_Ports, a group of both.
Left out on purpose: pfBlockerNG's own tables (pfB_…). Use the DNS filter add-in or an IP list there instead.
Firewall › Schedules › Add schedule:
Phones_YouTube: every day, 21:00 to 00:00. An end before the start runs past midnight; 00:00 means until midnight.Block_Youtube: every day, 21:00 to 23:00.Korthveil schedules are weekly. pfSense's month ranges for Block_Youtube (March, April) become a daily window; turn the rule on and off for the months you want.
Open Network › Policy routing, then Gateway groups › Add gateway group.

| Field | Example | Meaning |
|---|---|---|
| Name | WG_ONLY |
As in pfSense |
| Kill switch | on | No member answers: the traffic is dropped, never sent out the normal internet line |
| Tier 1 interface / Monitor IP | wgnord / 208.67.222.222 |
pfSense NORDGW's monitor |
| Tier 2 interface / Monitor IP | wgipv / 1.0.0.1 |
pfSense SEA14GW's monitor |
| Gateway | empty | A WireGuard tunnel needs none |
| Every / down after / up after | 5 s / 3 / 2 (defaults) | A member is down after 3 lost probes and back after 2 answers |
The monitor is pinged through the member's tunnel, so it tests the whole path to the internet, not just the handshake.
The four groups of the pfSense setup:
| Group | Tier 1 | Tier 2 | Kill switch | pfSense meaning |
|---|---|---|---|---|
WG_ONLY |
wgnord |
wgipv |
on | Only through WireGuard |
APPL_VPN |
wgnord |
wgipv |
off | NordVPN, IPVanish, else the WAN |
TV_VPN |
wgipv |
wgnord |
off | IPVanish first, else the WAN |
NORD_ONLY |
wgnord |
(none) | on | pfSense's single gateway NORDGW with the floating kill-switch rule |
The panel shows each member live: up with its round-trip time, down, and which one is active.

In pfSense, a pass rule with a gateway allows the traffic and chooses its path. Korthveil keeps these apart: policy routes choose the path, and rules allow it (Step 6). Policy routes are checked top to bottom, and the first match decides.
Add policy route, then Send via: A gateway group (failover):
| # | Name | Source | Destination | Service | Group |
|---|---|---|---|---|---|
| 1 | Torrent port via NordVPN only | Crypted_PC |
Not RFC_1918 |
TCP and UDP, source port 51413 | NORD_ONLY |
| 2 | Transmission via NordVPN only | Transmission_Host |
Not RFC_1918 |
any | NORD_ONLY |
| 3 | STUN via NordVPN only | Crypted_PC |
any | STUN_Ports |
NORD_ONLY |
| 4 | NordVPN_Sites via WireGuard only | any | NordVPN_Sites |
any | WG_ONLY |
| 5 | Discord via WireGuard | any | Discord_Hosts |
any | TV_VPN |
| 6 | Social media networks via WireGuard | any | Social_Media_Nets |
any | APPL_VPN |
| 7 | Social media hosts via WireGuard | any | Social_Media_Hosts |
any | APPL_VPN |
| 8 | Google and YouTube via WireGuard | any | Google_Nets |
any | APPL_VPN |
| 9 | TVs via IPVanish | StreamingTV |
any | any | TV_VPN |
| 10 | Appliances via NordVPN | Appliances |
any | any | APPL_VPN |
Each has From zones: the LAN zone (on the Wi-Fi test network, WIFI).
"Not" (invert match): pfSense's ! RFC_1918 is the Not check box under Destination: every destination except the private networks, so Transmission still reaches the LAN directly.


Firewall › Rules, from the LAN zone to the WAN zone, in this order:
| # | Name | Source | Service | Action | Schedule |
|---|---|---|---|---|---|
| 1 | Block QUIC on LAN | any | UDP 443 | Deny | |
| 2 | Blocked schedule for SonyTV (off, as in pfSense) | SonyTV |
any | Deny | Block_Youtube |
| 3 | Quarantined devices (off, as in pfSense) | Isolated_Devices |
any | Deny | |
| 4 | Phones no DoT during YouTube block | Phones |
TCP 853, UDP 853 | Deny | Phones_YouTube |
The existing allow rule from the LAN to the WAN stays below them.
Allow into the tunnels: traffic a policy route sends into wgnord or wgipv leaves through the vpn zone. Add LAN to VPN tunnels: from the LAN zone to vpn, any, Allow. pfSense passes it with the same LAN rule; Korthveil checks it as going to the tunnel's zone.

NAT: in Firewall › NAT › Add source NAT, one per tunnel, so the LAN's private addresses leave as the tunnel's address:
Internet via wgnord; Out interface: wgnord; Type: Masquerade; Family: IPv4 + IPv6.wgipv.Not carried over, on purpose:
| pfSense | Why not |
|---|---|
| WAN: block private and bogon networks | Korthveil drops every new connection from the WAN unless a rule or port forward allows it. On a firewall behind another router, a private-network block would also hit its own uplink. |
| WAN: port forwards to SentinelOps (192.168.2.11) | They belong to the firewall that owns the public address |
| Floating CoDel limiters | Traffic shaping is set per interface in Korthveil |
WG_CLIENTS rules (tun_wg2) |
That WireGuard server for remote devices is a separate setup |
Commit with a note such as VPN failover and pfSense rules. Then confirm the commit (the banner at the top).
Check the path of a connection: Firewall › Policy lookup. A Google address from a LAN device shows sends it via gateway group APPL_VPN: the first healthy of wgnord, wgipv, else the normal routes.
Watch a failover: when NordVPN stops answering, within about 15 seconds:
NORD_ONLY has no active member, so its traffic is blocked;When NordVPN answers again, it takes over as tier 1.

Existing connections keep their path until they end. A download running through NordVPN when it fails stops, and starts again through IPVanish.
| Symptom | Check |
|---|---|
| A member always shows down | Tunnel status: does the provider show online? The monitor IP must answer ping through the tunnel; try another (1.1.1.1, 9.9.9.9). |
| Traffic still leaves through the WAN | The policy route's From zone and addresses match the device. It is above any route that matches first. Policy lookup shows which route matches. |
| Steered traffic is dropped | The rule LAN to VPN tunnels (to zone vpn) exists, and source NAT on both tunnels. |
| Host-name aliases do not match | The firewall's own DNS resolves the name, and the device uses the same DNS answers (it should use the firewall or the same resolver). |
Everything through WG_ONLY stops |
Both providers are down and the kill switch works as intended. |
More: adr/0067 (gateway groups) and adr/0068 (invert match and source ports) describe the design.