Filtering on multi-interface firewall

Maxim Khitrov mkhitrov at gmail.com
Tue Aug 25 13:03:20 UTC 2009


Hello all,

A quick question regarding the behavior of FreeBSD and pf when you
have multiple local interfaces. In my case, I have a Soekris net5501
board with one interface being the uplink to ISP and the other three
dedicated to separate networks. There should be no traffic passing
from one network to the other and no one (except for a few admin IPs)
should be able to connect to any firewall port, especially ssh.

So to accomplish this, I have a default "block" rule followed by what
traffic is allowed to pass. The following rule is used to permit
internet traffic from one of the LANs:

pass in quick on $int_if from ($int_if:network) to !($int_if) tag INET

When this packet goes out on $ext_if, it is processed by a nat rule
followed by another pass:

nat on $ext_if tagged INET -> ($ext_if:0)
pass out quick on $ext_if queue (def, pri)

This part should work without problems (I say "should" because I don't
have the ability to test all of this right now). But my question is
about what happens if someone on $int_if network tries to connect to
the IP assigned to $ext_if or one of the other two interfaces? It
seems to me that this packet would be passed when coming in on
$int_if, because the "!($int_if)" portion of the rule is satisfied.
Once the packet makes it to the kernel, would the system then
recognize that it is the final destination for that packet and let it
go to whatever port was specified (ssh, for example)?

What I'm looking for is a way to define a "pass in" rule, so long as
the destination is guaranteed not to be the firewall itself, and I'm
not sure if "!($int_if)" accounts for this other scenario. I know that
I can create a table containing "self," but then the ruleset would
need to be reloaded for every IP change. Is there some other way to
specify "pass this packet in only if it isn't addressed to any local
interface?"

- Max


More information about the freebsd-pf mailing list