PF OpenBSD states
There are a number of things you can do here.
To see which hosts are responsible for the large number of state table entries you can do pfctl -vs state
.
To add more state table entries you can do what you suggested (set limit states
to a bigger number), but if there is an underlying issue you probably don't want to do that.
You can also consider adjusting the state timeout values (set timeout
), possibly using adaptive timeouts, in order to get rid of old/stale states more quickly.
See the manpage for pf.conf
and the manpage for pfctl
for more information
[Ref: Hitting the PF state table limit]
The PF State tables set the limit of connections that have been authorized, and thus limit the number new connections that the firewall will accept. You may have excess bandwidth available, but if there is no free capacity in the State Tables, then your firewall becomes a bottle-neck.
The configured limits for state information is accessible through pfctl
:
# pfctl -sm
states hard limit 10000
src-nodes hard limit 10000
frags hard limit 5000
tables hard limit 1000
table-entries hard limit 200000
The above limits pre-sets the allocated memory of the defined structures, such that they are always available, and it also limits growth of the said data structures. If your firewall traffic exceeds the above settings, then performance will be affected.
It is now important to monitor the effects of your traffic on the counters for the above limits. The generic -si
output gives us clues to where to further investigate potential bottle-necks in our firewall.
# pfctl -si
Status: Enabled for XXXXXXXXXXXXXXXX Debug: Urgent
State Table Total Rate
current entries 34
searches 96379206 15.2/s
inserts 726196 0.1/s
removals 726162 0.1/s
On the above gateway, connected to two infrequently used laptops,
the current entries
is very low relative to the hard limit 10000
above. Obviously, the current entries
will fluctuate due to use,
and on a busier gateway may fluctuate significantly.
[Ref: Hitting the PF state table limit, Open BSD state hard-limit reached]
An important counter to monitor from pfctl -si
is the memory
counter. The same details should be available through systat pf
.
From an active gateway linking our 6 sites, we get the following from a standard install, no modification to state tables.
# pfctl -si | grep memory
memory 209230 0.1/s
The counter highlights how often PF has failed at least one of the pool(9)
. The higher the number, the higher the frequency of incidences where packets arriving at the firewall have most likely been dropped due to one of the hardware limits.
Our above example shows 209,230 times the memory limit was hit.
The next review is to check with Kernel memory allocations, using vmstat
. To narrow our search down to the effects on the pf state table we check the entry for pfstatepl.
Below, we grab the lines with state or Fail (so we can get the column headers)
# vmstat -m | grep -E "state|Fail"
Name Size Requests Fail InUse Pgreq Pgrel Npage Hiwat Minpg Maxpg Idle
pfstatepl 296 213123877 209235 5075 1050 0 1050 1050 0 2308 526
pfstatekeypl
pfstateitempl
pfstatepl
is the label for memory allocated for the struct pf_state
(/usr/src/sys/net/pf_ioctl.c
) The failures do seem to be significant.
pfctl -vvsi | grep congestion