Server PF Boilerplate

Date: 20251216

Scope:

PF built into OpenBSD and FreeBSD can give protection to services running on a server. To avoid any performance penalties and where filtering is not required for specific services, this should deviate away from block all/allow to block known/restrict. In this configuration, users must be aware of the services they are running because accidentally exposed services will immediately be available on the wire.

Instructions:

On FreeBSD, enable pf and pflog (see below). PF on OpenBSD is on by default:

service pf enable && service pf start
service pflog enable && service pflog start

Set up tables to include your management addresses. There should be no reason for adhoc connectivity to these hosts for management functions. Use tables instead of macros to reduce the rule set and speed up rule evaluation. While tables do use more memory, this is less of an issue these days, but the performance increase is noticeable on large rule sets:

table <mgmt_v6> persist { 2001:db8:dead:1::/64 }
table <mgmt_v4> persist { 198.51.100.0/24 }

Not mandatory, but a lot of mirror maintainers have issues with not only AI bots but China Mobile. They will use mirrors or servers with large data sets outside of their network to shore up bandwidth ratios on their international transit providers. This is completely optional and depends on the audience you are trying to attract with the service:

table <china_mobile> persist { 111.0.0.0/10, 223.64.0.0/10, 2409:8000::/20 } # Problematic provider that uses your resources for ingress balance

Restrict IPv6 and IPv4 ICMP types to only what is necessary for the server to connect and provide health status:

icmp6_types="{ unreach, toobig, timex, paramprob, echoreq, echorep, routeradv, routersol, neighbradv, neighbrsol }"
icmp4_types="{ unreach, timex, paramprob, echoreq }"

Loopback interfaces typically don't need protection or filtering. Set PF to skip this interface so it doesn't get included by any rule evaluation by accident:

set skip on lo

Block all known management services. Typically, set to drop for these services so they aren't visible and avoids detection in high-speed network scans. To reduce connection load and terminate connections if they don't match an evaluation rule, change rules from drop to return:

block drop in quick from <china_mobile>
block drop in log proto tcp to port ssh
block drop in log proto udp to port snmp
block drop in proto icmp6
block drop in proto icmp

For the above management services, create rules for explicit access to these services:

## ICMP
pass inet6 proto icmp6 icmp6-type $icmp6_types
pass inet proto icmp all icmp-type $icmp4_types

## SSH
pass in log inet6 proto tcp from <mgmt_v6> to port ssh
pass in log proto tcp from <mgmt_v4> to port ssh

## SNMP
pass in log proto udp from <mgmt_v6> to port snmp

Once rule build is complete, validate the The changes:

pfctl -nf /etc/pf.conf

If there are no syntax errors, perform a load of the rules:

pfctl -f /etc/pf.conf

Build on the above rule set for service or site-specific requirements. Further details on traffic management can be found in the relevant in the OpenBSD and FreeBSD pf.conf man pages.

Complete /etc/pf.conf rule set:

table <mgmt_v6> persist { 2001:db8:dead:1::/64 }
table <mgmt_v4> persist { 198.51.100.0/24 }
table <china_mobile> persist { 111.0.0.0/10, 223.64.0.0/10, 2409:8000::/20 } # Problematic provider that uses your resources for ingress balance
icmp6_types="{ unreach, toobig, timex, paramprob, echoreq, echorep, routeradv, routersol, neighbradv, neighbrsol }"
icmp4_types="{ unreach, timex, paramprob, echoreq }"

set skip on lo

block drop in quick from <china_mobile>
block drop in log proto tcp to port ssh
block drop in log proto udp to port snmp
block drop in proto icmp6
block drop in proto icmp

## ICMP
pass inet6 proto icmp6 icmp6-type $icmp6_types
pass inet proto icmp all icmp-type $icmp4_types

## SSH
pass in log inet6 proto tcp from <mgmt_v6> to port ssh
pass in log proto tcp from <mgmt_v4> to port ssh

## SNMP
pass in log proto udp from <mgmt_v6> to port snmp

End of Document

On this page
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9