[OpenBSD]

[Previous: Scrub (Packet Normalization)] [Contents] [Next: Packet Queueing and Prioritization]

PF: Anchors and Named Rulesets


Table of Contents


Introduction

In addition to the main ruleset, PF can also evaluate sub rulesets. Since sub rulesets can be manipulated on the fly by using pfctl(8), they provide a convenient way of dynamically altering an active ruleset. Whereas a table is used to hold a dynamic list of addresses, a sub ruleset is used to hold a dynamic set of filter, nat, rdr, and binat rules.

Sub rulesets are attached to the main ruleset by using anchors. There are four types of anchor rules:

Only the main ruleset can contain anchor rules.

Named Rulesets

A named ruleset is a group of filter and/or translation rules that has been assigned a name. An anchor point may contain more than one such ruleset. When PF comes across an anchor rule in the main ruleset, it will evaluate all the rulesets attached to that anchor point in alphabetical order according to their names. Processing will then continue in the main ruleset unless the packet matches a filter rule that uses the quick option or a translation rule within the anchor in which case the match will be considered final and will abort the evaluation of rules in both the anchor and the main rulesets.

For example:

ext_if = "fxp0"

block on $ext_if all
pass  out on $ext_if all keep state
anchor goodguys

This ruleset sets a default deny policy on fxp0 for both incoming and outgoing traffic. Traffic is then statefully passed out and an anchor rule is created named goodguys. Anchors can be populated with rules by two methods:

The load rule causes pfctl to populate the specified anchor and named ruleset by reading rules from a text file. Example:

load anchor goodguys:ssh from "/etc/anchor-goodguys-ssh"

When the main ruleset is loaded, the rules listed in the file /etc/anchor-goodguys-ssh will be loaded into the named ruleset ssh attached to the goodguys anchor.

To add rules to an anchor using pfctl, the following type of command can be used:

# echo "pass in proto tcp from 192.0.2.3 to any port 22" \
   | pfctl -a goodguys:ssh -f -

This adds a pass rule to the ruleset named ssh attached to the goodguys anchor. PF will then evaluate this rule (and any other filter rules that get added) when it reaches the anchor goodguys line in the main ruleset.

Rules can also be saved and loaded from a text file:

# cat >> /etc/anchor-goodguys-www
pass in proto tcp from 192.0.2.3 to any port 80
pass in proto tcp from 192.0.2.4 to any port { 80 443 }

# pfctl -a goodguys:www -f /etc/anchor-goodguys-www

This loads the rules from the /etc/anchor-goodguys-www file into the named ruleset www in the goodguys anchor.

Filter and translation rules can be loaded into a named ruleset using the same syntax and options as rules loaded into the main ruleset. One caveat, however, is that any macros that are used must also be defined within the named ruleset; macros that are defined in the main ruleset are not visible from named rulesets.

Each named ruleset, as well as the main ruleset, exist separately from the other rulesets. Operations done on one ruleset, such as flushing the rules, do not affect any of the others. In addition, removing an anchor point from the main ruleset does not destroy the anchor or any named rulesets that are attached to that anchor. A named ruleset is not destroyed until it's flushed of all rules using pfctl(8). Once an anchor point has no named rulesets attached to it, it's also destroyed.

Anchor Options

Optionally, anchor rules can specify interface, protocol, source and destination address, etc., using the same syntax as filter rules. When such information is given, anchor rules are only processed if the packet matches the anchor rule's definition. For example:
ext_if = "fxp0"

block on $ext_if all
pass  out on $ext_if all keep state
anchor ssh in on $ext_if proto tcp from any to any port 22

The rules in the anchor ssh are only evaluated for TCP packets destined for port 22 that come in on fxp0. Rules are then added to the anchor like so:

# echo "pass in from 192.0.2.10 to any" | pfctl -a ssh:allowed -f -

So, even though the filter rule doesn't specify an interface, protocol, or port, the host 192.0.2.10 will only be permitted to connect using SSH because of the anchor rule's definition.

Manipulating Named Rulesets

Manipulation of named rulesets is performed via pfctl. It can be used to add and remove rules from a ruleset without reloading the main ruleset.

To list all the rules in the ruleset allowed attached to the ssh anchor:

# pfctl -a ssh:allowed -s rules

To flush all filter rules from the same ruleset:

# pfctl -a ssh:allowed -F rules

If the ruleset name is omitted, the action applies to all rules in the anchor.

For a full list of commands, please see pfctl(8).

[Previous: Scrub (Packet Normalization)] [Contents] [Next: Packet Queueing and Prioritization]


[back] www@openbsd.org
$OpenBSD: anchors.html,v 1.10 2004/01/01 04:16:17 nick Exp $