Options
The early release of pfctl(8)
included with OpenBSD 3.0 (and 3.1) used the -O
command-line option to specify the algorithm for filter rules
optimization. Because the new version of pf(4)
included with OpenBSD 3.2 allows more influence over the filtering engine
behavior, these options have moved to the rules file. It is simply more
convenient this way.
There are four categories of options that you may define in your packet filter rules file:
limitloginterfaceoptimizationtimeout
The -O option is still available, but its purpose has
changed. It tells pfctl(8)
to load only the options section from the rules file, as in
$ sudo pfctl -f /etc/pf.conf -O
The already loaded NAT or filter rules will not be modified. Remember that if you disable or remove an option that was defined before, that option will be reset to its default value.
limit
The limit frags n and the limit states
m options set hard limits on the number of memory pools
used by the packet filter. They tell pf(4)
how much memory it can use to store packet fragments (fragments are stored
in memory before reassembly and are reassembled when you use
scrub rules) and state table entries (for stateful filtering;
enable it with the keep state rules in the filter section).
If you set this option, pf(4)
will store only n fragments or
m state table entries. Administrators use this
option to avoid performance hits and to prevent attacks from overwhelming
the firewall's resources. Both limits are independent. You may set either
or both, or you may combine both in a single rule:
#################################################################
# macro definitions
#################################################################
# options: "set"
# ex. 1: limit the number of fragments kept in memory to 30000
set limit frags 30000
# ex. 2: limit the number of state table entries to 25000
set limit states 25000
# ex. 3: combine
set limit { frags 30000, states 25000 }
You can check the current limits:
$ sudo pfctl -s memory
states hard limit 25000
frags hard limit 30000
If a limit is unset, you'll see output similar to this one:
$ sudo pfctl -s memory
states unlimited
frags unlimited
Note that there is no way to unset these limits in OpenBSD 3.2. You
can change the values of limits, if you can change and reload
/etc/pf.conf:
$ sudo vi /etc/pf.conf
$ sudo pfctl -f /etc/pf.conf
To reset limits to their unlimited state, you have to comment out or
remove set limit ... rules in /etc/pf.conf, and
reboot your firewall:
$ sudo vi /etc/pf.conf
$ sudo reboot
This behavior has been fixed in the -current branch and is expected to appear in OpenBSD 3.3.
For more information about packet fragmentation and reassembly, including the issue of timeouts, consult RFC815 [Clark 1982]. If that doesn't answer your questions, read [Stevens 1994, 2:275-300].
loginterface
The new loginterface ifname option specifies the
name of the network interface on which pf(4)
will collect statistics. These statistics are
- bytes received
- bytes sent
- packets received (passed and blocked)
- packets sent (passed and blocked)
The following example shows how to activate this option:
#################################################################
# macro definitions
ext_if = "ne1"
#################################################################
# options: "set"
# ex. 1: collect statistics on ne1
set loginterface $ext_if
pfctl(8)
can display these statistics:
$ sudo pfctl -s info
...
Interface Stats for ne1 IPv4 IPv6
Bytes In 760 0
Bytes Out 696 0
Packets In
Passed 10 0
Blocked 0 0
Packets Out
Passed 6 0
Blocked 0 0
...
You can collect statistics for only one interface, even if you use
multiple set loginterface rules. This snippet
set loginterface ne1
set loginterface ne2
will only collect statistics on ne2 because it was the
last loginterface rule. To switch it off, you must add the
set interface none rule (as the last set
loginterface rule) to /etc/pf.conf and reload the
options with
$ sudo pfctl -O -f /etc/pf.conf
optimization
This rule controls the packet filter engine optimization options. The
old optimization options -O found in earlier version of have
been replaced with the optimization algorithm rule.
There are six values of the algorithm argument:
default: as its name says, it's the default optimization algorithmnormal: same asdefaulthigh-latency: used for high-latency links, such as satellite linkssatellite: same ashigh-latencyaggressive: expires idle connections earlier thandefault; using less memory and CPU time while possibly dropping some legitimate connectionsconservative: tries to avoid dropping any legitimate connections at the expense of increased memory usage and CPU utilization
Don't forget to reload the new options after changing the optimization algorithm:
$ sudo pfctl -O -f /etc/pf.conf
Before you rush to enable these optimization rules, you should know that these algorithms make a difference in special cases like high-latency connections, or very busy corporate, government, or education networks. Small networks and networks with low traffic will see no noticeable performance improvements.
The optimization rule is a shortcut for setting a bunch of
timeout rules quickly. If none of them seem to work in your
particular setup, consider adjusting the timeout values
yourself, as described below.
timeout
The timeout option rule adjusts the expiration time of
stateful connections. These rules only apply to packets matching stateful
connections (established with the keep state keyword in
pass filter rules). The general syntax of this rule is
set timeout protocol.connectionstate timeout, for
example:
#################################################################
# options: "set"
# ex. 1 sets timeout of the stateful connection to 20 seconds
# after receiving the first packet from the host initializing
# this connection.
set timeout tcp.first 20
# ex. 2 sets timeout of the stateful connection to 20 seconds
# after receiving the first packet from the host initializing
# this connection, then, if the connection is established,
# every packet that matches the established state of a TCP
# connection resets the timeout of the TCP connection it is a
# part of to 10 seconds. This is very aggressive, and will result
# in a high percentage of lost valid connections on slow links.
set timeout tcp.first 20
set timeout tcp.established 10
# ex. 3 same as ex. 2, but both rules have been combined on a
# single line (the order of protocol.state rules is not relevant)
set timeout { tcp.first 20, tcp.established 10 }
Example 1 above sets a very aggressive rule. If the connection is not established in 20 seconds, it will be dropped. In example 2, the connection will be dropped if the firewall does not receive a packet that is a part of the established TCP connection in 10 seconds. This is a very aggressive setting.
The protocol.connectionstate can be one of these
values:
tcp.firsttcp.openingtcp.establishedtcp.closingtcp.finwaittcp.closed
All of the above values match various states of a TCP connection cycle. (To learn more about the TCP connection state transition cycle, consult RFC761 [Postel 1980], and if you are still looking for more information, read [Stevens 1994, 1:240-242, 2:805-807].)
You can check global timeout settings with
$ sudo pfctl -s timeouts
tcp.first 120s
tcp.opening 30s
tcp.established 86400s
tcp.closing 900s
tcp.finwait 45s
tcp.closed 90s
udp.first 60s
udp.single 30s
udp.multiple 60s
icmp.first 20s
icmp.error 10s
other.first 60s
other.single 30s
other.multiple 60s
frag 30s
interval 10s
As you can see, it is possible to control other protocols, like UDP, or
ICMP, but the number of protocol.state matches is more
limited:
udp.firstudp.singleudp.multiple
icmp.firsticmp.error
other.firstother.singleother.multiple
other is a catch-all category for protocols which are neither
TCP, UDP, nor ICMP.
The last two timeouts (interval and frag)
specify the interval between flushing expired states and fragments and the
time before unassembled fragments are flushed.
#################################################################
# options: "set"
# this connection.
set timeout interval 20
set timeout frags 20
Because optimization rules reset various
timeout settings, you should always list
optimization rules before your timeout
rules; otherwise your timeout settings will be overwritten
the values introduced by optimization rules.