Hi all,

I'm having an issue with tables and anchors running 4.5 that I've beat
myself up with (along with a few willing souls in #pf and #openbsd) today.

The basis of this problem is the ability (or non-ability in my case) to
access global tables from within anchors, and after spending time searching
Google, finding a few others with similar issues but no resolution, and
posing the question in IRC I'm now posing it to the misc list.


Here is what I have:

stripped down for brevity:

############################################################
############################

##############
### Tables ###
##############
table <abusive_hosts> persist

deny in log quick on dc0 from <abusive_hosts>

#####################
### Overload_Test ###
#####################


anchor "Overload_Test" {
        pass in log quick on dc0 proto tcp \
        from { any } to { any } \
        port { 50 } keep state \
        (max-src-conn-rate 3/15, overload <abusive_hosts> flush)\
        queue ( highest )


}

#######################################################################################

Now what happens here is that a private table "abusive_hosts" gets created
within the Overload_Test anchor and addresses get added to it as I would
expect, which I'm fine with, but this from pfctl(8) confuses me a little:

            "When a rule referring to a table is loaded in an anchor, the rule
             will use the private table if one is defined, and then fall back
             to the table defined in the main ruleset, if there is one.  This


             is similar to C rules for variable scope.  It is possible to cre-
             ate distinct tables with the same name in the global ruleset and
             in an anchor, but this is often bad design and a warning will be


             issued in that case."


This makes me think that since I didn't define the abusive_hosts table
within the anchor above that it would "fall back" to the global one.

Note the warning about the namespace conflict is given.

I'm fine with all of this up to the point where I run into a wall, which is
here, I see two possible solutions

1.  Referencing the global table from within the anchor.

       Something like this

########################################################################################

##############
### Tables ###
##############
table <abusive_hosts> persist

deny in log quick on dc0 from <abusive_hosts>

#####################
### Overload_Test ###
#####################
anchor "Overload_Test" {
        pass in log quick on dc0 proto tcp \
        from { any } to { any } \
        port { 50 } keep state \
        (max-src-conn-rate 3/15, overload <*/abusive_hosts> flush)\


        queue ( highest )
}

#######################################################################################


     However the */absive_hosts obviously is not the right sytax for this,
is there such a syntax?, and if not, how can a table be called global if it
cannot be accessed from a certain place?


Option 2:  Access the private table from outside the anchor:

########################################################################################

##############
### Tables ###
##############
table <abusive_hosts> persist

deny in log quick on dc0 from <Overload_Test/abusive_hosts>

#####################
### Overload_Test ###
#####################
anchor "Overload_Test" {
        pass in log quick on dc0 proto tcp \
        from { any } to { any } \
        port { 50 } keep state \
        (max-src-conn-rate 3/15, overload <abusive_hosts> flush)\


        queue ( highest )
}

#######################################################################################

Of course this doesn't work either, again, not sure if this is possible, and
if it is, I'm not able to find documentation on it up to this point.


Finally, I came up with a somewhat acceptable solution, and that is to do
this:

########################################################################################

#####################
### Overload_Test ###
#####################
anchor "Overload_Test" {
        deny in log quick from <abusive_hosts>
        pass in log quick on dc0 proto tcp \
        from { any } to { any } \


        port { 50 } keep state \
        (max-src-conn-rate 3/15, overload <abusive_hosts> flush)\
        queue ( highest )
}

#######################################################################################


That actually gives the desired behavior, but the only issue I have with
that, is it makes logging a bit confusing, the idea here is to send abusive
hosts to the abusive hosts global table and have that logged separately.

Thanks in advance,

J

Reply via email to