Prevent Any Traffic from VPN Hosts from Egressing the WAN

This article is part of a series.

Some users want to be sure traffic that is policy-routed out their VPN tunnel cannot leave their network via the open Internet. This presents several challenges due to the way pfSense processes NAT and firewall rules.  For instance, if the VPN tunnel is down, by default pfSense deletes the gateway from the rule which will cause the traffic to be routed according to the routing table. If an attempt is made to block all packets going out the WAN interface that are sourced from VPN Host A1, the match will fail because NAT occurs before the rules are checked, so the packets will not appear to be sourced from, they will be sourced from, the WAN interface address.

The pf firewall, and therefore pfSense, includes a mechanism of marking packets while they are internal to pf and matching that mark in later rules. In this application, packets destined for the VPN tunnel will be marked with the mark NO_WAN_EGRESS. Later, a floating rule on WAN in the outbound direction will drop all traffic that matches that mark. It is configured like this:

Navigate to Firewall > Rules, LAN tab and edit the rule that sends traffic to the VPN. It will look similar to this:

VPN Policy Routing Rule

Under Advanced features click the Advanced button to open the Advanced options settings. In the field above the label reading You can mark a packet matching this rule and use this mark to match on other NAT/filter rules  enter the text NO_WAN_EGRESS. Now all packets flowing through the firewall destined for the VPN will be marked.

Firewall Rule Advanced Options

Save the rule and Apply changes.

A rule must now be created to match any traffic exiting the firewall via the public WAN marked NO_WAN_EGRESS and drop it. With pfSense, in order to match traffic going out an interface a floating rule must be configured. Navigate to Firewall > Rules, Floating tab and click the Plus button button to add a new rule.

Action: Reject
Quick: Checked
Interface: WAN (you can also select multiple WAN interfaces or an interface group here)
Direction: out
Protocol: any
Source: any
Destination: any
Description: Reject outbound traffic marked NO_WAN_EGRESS

Under Advanced features click the Advanced button to open the Advanced options settings. In the field above the label reading You can match packet on a mark placed before on another rule enter the text NO_WAN_EGRESS.

Save the rule and Apply changes.

Your rule should look like this:

Floating NO_WAN_EGRESS Rule Screenshot

That's it. Take the VPN tunnel down and try to access the Internet from Host A1.  All traffic will be rejected as it attempts to exit the firewall.

Note that there is an alternate method to accomplish this. Navigate to System > Advanced, Miscellaneous tab. Under the Gateway Monitoring section there is an option to Skip rules when gateway is down. This will accomplish the same task, but the rule that policy routes the traffic from Host A1 will have to be followed by a rule that rejects all traffic from Host A1 or the traffic will be routed according to the default pass rule on LAN. This checkbox also affects all gateways and all policy routing rules on the router and this author feels it is less elegant than the mark/match method and is a bit ham-fisted.