| #
c72fb110
|
| 06-Jan-2026 |
Kristof Provost <kp@FreeBSD.org> |
pf: convert state limiter interface to netlink
This is a new feature with new ioctl calls, so we can safely remove them right now.
Sponsored by: Rubicon Communications, LLC ("Netgate")
|
| #
46164812
|
| 30-Dec-2025 |
Kristof Provost <kp@FreeBSD.org> |
pf: introduce source and state limiters
both source and state limiters can provide constraints on the number of states that a set of rules can create, and optionally the rate at which they are creat
pf: introduce source and state limiters
both source and state limiters can provide constraints on the number of states that a set of rules can create, and optionally the rate at which they are created. state limiters have a single limit, but source limiters apply limits against a source address (or network). the source address entries are dynamically created and destroyed, and are also limited.
this started out because i was struggling to understand the source and state tracking options in pf.conf, and looking at the code made it worse. it looked like some functionality was missing, and the code also did some things that surprised me. taking a step back from it, even it if did work, what is described doesn't work well outside very simple environments.
the functionality i'm talking about is most of the stuff in the Stateful Tracking Options section of pf.conf(4).
some of the problems are illustrated one of the simplest options: the "max number" option that limits the number of states that a rule is allowed to create:
- wiring limits up to rules is a problem because when you load a new ruleset the limit is reset, allowing more states to be created than you intended. - a single "rule" in pf.conf can expand to multiple rules in the kernel thanks to things like macro expansion for multiple ports. "max 1000" on a line in pf.conf could end up being many times that in effect. - when a state limit on a rule is reached, the packet is dropped. this makes it difficult to do other things with the packet, such a redirect it to a tarpit or another server that replies with an outage notices or such.
a state limiter solves these problems. the example from the pf.conf.5 change demonstrates this:
An example use case for a state limiter is to restrict the number of connections allowed to a service that is accessible via multiple protocols, e.g. a DNS server that can be accessed by both TCP and UDP on port 53, DNS-over-TLS on TCP port 853, and DNS-over-HTTPS on TCP port 443 can be limited to 1000 concurrent connections:
state limiter "dns-server" id 1 limit 1000
pass in proto { tcp udp } to port domain state limiter "dns-server" pass in proto tcp to port { 853 443 } state limiter "dns-server"
a single limit across all these protocols can't be implemented with per rule state limits, and any limits that were applied are reset if the ruleset is reloaded.
the existing source-track implementation appears to be incomplete, i could only see code for "source-track global", but not "source-track rule". source-track global is too heavy and unweildy a hammer, and source-track rule would suffer the same issues around rule lifetimes and expansions that the "max number" state tracking config above has.
a slightly expanded example from the pf.conf.5 change for source limiters:
An example use for a source limiter is the mitigation of denial of service caused by the exhaustion of firewall resources by network or port scans from outside the network. The states created by any one scanner from any one source address can be limited to avoid impacting other sources. Below, up to 10000 IPv4 hosts and IPv6 /64 networks from the external network are each limited to a maximum of 1000 connections, and are rate limited to creating 100 states over a 10 second interval:
source limiter "internet" id 1 entries 10000 \ limit 1000 rate 100/10 \ inet6 mask 64
block in on egress pass in quick on egress source limiter "internet" pass in on egress proto tcp probability 20% rdr-to $tarpit
the extra bit is if the source limiter doesn't have "space" for the state, the rule doesn't match and you can fall through to tarpitting 20% of the tcp connections for fun.
i've been using this in anger in production for over 3 years now.
sashan@ has been poking me along (slowly) to get it in a good enough shape for the tree for a long time. it's been one of those years.
bluhm@ says this doesnt break the regress tests. ok sashan@
Obtained from: OpenBSD, dlg <dlg@openbsd.org>, 8463cae72e Sponsored by: Rubicon Communications, LLC ("Netgate")
show more ...
|
| #
2be46b52
|
| 27-Aug-2025 |
Kristof Provost <kp@FreeBSD.org> |
pfctl: fix once rules
parse.y revision 1.682 from 16.07.2018 errornously allowed `match once' and `anchor "a" once'.
Fix both by checking for PF_DROP not PF_MATCH and creating anchors in the parser
pfctl: fix once rules
parse.y revision 1.682 from 16.07.2018 errornously allowed `match once' and `anchor "a" once'.
Fix both by checking for PF_DROP not PF_MATCH and creating anchors in the parser already such that they can be used to distinguish anchor rules in the same check as well.
Found and fixed by Petr Hoffmann <petr.hoffmann at oracle dot com>, thanks!
While here, remove an unneeded cast and make pfctl_add_rule() void as it always returned 0.
OK sashan
Obtained from: OpenBSD, kn <kn@openbsd.org>, 6da84b37b3 Sponsored by: Rubicon Communications, LLC ("Netgate")
show more ...
|
| #
9dfc5e03
|
| 22-Aug-2025 |
Kristof Provost <kp@FreeBSD.org> |
pfctl: allow tables to be defined inside anchors
This change allows user to define table inside the anchor like that: anchor foo { table <bar> { 192.168.1.1 }
pfctl: allow tables to be defined inside anchors
This change allows user to define table inside the anchor like that: anchor foo { table <bar> { 192.168.1.1 } pass in from <bar> to <self> } Without this diff one must either create table <bar> in main ruleset (root) or use 'pfctl -a foo -t bar -T add 192.168.1.1' This glitch is hard to notice. Not many human admins try to attach tables to non-global anchors. Deamons which configure pf(4) automatically at run time such as relayd(8) and spamd(8) create tables attached to thair anchors (for example 'relayd/*') but the deamons use way similar to pfctl(8) to add and manage those tables.
The reason why I'd like to seal this gap is that my long term goal is to turn global `pfr_ktable` in pf(4) into member of pf_anchor. So each ruleset will get its own tree of tables.
feedback and OK bluhm@
Obtained from: OpenBSD, sashan <sashan@openbsd.org>, 30269bc362 Sponsored by: Rubicon Communications, LLC ("Netgate")
show more ...
|
| #
7aac81a6
|
| 20-Aug-2025 |
Kristof Provost <kp@FreeBSD.org> |
pfctl: support recusive printing of tables
Currently 'pfctl -a "*" -sr' recursively walks anchor tree and shows rules found in every anchor. This commit introduces the same behavior for tables. Comm
pfctl: support recusive printing of tables
Currently 'pfctl -a "*" -sr' recursively walks anchor tree and shows rules found in every anchor. This commit introduces the same behavior for tables. Command 'pfctl -a "*" -sT' prints all tables attached to every anchor loaded to pf(4).
Inconsistency has been noticed by Klemens (kn@).
OK @bluhm, OK @kn
Obtained from: OpenBSD, sashan <sashan@openbsd.org>, 3898e3532e Sponsored by: Rubicon Communications, LLC ("Netgate")
show more ...
|
| #
d2761422
|
| 31-Jul-2025 |
Kajetan Staszkiewicz <ks@FreeBSD.org> |
pf: Use different address family for source and redirection address
The function pf_map_addr() and source tracking operate on a single address family. This made sense before introducing address fami
pf: Use different address family for source and redirection address
The function pf_map_addr() and source tracking operate on a single address family. This made sense before introducing address family translation. When combining af-to with route-to or with sticky-address, the next-hop or the NAT address are of different address family than the source address. For example in NAT64 scenaro an IPv6 source address is translated to an IPv4 address and routed over IPv4 gateway.
Make source nodes dual-AF, that is have a separate source AF and redirection AF. Store route AF in struct pf_kstate, export it to pfctl. When loading rules with redirection pools with pfctl store address family of each address. When printing states don't deduce next-hop's address family from af-to, use the one stored in state.
Reviewed by: kp Approved by: kp Sponsored by: InnoGames GmbH Differential Revision: https://reviews.freebsd.org/D51659
show more ...
|
| #
9f21a946
|
| 07-Jul-2025 |
Kristof Provost <kp@FreeBSD.org> |
pf: rename PF_OPT_TABLE_PREFIX to PF_OPTIMIZER_TABLE_PFX
Move it to pf.h. OPT is misleading and usually refers to command line arguments to pfctl
ok sashan kn
Obtained from: OpenBSD, henning <henn
pf: rename PF_OPT_TABLE_PREFIX to PF_OPTIMIZER_TABLE_PFX
Move it to pf.h. OPT is misleading and usually refers to command line arguments to pfctl
ok sashan kn
Obtained from: OpenBSD, henning <henning@openbsd.org>, 9c6ad19ba4 Sponsored by: Rubicon Communications, LLC ("Netgate")
show more ...
|
| #
041ce1d6
|
| 04-Jul-2025 |
Kristof Provost <kp@FreeBSD.org> |
pfctl: recursively flush rules and tables
The recursive operation ("pfctl -a '*' ...") works for '-s' option already. This change enables the same thing for '-F' option, so "pfctl -a '*' -Fa" will f
pfctl: recursively flush rules and tables
The recursive operation ("pfctl -a '*' ...") works for '-s' option already. This change enables the same thing for '-F' option, so "pfctl -a '*' -Fa" will flush everything from PF driver.
The idea was discussed with many on tech@ in spring 2019.
OK kn@
Obtained from: OpenBSD, sashan <sashan@openbsd.org>, ae711728d4 Obtained from: OpenBSD, sashan <sashan@openbsd.org>, 7abd52e24a Sponsored by: Rubicon Communications, LLC ("Netgate")
show more ...
|
| #
ada0846f
|
| 02-Jul-2025 |
Kristof Provost <kp@FreeBSD.org> |
pfctl: Reuse copy_satopfaddr() when killing entries
Recently introduced in pfctl_parser.c r1.333, this helper nicely simplifies code when copying IPs based on their address family, so use it in five
pfctl: Reuse copy_satopfaddr() when killing entries
Recently introduced in pfctl_parser.c r1.333, this helper nicely simplifies code when copying IPs based on their address family, so use it in five other places when killing state or source node entries.
All addresses copied in these code paths result from either pfctl_parse_host() or pfctl_addrprefix() which guarantee the address family set to AF_INET or AF_INET6. Therefore, effectively relaxing the case of unhandled families from errx(3) in callers to warnx(3) in copy_satopfaddr() is safe since it's never reached.
OK sashan
Obtained from: OpenBSD, kn <kn@openbsd.org>, 0ff82421d8 Sponsored by: Rubicon Communications, LLC ("Netgate")
show more ...
|
| #
fb48e6d7
|
| 27-Jun-2025 |
Kristof Provost <kp@FreeBSD.org> |
pfctl: Remove unused af argument from unmask()
This has been unused for years.
While here, zap the duplicate function signature from pfctl.h (already present in pfctl_parser.h); spotted by sashan,
pfctl: Remove unused af argument from unmask()
This has been unused for years.
While here, zap the duplicate function signature from pfctl.h (already present in pfctl_parser.h); spotted by sashan, thanks.
OK sashan
Obtained from: OpenBSD, kn <kn@openbsd.org>, f0bb6ca5dd Sponsored by: Rubicon Communications, LLC ("Netgate")
show more ...
|
| #
5c0eb439
|
| 27-Jun-2025 |
Kristof Provost <kp@FreeBSD.org> |
pfctl: Move AF-specific mask logic from callers into set_ipmask()
Instead of doing the same dance with every caller, check for user provided mask or address familiy specific maximum inside the funct
pfctl: Move AF-specific mask logic from callers into set_ipmask()
Instead of doing the same dance with every caller, check for user provided mask or address familiy specific maximum inside the function itself.
Feedback and OK claudio
Obtained from: OpenBSD, kn <kn@openbsd.org>, c04427dd30 Sponsored by: Rubicon Communications, LLC ("Netgate")
show more ...
|
| #
a7d631f6
|
| 17-Jun-2025 |
Kristof Provost <kp@FreeBSD.org> |
pfctl: fix use-after-free and memory leak in pfctl_optimzie.c
OK bluhm@
Obtained from: OpenBSD, sashan <sashan@openbsd.org>, 43d70b8338 Sponsored by: Rubicon Communications, LLC ("Netgate")
|
| #
4ace4ea9
|
| 29-May-2025 |
Kristof Provost <kp@FreeBSD.org> |
pfctl: add option -S (no domain resolution)
manpage wording and reminder about usage() jmc@ ok florian@ henning@
Reviewed by: ziaee (manpages) Obtained from: OpenBSD, benno <benno@openbsd.org>, 7c8
pfctl: add option -S (no domain resolution)
manpage wording and reminder about usage() jmc@ ok florian@ henning@
Reviewed by: ziaee (manpages) Obtained from: OpenBSD, benno <benno@openbsd.org>, 7c8726d43b Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D50724
show more ...
|
| #
aeddee83
|
| 28-Mar-2025 |
Kajetan Staszkiewicz <ks@FreeBSD.org> |
pfctl: Split pool parsing into separate functions
The pf pools are used in NAT, route-to and af-to rules. Some parts of code are duplicated between them. Create functions apply_redirspec(), apply_na
pfctl: Split pool parsing into separate functions
The pf pools are used in NAT, route-to and af-to rules. Some parts of code are duplicated between them. Create functions apply_redirspec(), apply_nat_ports() and apply_rdr_ports() to handle the common tasks.
Simplify data structures used for pool parsing. Move the contents of struct redirection to struct redirspec. Map all ways of parsing pools directly onto struct redirspec. Name various forms of struct redirspect to hint where they are used.
Remove struct redirspec *rroute from struct filter_opts, because filter_opts is bzero()'ed after the route part of rule is parsed, and thus can't be used.
Add tests to ensure that parsing and error messages behave as expected. The tests have been written and tested with pfctl from before this patch.
This is prerequisite for adding support for OpenBSD NAT syntax.
Reviewed by: kp Approved by: kp (mentor) Sponsored by: InnoGames GmbH Differential Revision: https://reviews.freebsd.org/D49218
show more ...
|
| #
7cef9d19
|
| 10-Feb-2025 |
Kristof Provost <kp@FreeBSD.org> |
pfctl: cache name/index mappings
Provide local implementations of if_nametoindex(3) and if_indextoname(3) that make use of the cache of addresses populated by the ifa_load on startup to save the tro
pfctl: cache name/index mappings
Provide local implementations of if_nametoindex(3) and if_indextoname(3) that make use of the cache of addresses populated by the ifa_load on startup to save the trouble of calling expensive getaddrinfo(3) up to four times per rule. Performance wise this change provides a speed up factor of 20 with a 11k line ruleset on a machine with 150 VLANs and 250 IP addresses (20 seconds down to 1 in this case).
"wow!" henning, ok benno, florian
Obtained from: OpenBSD, mikeb <mikeb@openbsd.org>, 918dda8655 Sponsored by: Rubicon Communications, LLC ("Netgate")
show more ...
|
| #
4aafc73d
|
| 07-Jan-2025 |
Kristof Provost <kp@FreeBSD.org> |
pfctl: pfctl_set_hostid always returns 0
Don't pretend otherwise and make it a void function instead.
ok dlg
Obtained from: OpenBSD, mcbride <mcbride@openbsd.org>, 9ac6101ff7 Sponsored by: Rubicon
pfctl: pfctl_set_hostid always returns 0
Don't pretend otherwise and make it a void function instead.
ok dlg
Obtained from: OpenBSD, mcbride <mcbride@openbsd.org>, 9ac6101ff7 Sponsored by: Rubicon Communications, LLC ("Netgate")
show more ...
|
| #
e11dacbf
|
| 11-Oct-2024 |
Kristof Provost <kp@FreeBSD.org> |
pf: partially import OpenBSD's NAT rewrite
We won't follow this fully, because it involves breaking syntax changes (removing nat/rdr rules and moving this functionality into regular rules) as well a
pf: partially import OpenBSD's NAT rewrite
We won't follow this fully, because it involves breaking syntax changes (removing nat/rdr rules and moving this functionality into regular rules) as well as behaviour changes because NAT is now done after the rules evaluation, rather than before it.
We import some related changes anyway, because it paves the way for nat64 support. This change introduces a new pf_kpool in struct pf_krule, for nat. It is not yet used (but will be for nat64) and renames the existing 'rpool' to 'rdr'.
Obtained from: OpenBSD, henning <henning@openbsd.org>, 0ef3d4febe Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D47783
show more ...
|
| #
347dd053
|
| 29-Nov-2024 |
Richard Scheffenegger <rscheff@FreeBSD.org> |
tcp: add TH_AE capabilities to ppp and pf
Add support for the AE Flag in the TCP header to pf and ppp. Commonalize to the use of "E"(ECE), "W"(CWR) and "e"(AE) for the TCP header flags, in line with
tcp: add TH_AE capabilities to ppp and pf
Add support for the AE Flag in the TCP header to pf and ppp. Commonalize to the use of "E"(ECE), "W"(CWR) and "e"(AE) for the TCP header flags, in line with tcpdump.
Reviewers: kp, cc, tuexen, cy, #transport! Sponsored by: NetApp, Inc. Differential Revision: https://reviews.freebsd.org/D47106
show more ...
|
| #
9c125336
|
| 11-Oct-2024 |
Kristof Provost <kp@FreeBSD.org> |
pf: convert DIOCGETSRCNODES to netlink
Sponsored by: Rubicon Communications, LLC ("Netgate")
|
| #
637d81c5
|
| 29-Aug-2024 |
Kristof Provost <kp@FreeBSD.org> |
pfctl: fix incorrect optimization
In the non-optimized case, an address list containing "any" (ie. { any 10.0.0.1 }) should be folded in the parser to any, not to 10.0.0.1. How long this bug has be
pfctl: fix incorrect optimization
In the non-optimized case, an address list containing "any" (ie. { any 10.0.0.1 }) should be folded in the parser to any, not to 10.0.0.1. How long this bug has been with us is unclear. ok guenther mcbride
Obtained from: OpenBSD, deraadt <deraadt@openbsd.org>, e3b4bc25a0 Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D46580
show more ...
|
| #
d9ab8999
|
| 07-Jun-2024 |
Kristof Provost <kp@FreeBSD.org> |
pf: migrate DIOCGETLIMIT/DIOCSETLIMIT to netlink
Event: Kitchener-Waterloo Hackathon 202406
|
| #
30bad751
|
| 05-Jun-2024 |
Kristof Provost <kp@FreeBSD.org> |
pf: convert DIOCGETTIMEOUT/DIOCSETTIMEOUT to netlink
|
| #
c36c90a2
|
| 01-Jun-2024 |
Kristof Provost <kp@FreeBSD.org> |
pf: convert DIOCSETDEBUG to netlink
Sponsored by: Rubicon Communications, LLC ("Netgate")
|
| #
f1612e70
|
| 09-May-2024 |
Kristof Provost <kp@FreeBSD.org> |
libpfctl: fix file descriptor leak
pfctl_get_rules_info() opened a netlink socket, but failed to close it again. Fix this by factoring out the netlink-based function into a _h variant that takes str
libpfctl: fix file descriptor leak
pfctl_get_rules_info() opened a netlink socket, but failed to close it again. Fix this by factoring out the netlink-based function into a _h variant that takes struct pfctl_handle, and implement pfctl_get_rules_info() based on that, remembering to close the fd.
While here migrate all in-tree consumers to the _h variant.
MFC after: 3 days Sponsored by: Rubicon Communications, LLC ("Netgate")
show more ...
|
| #
7ce98cf2
|
| 06-Oct-2023 |
Kristof Provost <kp@FreeBSD.org> |
pfctl: fix incorrect mask on dynamic address
A PF rule using an IPv4 address followed by an IPv6 address and then a dynamic address, e.g. "pass from {192.0.2.1 2001:db8::1} to (pppoe0)", will have a
pfctl: fix incorrect mask on dynamic address
A PF rule using an IPv4 address followed by an IPv6 address and then a dynamic address, e.g. "pass from {192.0.2.1 2001:db8::1} to (pppoe0)", will have an incorrect /32 mask applied to the dynamic address.
MFC after: 3 weeks Obtained from: OpenBSD See also: https://ftp.openbsd.org/pub/OpenBSD/patches/5.6/common/007_pfctl.patch.sig Sponsored by: Rubicon Communications, LLC ("Netgate") Event: Oslo Hackathon at Modirum
show more ...
|