Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
PFCTL(8)		FreeBSD	System Manager's Manual		      PFCTL(8)

     pfctl -- control the packet filter	(PF) device

     pfctl [-deghNnPqrvz] [-a anchor] [-D macro=value] [-F modifier] [-f file]
	   [-i interface] [-K key] [-k key] [-L	statefile] [-o level]
	   [-p device] [-S statefile] [-s modifier [-R id]]
	   [-t table -T	command	[address ...]] [-V rdomain] [-x	level]

     The pfctl utility communicates with the packet filter device using	the
     ioctl interface described in pf(4).  It allows ruleset and	parameter con-
     figuration, and retrieval of status information from the packet filter.
     Packet filtering restricts	the types of packets that pass through network
     interfaces	entering or leaving the	host based on filter rules as de-
     scribed in	pf.conf(5).  The packet	filter can also	replace	addresses and
     ports of packets.

     The packet	filter is enabled by default.  Should pfctl be unable to load
     a ruleset,	an error occurs	and the	original ruleset remains in place.  If
     this happens at system startup, the ruleset defined by the	RULES variable
     in	rc(8) remains in place.

     The packet	filter does not	itself forward packets between interfaces.
     Forwarding	can be enabled by setting the sysctl(8)	variables
     net.inet.ip.forwarding and/or net.inet6.ip6.forwarding to 1.  Set them
     permanently in sysctl.conf(5).

     At	least one option must be specified.  The options are as	follows:

     -a	anchor
	     Apply flags -f, -F, -s, and -T only to the	rules in the specified
	     anchor.  In addition to the main ruleset, pfctl can load and ma-
	     nipulate additional rulesets by name, called anchors.  The	main
	     ruleset is	the default anchor.

	     Anchors are referenced by name and	may be nested, with the	vari-
	     ous components of the anchor path separated by `/'	characters,
	     similar to	how file system	hierarchies are	laid out.  The last
	     component of the anchor path is where ruleset operations are per-

	     Evaluation	of anchor rules	from the main ruleset is described in

	     For example, the following	will show all filter rules (see	the -s
	     flag below) inside	the anchor "authpf/smith(1234)", which would
	     have been created for user	"smith"	by authpf(8), PID 1234:

		   # pfctl -a "authpf/smith(1234)" -s rules

	     Private tables can	also be	put inside anchors, either by having
	     table statements in the pf.conf(5)	file that is loaded in the an-
	     chor, or by using regular table commands, as in:

		   # pfctl -a foo/bar -t mytable -T add

	     When a rule referring to a	table is loaded	in an anchor, the rule
	     will use the private table	if one is defined, and then fall back
	     to	the table defined in the main ruleset, if there	is one.	 This
	     is	similar	to C rules for variable	scope.	It is possible to cre-
	     ate distinct tables with the same name in the global ruleset and
	     in	an anchor, but this is often bad design	and a warning will be
	     issued in that case.

	     By	default, recursive inline printing of anchors applies only to
	     unnamed anchors specified inline in the ruleset.  If the anchor
	     name is terminated	with a `*' character, the -s flag will recur-
	     sively print all anchors in a brace delimited block.  For example
	     the following will	print the "authpf" ruleset recursively:

		   # pfctl -a 'authpf/*' -sr

	     To	print the main ruleset recursively, specify only `*' as	the
	     anchor name:

		   # pfctl -a '*' -sr

	     To	flush all rulesets and tables recursively, specify only	`*' as
	     the anchor	name:

		   # pfctl -a '*' -Fa

     -D	macro=value
	     Define macro to be	set to value on	the command line.  Overrides
	     the definition of macro in	the ruleset.

     -d	     Disable the packet	filter.

     -e	     Enable the	packet filter.

     -F	modifier
	     Flush the filter parameters specified by modifier (may be abbre-

	     -F	rules	   Flush the filter rules.
	     -F	states	   Flush the state table (NAT and filter).
	     -F	Sources	   Flush the source tracking table.
	     -F	info	   Flush the filter information	(statistics that are
			   not bound to	rules).
	     -F	Tables	   Flush the tables.
	     -F	osfp	   Flush the passive operating system fingerprints.
	     -F	Reset	   Reset limits, timeouts and other options back to
			   default settings.  See the OPTIONS section in
			   pf.conf(5) for details.
	     -F	all	   Flush all of	the above.

	     If	-a is specified	as well	and anchor is terminated with a	`*'
	     character,	rules, Tables and all flush the	given anchor recur-

     -f	file
	     Replace the current ruleset with the rules	contained in file.
	     This file may contain macros, tables, options, and	normalization,
	     queueing, translation, and	filtering rules.  With the exception
	     of	macros and tables, the statements must appear in that order.

     -g	     Include output helpful for	debugging.

     -h	     Help.

     -i	interface
	     Restrict the operation to the given interface.

     -K	key  Kill all of the source tracking entries originating from the host
	     or	network	specified by key.  A second -K option may be speci-
	     fied, which will kill all the source tracking entries from	the
	     first host/network	to the second.

     -k	key  Kill all of the state entries originating from the	host or	net-
	     work specified by key.  A second -k option	may be specified,
	     which will	kill all the state entries from	the first host/network
	     to	the second.

	     A network prefix length of	0 can be used as a wildcard.  To kill
	     all states	with the target	"host2":

		   # pfctl -k	-k host2

	     It	is also	possible to kill states	by rule	label, state key, or
	     state ID.	In this	mode the first -k argument is used to specify
	     the type; a second	-k gives the actual target.

	     To	kill states by rule label, use the label modifier.  To kill
	     all states	created	from rules carrying the	label "foobar":

		   # pfctl -k label -k foobar

	     To	kill one specific state	by its state key (as shown by pfctl -s
	     state), use the key modifier.  To kill a state originating	from to, protocol TCP, use:

		   # pfctl -k key -k 'tcp <-'

	     To	kill one specific state	by its unique state ID (as shown by
	     pfctl -s state -vv), use the id modifier.	To kill	a state	with
	     ID	4823e84500000003 use:

		   # pfctl -k id -k 4823e84500000003

	     To	kill a state with ID 4823e84500000018 created from a backup
	     firewall with hostid 00000002 use:

		   # pfctl -k id -k 4823e84500000018/2

     -L	statefile
	     Load pf states from the file specified by statefile.

     -N	     Do	not perform domain name	resolution.  If	a name cannot be re-
	     solved without DNS, an error will be reported.

     -n	     Do	not actually load rules, just parse them.

     -o	level
	     Control the ruleset optimizer, overriding any rule	file settings.

	     -o	none	   Disable the ruleset optimizer.
	     -o	basic	   Enable basic	ruleset	optimizations.	This is	the
			   default behaviour.
	     -o	profile	   Enable basic	ruleset	optimizations with profiling.
	     For further information on	the ruleset optimizer, see pf.conf(5).

     -P	     Print ports using their names in /etc/services if available.

     -p	device
	     Use the device file device	instead	of the default /dev/pf.

     -q	     Only print	errors and warnings.

     -r	     Perform reverse DNS lookups on states and tables when displaying
	     them.  -N and -r are mutually exclusive.

     -S	statefile
	     Store the pf state	table in the file specified by statefile.

     -s	modifier
	     Show the filter parameters	specified by modifier (may be abbrevi-

	     -s	queue	     Show the currently	loaded queue definitions.
			     When used together	with -v, per-queue statistics
			     are also shown.  When used	together with -v -v,
			     pfctl will	loop and show updated queue statistics
			     every five	seconds, including measured bandwidth
			     and packets per second.
	     -s	rules	     Show the currently	loaded filter rules.  If -R id
			     is	specified as well, only	the rule with the
			     specified numeric ID is shown.  When used to-
			     gether with -v, the per-rule statistics (number
			     of	evaluations, packets and bytes)	are also
			     shown.  Note that the "skip step" optimization
			     done automatically	by the kernel will skip	evalu-
			     ation of rules where possible.  Packets passed
			     statefully	are counted in the rule	that created
			     the state (even though the	rule isn't evaluated
			     more than once for	the entire connection).
	     -s	Anchors	     Show the currently	loaded anchors directly	at-
			     tached to the main	ruleset.  If -a	anchor is
			     specified as well,	the anchors loaded directly
			     below the given anchor are	shown instead.	If -v
			     is	specified, all anchors attached	under the tar-
			     get anchor	will be	displayed recursively.
	     -s	states	     Show the contents of the state table.  If -R id
			     is	specified as well, only	states created by the
			     rule with the specified numeric ID	are shown.
	     -s	Sources	     Show the contents of the source tracking table.
	     -s	info	     Show filter information (statistics and coun-
			     ters).  When used together	with -v, source	track-
			     ing statistics, the firewall's 32-bit hostid num-
			     ber and the main ruleset's	MD5 checksum for use
			     with pfsync(4) are	also shown.
	     -s	labels	     Show per-rule statistics (label, evaluations,
			     packets total, bytes total, packets in, bytes in,
			     packets out, bytes	out, state creations) of fil-
			     ter rules with labels, useful for accounting.  If
			     -R	id is specified	as well, only the statistics
			     for the rule with the specified numeric ID	are
	     -s	timeouts     Show the current global timeouts.
	     -s	memory	     Show the current pool memory hard limits.
	     -s	Tables	     Show the list of tables.
	     -s	osfp	     Show the list of operating	system fingerprints.
	     -s	Interfaces   Show the list of interfaces and interface groups
			     available to PF.  When used together with -v, it
			     additionally lists	which interfaces have skip
			     rules activated.  When used together with -vv,
			     interface statistics are also shown.  -i can be
			     used to select an interface or a group of inter-
	     -s	all	     Show all of the above, except for the lists of
			     interfaces	and operating system fingerprints.

	     Counters shown with -s info are:

	     match	     explicit rule match
	     bad-offset	     currently unused
	     fragment	     invalid fragments dropped
	     short	     short packets dropped
	     normalize	     dropped by	normalizer: illegal packets
	     memory	     memory could not be allocated
	     bad-timestamp   bad TCP timestamp;	RFC 1323
	     congestion	     network interface queue congested
	     ip-option	     bad IP/IPv6 options
	     proto-cksum     invalid protocol checksum
	     state-mismatch  packet was	associated with	a state	entry, but se-
			     quence numbers did	not match
	     state-insert    state insertion failure
	     state-limit     configured	state limit was	reached
	     src-limit	     source node/connection limit
	     synproxy	     dropped by	synproxy
	     translate	     no	free ports in translation port range
	     no-route	     dropped by	no-route

     -T	command	[address ...]
	     Specify the command (may be abbreviated) to apply to the table.
	     Commands include:

	     -T	kill	   Kill	a table.
	     -T	flush	   Flush all addresses of a table.
	     -T	add	   Add one or more addresses in	a table.  Automati-
			   cally create	a persistent table if it does not ex-
	     -T	delete	   Delete one or more addresses	from a table.
	     -T	expire number
			   Delete addresses which had their statistics cleared
			   more	than number seconds ago.  For entries which
			   have	never had their	statistics cleared, number
			   refers to the time they were	added to the table.
	     -T	replace	   Replace the addresses of the	table.	Automatically
			   create a persistent table if	it does	not exist.
	     -T	show	   Show	the content (addresses)	of a table.
	     -T	test	   Test	if the given addresses match a table.
	     -T	zero	   Clear all the statistics of a table.

	     For the add, delete, replace, and test commands, the list of ad-
	     dresses can be specified either directly on the command line
	     and/or in an unformatted text file, using the -f flag.  Comments
	     starting with a `#' are allowed in	the text file.	With these
	     commands, the -v flag can also be used once or twice, in which
	     case pfctl	will print the detailed	result of the operation	for
	     each individual address, prefixed by one of the following let-

	     A	  The address/network has been added.
	     C	  The address/network has been changed (negated).
	     D	  The address/network has been deleted.
	     M	  The address matches (test operation only).
	     X	  The address/network is duplicated and	therefore ignored.
	     Y	  The address/network cannot be	added/deleted due to conflict-
		  ing `!' attributes.
	     Z	  The address/network has been cleared (statistics).

	     Each table	can maintain a set of counters that can	be retrieved
	     using the -v flag of pfctl.  For example, the following commands
	     define a wide open	firewall which will keep track of packets go-
	     ing to or coming from the OpenBSD FTP server.  The	following com-
	     mands configure the firewall and send 10 pings to the FTP server:

		   # printf "table <test> counters { }\n \
		       pass out	to <test>\n" | pfctl -f-
		   # ping -qc10

	     We	can now	use the	table show command to output, for each address
	     and packet	direction, the number of packets and bytes that	are
	     being passed, matched or blocked by rules referencing the table.
	     Note that the match counters are incremented for every match rule
	     in	which they are referenced, meaning that	a single packet	may be
	     counted multiple times.  The time at which	the current accounting
	     started is	also shown with	the "Cleared" line.

		   # pfctl -t test -vTshow
			   Cleared:	   Fri Jun 28 11:17:37 2013
			   In/Block:	   [ Packets: 0	   Bytes: 0	   ]
			   In/Match	   [ Packets: 54   Bytes: 10028	   ]
			   In/Pass:	   [ Packets: 5	   Bytes: 1949	   ]
			   Out/Block:	   [ Packets: 0	   Bytes: 0	   ]
			   Out/Match	   [ Packets: 65   Bytes: 12684	   ]
			   Out/Pass:	   [ Packets: 6	   Bytes: 389	   ]

	     Similarly,	it is possible to view global information about	the
	     tables by using the -v modifier twice and the -s Tables command.
	     This will display the number of addresses on each table, the num-
	     ber of rules which	reference the table, and the global packet
	     statistics	for the	whole table:

		   # pfctl -vvsTables
		   --a-r-C test
			   Addresses:	1
			   Cleared:	Fri Jun	28 11:17:37 2013
			   References:	[ Anchors: 0	   Rules: 4	   ]
			   Evaluations:	[ NoMatch: 35	   Match: 8	   ]
			   In/Block:	[ Packets: 0	   Bytes: 0	   ]
			   In/Match:	[ Packets: 54	   Bytes: 10028	   ]
			   In/Pass:	[ Packets: 5	   Bytes: 1949	   ]
			   In/XPass:	[ Packets: 0	   Bytes: 0	   ]
			   Out/Block:	[ Packets: 0	   Bytes: 0	   ]
			   Out/Match:	[ Packets: 65	   Bytes: 12684	   ]
			   Out/Pass:	[ Packets: 6	   Bytes: 389	   ]
			   Out/XPass:	[ Packets: 0	   Bytes: 0	   ]

	     Only packets creating state are matched in	the Evaluations	line,
	     but all packets passing as	a result of the	state are correctly
	     accounted for.  Reloading the table(s) or ruleset will not	affect
	     packet accounting in any way.  The	two "XPass" counters are in-
	     cremented instead of the "Pass" counters when a "stateful"	packet
	     is	passed but doesn't match the table anymore.  This will happen
	     in	our example if someone flushes the table while the ping(8)
	     command is	running.

	     When used with a single -v, pfctl will only display the first
	     line containing the table flags and name.	The flags are defined
	     as	follows:

	     c	  For constant tables, which cannot be altered outside
	     p	  For persistent tables, which don't get automatically killed
		  when no rules	refer to them.
	     a	  For tables which are part of the active tableset.  Tables
		  without this flag do not really exist, cannot	contain	ad-
		  dresses, and are only	listed if the -g flag is given.
	     i	  For tables which are part of the inactive tableset.  This
		  flag can only	be witnessed briefly during the	loading	of
	     r	  For tables which are referenced (used) by rules.
	     h	  This flag is set when	a table	in the main ruleset is hidden
		  by one or more tables	of the same name from anchors attached
		  below	it.
	     C	  This flag is set when	per-address counters are enabled on
		  the table.

     -t	table
	     Specify the name of the table.

     -V	rdomain
	     Select the	routing	domain to be used to kill states by host or by
	     label.  The rdomain of a state is displayed in parentheses	before
	     the host by -s states.

     -v	     Produce more verbose output.  A second use	of -v will produce
	     even more verbose output including	ruleset	warnings.  See the
	     previous section for its effect on	table commands.

     -x	level
	     Set the debug level, which	limits the severity of log messages
	     printed by	pf(4).	This should be a keyword from the following
	     ordered list (highest to lowest): emerg, alert, crit, err,
	     warning, notice, info, and	debug.	These keywords correspond to
	     the similar (LOG_)	values specified to the	syslog(3) library rou-
	     tine, and may be abbreviated on the command line.

     -z	     Clear per-rule statistics.

     /etc/pf.conf  Packet filter rules file.
     /etc/pf.os	   Passive operating system fingerprint	database.

     pf(4), pf.conf(5),	pf.os(5), sysctl.conf(5), authpf(8), ftp-proxy(8),
     rc(8), rc.conf(8),	sysctl(8)

     The pfctl program and the pf(4) filter mechanism first appeared in
     OpenBSD 3.0.

FreeBSD	13.0			 July 20, 2020			  FreeBSD 13.0


Want to link to this manual page? Use this URL:

home | help