Bacula File/Storage Connection Woes using PF

Jeremy Chadwick koitsu at freebsd.org
Wed Mar 26 08:42:18 PDT 2008


On Wed, Mar 26, 2008 at 04:02:02PM +0100, Dalibor Gudzic wrote:
> On Wed, Mar 26, 2008 at 3:53 AM, Jeremy Chadwick <koitsu at freebsd.org> wrote:
> > I'll try to explain it with a very small ruleset and a couple scenarios:
> >
> >  $ext_if = network interface that's got a public IP address
> >  4.4.4.4 = our public IP address
> >
> >  pass out quick all flags S/SA keep state
> >  pass out quick all
> >  block in log all
> >  pass in quick on $ext_if inet proto tcp from any to 4.4.4.4 port ssh
> >
> > Two scenarios:
> >
> > 1) When an incoming TCP packet from <any> to 4.4.4.4 on port 22 is seen,
> > that incoming packet is permitted (rule #4).  Outbound responses from
> > 4.4.4.4 to <whoever sent the original incoming packet> are also
> > permitted (rule #1).  Note the "keep state".
> >
> Correct me if I'm wrong, but I think the outbound packet will be matched
> against the #2 rule, as the rule #1 has "flags S/SA" and will not match the
> packet since the packet would have "ACK" flag set. Thus, the state will not
> be created in state table.

The pf.conf(5) manpage for STATEFUL INSPECTION has this to say:

   If a packet matches a pass ... keep state rule, the filter creates a
   state for this connection and automatically lets pass all subsequent
   packets of that connection.

I read this as: "if a packet matches a pass ... keep state rule, pf
begins permitting all I/O for that now-state-tracked session".  One of
the entire points of state tracking is that it lets pf avoid having to
reiterate the rule table for every packet.

This is how I understand it, at least on RELENG_6 with the above rules:

pfbox (4.4.4.4) tries to connect to some host on the Internet via TCP
(ignoring port numbers for now):

  pfbox    -> somehost   = TCP flags SYN set, ACK not set
                         = PASS: matches rule #1
                         = pf creates state-table entry for tracking
  somehost -> pfbox      = TCP flags: SYN set, ACK set
                         = PASS: has state-table entry
  pfbox    -> somehost   = TCP flags: SYN not set, ACK set
                         = PASS: has state-table entry

Things in this case should work fine, relying on the state-table entry
for permitted I/O.

Now the opposite, where some host on the Internet attempts to connect to
4.4.4.4 on port 22:

  somehost -> pfbox      = TCP flags SYN set, ACK not set
                         = PASS: matches rule #4
  pfbox    -> somehost   = TCP flags: SYN set, ACK set
                         = PASS: matches rule #2
  somehost -> pfbox      = TCP flags SYN not set, ACK set
                         = PASS: matches rule #4

A state-table entry won't be created for this one, since rule #1
specifies "flags S/SA" (won't match SYN+ACK both set).

If one was to add "keep state" to rule #4 (RELENG_6), or use RELENG_7
(where "keep state" is implied) and some host on the Internet attempts
to connect to 4.4.4.4 on port 22, we should see:
  
  somehost -> pfbox      = TCP flags SYN set, ACK not set
                         = PASS: matches rule #4
                         = pf creates state-table entry for tracking
  pfbox    -> somehost   = TCP flags: SYN set, ACK set
                         = PASS: has state-table entry
  somehost -> pfbox      = TCP flags SYN not set, ACK set
                         = PASS: has state-table entry

Do we agree?

-- 
| Jeremy Chadwick                                    jdc at parodius.com |
| Parodius Networking                           http://www.parodius.com/ |
| UNIX Systems Administrator                      Mountain View, CA, USA |
| Making life hard for others since 1977.                  PGP: 4BD6C0CB |



More information about the freebsd-pf mailing list