= Pf = The '''Berkeley Packet Filter''' ('''pf''') is a firewall utility. `pf(4)` is run as a service, while `pfctl(8)` is a userland interface. <<TableOfContents>> ---- == Installation == All [[BSD]] distributions have `pf(8)` installed. Note that the [[BSD/FreeBSD|FreeBSD]] implementation has diverged from the upstream project. ---- == Configuration == For the most basic of usecases, this is perfect. {{{ block in all pass out all keep state }}} To check the configuration of `pf(4)`, run... {{{ pfctl -nf /usr/local/etc/pf.conf }}} === Basic Server Setup === A server needs to be addressable by the external network. In order to minimize repetition, macros should be used to store the TCP and UDP ports that need to be opened. {{{ tcp_services = "{ 22 53 80 443 }" udp_services = "{ 53 }" icmp_types = "echoreq" # Basic inbound TCP rule pass in inet proto tcp $tcp_services flags S/SA keep state # Basic inbound UDP rule pass in inet proto udp $udp_services keep state # Basic ICMP ping rule pass inet proto icmp all icmp-type $icmp_types keep state # Basic outbound connections rule pass out proto tcp all modulate state flags S/SA pass out proto { udp, icmp } all keep state }}} If you have dedicated interfaces for internal and external networks, it becomes much simpler to create rules. {{{ ext_if="xl0" int_if="xl1" localnet=$int_if:network # hardened firewall block drop in quick on $ext_if from $localnet to any block drop out quick on $ext_if from any to $localnet # hardened ICMP rules pass inet proto icmp from $localnet to any keep state pass inet proto icmp from any to $ext_if keep state }}} === Blocking Brute Force Attacks === Clients that attempt a high number of connections are often brute force attackers. `pf(4)` can easily add these addresses to a blacklisted table. {{{ localnet = "{ 192.168.100.0/24 }" tcp_services = "{ 22 }" table <bruteforce> persist block quick from <bruteforce> pass inet proto tcp from any to $localnet port $tcp_services \ flags S/SA keep state \ (max-src-conn 100, max-src-conn-rate 15/5, \ overload <bruteforce> flush global) }}} The `<bruteforce>` table can be cleared based on an expiry time (in seconds) using `pfctl(8)`. {{{ pfctl -t bruteforce -T expire 86400 }}} This can be automated with a `cron` job. ---- == See also == [[https://man.freebsd.org/cgi/man.cgi?pf(4)|pf(4) (FreeBSD)]] [[https://man.freebsd.org/cgi/man.cgi?pf.conf(5)|pf.conf(5) (FreeBSD)]] [[https://man.openbsd.org/pf|pf(4) (OpenBSD)]] [[https://man.openbsd.org/pf.conf|pf.conf(5) (OpenBSD)]] ---- CategoryRicottone