PF pf: NAT Multiple Internal (LAN) Interfaces

Hello,

I cannot seem to find information on how to perform NAT for multiple internal (LAN) interfaces with pf.

I have a very simple set of rules for performing basic NAT:

Code:
#       Definitions
ext_if = "wlan0"        # macro for external interface - use tun0 for PPPoE
int_if = "ue0"        # macro for internal interface
localnet = $int_if:network
icmp_types="echoreq"

# Skip all loopback traffic
set skip on lo

# Scrub all traffic
scrub in

# Perform NAT on external interface
nat on $ext_if from $localnet to any -> ($ext_if)

# Default block rule
block log all

# Allow from internal
pass from { lo0, $localnet } to any keep state

My question is, how would I adjust the above to allow for more than one internal interface?

Thanks!
 
My question is, how would I adjust the above to allow for more than one internal interface?
Just change $localnet. NAT is done on the outgoing interface, it really doesn't matter how many internal interfaces it has. As long as the NAT rule applies.
 
This is enough and you don't have to think about how many LAN interfaces there are and what subnets they are using:

Code:
nat on $ext_if inet from ! ($ext_if) to any -> ($ext_if)

This works because the only traffic that requires outbound NAT is traffic that is forwarded traffic from private address (RFC1918) networks going out to the internet and is not originating from the router/firewall itself. Traffic that doesn't need outbound NAT won't show up in the outgoing queue of ext_if, the only exception is traffic that originates directly from the firewall/router host itself, this is covered by the ! ($ext_if) source qualification in the rule and the outbound NAT is not applied to it needlessly.

In the rare event you don't want to NAT some of the outgoing traffic on ext_if you can add a new nat rule above this one as an exception.
 
The trick with NAT rules is that they only apply to traffic that matches the from .... to .... filter. The original rule only NAT'ed traffic from the network of $int_if due to the $int_if:network. Traffic using any other source address won't match and therefor won't be NAT'ed.
 
Back
Top