In the previous post I described how you can create virtual interfaces which can be used to fetch unique address for each interface using dhclient(8). To use these different addresses assigned to different virtual interfaces in your packet filter NAT you can use following pf.conf. It is important to note that the last filter policy needs to be floating as the packets will flow out from the physical interface and the return packets will arrive on the virtual interface.
# # Macros # INT_IF = "em0" EXT_IF = "bge0" VIRT_IF1 = "ngeth0" VIRT_IF2 = "ngeth1" VIRT_IF3 = "ngeth2" table <private_nets> persist { 127/8, 10/8, 172.16/12, 192.168/16, 169.254/16 } # # Options and default policy # set block-policy drop set state-policy if-bound # # Packet normalization # scrub in all scrub out on $EXT_IF all random-id scrub on $EXT_IF all reassemble tcp # # NAT/redirects # # NAT nat on $EXT_IF from <private_nets> to any -> \ { ($EXT_IF), ($VIRT_IF1), ($VIRT_IF2), ($VIRT_IF3) } # # Filter rules # block log all pass on $INT_IF all pass out all pass out on $EXT_IF from { ($VIRT_IF1), ($VIRT_IF2), ($VIRT_IF3) } to \ any keep state (floating)