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