xref: /netbsd-src/usr.sbin/npf/npfctl/npf.conf.5 (revision 8e33eff89e26cf71871ead62f0d5063e1313c33a)
1.\"    $NetBSD: npf.conf.5,v 1.91 2020/05/30 14:16:56 rmind Exp $
2.\"
3.\" Copyright (c) 2009-2020 The NetBSD Foundation, Inc.
4.\" All rights reserved.
5.\"
6.\" This material is based upon work partially supported by The
7.\" NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\"    notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\"    notice, this list of conditions and the following disclaimer in the
16.\"    documentation and/or other materials provided with the distribution.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28.\" POSSIBILITY OF SUCH DAMAGE.
29.\"
30.Dd May 19, 2020
31.Dt NPF.CONF 5
32.Os
33.Sh NAME
34.Nm npf.conf
35.Nd NPF packet filter configuration file
36.\" -----
37.Sh DESCRIPTION
38.Nm
39is the default configuration file for the NPF packet filter.
40.Pp
41This manual page serves as a reference for editing
42.Nm .
43Please refer to the official NPF documentation website for comprehensive and
44in-depth information.
45.Pp
46There are multiple structural elements that
47.Nm
48may contain, such as:
49.Pp
50.Bl -bullet -offset indent -compact
51.It
52variables
53.It
54table definitions (with or without content)
55.It
56abstraction groups
57.It
58packet filtering rules
59.It
60map rules for address translation
61.It
62application level gateways
63.It
64procedure definitions to call on filtered packets
65.It
66parameter settings.
67.El
68.Sh SYNTAX
69.Ss Variables
70Variables are specified using the dollar
71.Pq Li $
72sign, which is used for both
73definition and referencing of a variable.
74Variables are defined by assigning a value to them as follows:
75.Pp
76.Dl $var1 = 10.0.0.1
77.Pp
78A variable may also be defined as a set:
79.Pp
80.Dl $var2 = { 10.0.0.1, 10.0.0.2 }
81.Pp
82Common variable definitions are for IP addresses, networks, ports,
83and interfaces.
84.Ss Tables
85Tables are specified using a name between angle brackets
86.Sq Li <
87and
88.Sq Li > .
89The following is an example of table definition:
90.Pp
91.Dl table <blocklist> type ipset
92.Pp
93Currently, tables support three data storage types:
94.Cm ipset ,
95.Cm lpm ,
96or
97.Cm const .
98The contents of the table may be pre-loaded from the specified file.
99The
100.Cm const
101tables are immutable (no insertions or deletions after loading) and
102therefore must always be loaded from a file.
103.Pp
104The specified file should contain a list of IP addresses and/or networks
105in the form of
106.Li 10.1.1.1
107or
108.Li 10.0.0.0/24 .
109.Pp
110Tables of type
111.Cm ipset
112and
113.Cm const
114can only contain IP addresses (without masks).
115The
116.Cm lpm
117tables can contain networks and they will perform the longest
118prefix match on lookup.
119.Ss Interfaces
120In NPF, an interface can be referenced directly by using its name, or can be
121passed to an extraction function which will return a list of IP addresses
122configured on the actual associated interface.
123.Pp
124It is legal to pass an extracted list from an interface in keywords where
125NPF would expect instead a direct reference to said interface.
126In this case, NPF infers a direct reference to the interface, and does not
127consider the list.
128.Pp
129There are two types of IP address lists.
130With a static list, NPF will capture the interface addresses on configuration
131load, whereas with a dynamic list NPF will capture the runtime list of
132addresses, reflecting any changes to the interface, including the attach and
133detach.
134Note that with a dynamic list, bringing the interface down has no effect,
135all addresses will remain present.
136.Pp
137Three functions exist, to extract addresses from an interface with a chosen
138list type and IP address type:
139.Bl -tag -width "Fn ifaddrs interface" -offset indent
140.It Fn inet4 interface
141Static list.
142IPv4 addresses.
143.It Fn inet6 interface
144Static list.
145IPv6 addresses.
146.It Fn ifaddrs interface
147Dynamic list.
148Both IPv4 and IPv6.
149The
150.Cm family
151keyword of a filtering rule can be used in combination to explicitly select
152an IP address type.
153This function can also be used with
154.Cm map
155to specify the translation address, see below.
156.El
157.Pp
158Example of configuration:
159.Bd -literal -offset indent
160$var1 = inet4(wm0)
161$var2 = ifaddrs(wm0)
162
163group default {
164	block in on wm0 all               # rule 1
165	block in on $var1 all             # rule 2
166	block in on inet4(wm0) all        # rule 3
167	pass in on inet6(wm0) from $var2  # rule 4
168	pass in on wm0 from ifaddrs(wm0)  # rule 5
169}
170.Ed
171.Pp
172In the above example,
173.Li $var1
174is the static list of IPv4 addresses configured
175on wm0, and
176.Li $var2
177is the dynamic list of all the IPv4 and IPv6 addresses configured on wm0.
178The first three rules are equivalent, because with the
179.Ic block Ar "..." Cm on Li < Ns Ar interface Ns Li >
180syntax, NPF expects a direct reference to an interface, and therefore does
181not consider the extraction functions.
182The fourth and fifth rules are equivalent, for the same reason.
183.Ss Groups
184NPF requires that all rules be defined within groups.
185Groups can be thought of as higher level rules which can contain subrules.
186Groups may have the following options: name, interface, and direction.
187Packets matching group criteria are passed to the ruleset of that group.
188If a packet does not match any group, it is passed to the
189.Dv default
190group.
191The
192.Dv default
193group must always be defined.
194.Pp
195Example of configuration:
196.Bd -literal -offset indent
197group "my-name" in on wm0 {
198	# List of rules, for packets received on wm0
199}
200group default {
201	# List of rules, for the other packets
202}
203.Ed
204.Ss Rules
205With a rule statement NPF is instructed to
206.Ic pass
207or
208.Ic block
209a packet depending on packet header information, transit direction and
210the interface it arrived on, either immediately upon match or using the
211last match.
212.Pp
213If a packet matches a rule which has the
214.Cm final
215option set, this rule is considered the last matching rule, and
216evaluation of subsequent rules is skipped.
217Otherwise, the last matching rule is used.
218.Pp
219The
220.Cm proto
221keyword can be used to filter packets by layer 4 protocol (TCP, UDP, ICMP
222or other).
223Its parameter should be a protocol number or its symbolic name,
224as specified in the
225.Pa /etc/protocols
226file.
227This keyword can additionally have protocol-specific options, such as
228.Cm flags .
229.Pp
230The
231.Cd flags
232keyword can be used to match the packets against specific TCP flags,
233according to the following syntax:
234.Pp
235.D1 Ic proto Cm tcp flags Ar match Ns Op Li / Ns Ar mask
236.Pp
237Where
238.Ar match
239is the set of TCP flags to be matched, out of the
240.Ar mask
241set, both sets being represented as a string combination of:
242.Sq Cm S
243(SYN),
244.Sq Cm A
245(ACK),
246.Sq Cm F
247(FIN), and
248.Sq Cm R
249(RST).
250The flags that are not present in
251.Ar mask
252are ignored.
253.Pp
254To notify the sender of a blocking decision, three
255.Cm return
256options can be used in conjunction with a
257.Ic block
258rule:
259.Bl -tag -width "Cm return-icmp" -offset indent
260.It Cm return
261Behaves as
262.Cm return-rst
263or
264.Cm return-icmp ,
265depending on whether the packet being blocked is TCP or UDP.
266.It Cm return-rst
267Return a TCP RST message, when the packet being blocked is a TCP packet.
268Applies to IPv4 and IPv6.
269.It Cm return-icmp
270Return an ICMP UNREACHABLE message, when the packet being blocked is a UDP packet.
271Applies to IPv4 and IPv6.
272.El
273.Pp
274The
275.Cm from
276and
277.Cm to
278keywords are provided to filter by source or destination IP addresses.
279They can be used in conjunction with the
280.Cm port
281keyword.
282Negation (the exclamation mark) can be used in front of the address
283filter criteria.
284.Pp
285Further packet specification at present is limited to TCP and UDP
286understanding source and destination ports, and ICMP and IPv6-ICMP
287understanding icmp-type.
288.Pp
289A rule can also instruct NPF to create an entry in the state table when
290passing the packet or to apply a procedure to the packet (e.g. "log").
291.Pp
292A
293.Dq fully-featured
294rule would for example be:
295.Bd -literal -offset indent
296pass stateful in final family inet4 proto tcp flags S/SA \e
297        from $source port $sport to $dest port $dport    \e
298        apply \*qsomeproc\*q
299.Ed
300.Pp
301Alternatively, NPF supports
302.Xr pcap-filter 7
303syntax, for example:
304.Pp
305.Dl block out final pcap-filter \*qtcp and dst 10.1.1.252\*q
306.Pp
307Fragments are not selectable since NPF always reassembles packets
308before further processing.
309.Ss Stateful
310NPF supports stateful packet inspection which can be used to bypass
311unnecessary rule processing as well as to complement NAT.
312The connection state is uniquely identified by an n-tuple: IP version,
313layer 4 protocol, source and destination IP addresses and port numbers.
314Each state is represented by two keys: one for the original flow and
315one for the reverse flow, so that the reverse lookup on the returning
316packets would succeed.
317The packets are matched against the connection direction respectively.
318.Pp
319Depending on the settings (see the section on
320.Li state.key
321in the
322.Xr npf-params 7
323manual), the connection identifier (keys) may also include the interface ID,
324making the states per-interface.
325.Pp
326Stateful packet inspection is enabled using the
327.Cm stateful
328or
329.Cm stateful-all
330keywords.
331The former matches the interface after the state lookup, while the latter
332avoids matching the interface (assuming the
333.Li state.key.interface
334parameter is disabled),
335i.e. making the state global, and must be used with caution.
336In both cases, a full TCP state tracking is performed for TCP connections
337and a limited tracking for message-based protocols (UDP and ICMP).
338.Pp
339By default, a stateful rule implies SYN-only flag check
340.Pq Dq Li flags S/SAFR
341for the TCP packets.
342It is not advisable to change this behavior; however,
343it can be overridden with the aforementioned
344.Cm flags
345keyword.
346.Ss Map
347Network Address Translation (NAT) is expressed in a form of segment mapping.
348The translation may be
349.Cm dynamic
350(stateful) or
351.Cm static
352(stateless).
353The following mapping types are available:
354.Pp
355.Bl -tag -width "Cm \&<->" -offset indent -compact
356.It Cm \&->
357outbound NAT (translation of the source)
358.It Cm \&<-
359inbound NAT (translation of the destination)
360.It Cm \&<->
361bi-directional NAT (combination of inbound and outbound NAT)
362.El
363.Pp
364The following would translate the source (10.1.1.0/24) to the IP address
365specified by
366.Li $pub_ip
367for the packets on the interface
368.Li $ext_if .
369.Pp
370.Dl map $ext_if dynamic 10.1.1.0/24 -> $pub_ip
371.Pp
372Translations are implicitly filtered by limiting the operation to the
373network segments specified, that is, translation would be performed only
374on packets originating from the 10.1.1.0/24 network.
375Explicit filter criteria can be specified using
376.Cm pass Ar criteria ...
377as an additional option of the mapping.
378.Pp
379The dynamic NAT implies network address and port translation (NAPT).
380The port translation can be controlled explicitly.
381For example, the following provides
382.Dq port forwarding ,
383redirecting the public port 9022 to the port 22 of an internal host:
384.Pp
385.Dl map $ext_if dynamic proto tcp 10.1.1.2 port 22 <- $ext_if port 9022
386.Pp
387In the regular dynamic NAT case, it is also possible to disable port
388translation using the
389.Cm no-ports
390flag.
391.Pp
392The translation address can also be dynamic, based on the interface.
393The following would select the IPv4 address(es) currently assigned to the
394interface:
395.Pp
396.Dl map $ext_if dynamic 10.1.1.0/24 -> ifaddrs($ext_if)
397.Pp
398If the dynamic NAT is configured with multiple translation addresses,
399then a custom selection algorithm can be chosen using the
400.Cm algo
401keyword.
402The currently available algorithms for the dynamic translation are:
403.Bl -tag -width "Cm round-robin" -offset indent
404.It Cm ip-hash
405The translation address for a new connection is selected based on a
406hash of the original source and destination addresses.
407This algorithms attempts to keep all connections of particular client
408associated with the same translation address.
409This is the default algorithm.
410.It Cm round-robin
411The translation address for each new connection is selected on a
412round-robin basis.
413.It Cm netmap
414See the description below.
415.El
416.Pp
417The static NAT can also have different address translation algorithms,
418chosen using the
419.Cm algo
420keyword.
421The currently available algorithms are:
422.Bl -tag -width "Cm netmap" -offset indent
423.It Cm netmap
424Network address mapping from one segment to another, leaving the host
425part as-is.
426The new address is computed as following:
427.Pp
428.Dl addr = net-addr | (orig-addr & ~mask)
429.It Cm npt66
430IPv6-to-IPv6 network prefix translation (NPTv6).
431.El
432.Pp
433If no algorithm is specified, then 1:1 address mapping is assumed.
434Currently, the static NAT algorithms do not perform port translation.
435.Ss Application Level Gateways
436Certain application layer protocols are not compatible with NAT and require
437translation outside layers 3 and 4.
438Such translation is performed by packet filter extensions called
439Application Level Gateways (ALGs).
440.Pp
441NPF supports the following ALGs:
442.Bl -tag -width "Cm icmp" -offset indent
443.It Cm icmp
444ICMP ALG.
445Applies to IPv4 and IPv6.
446Allows to find an active connection by looking at the ICMP payload, and to
447perform NAT translation of the ICMP payload.
448Generally, this ALG is necessary to support
449.Xr traceroute 8
450behind the NAT, when using the UDP or TCP probes.
451.El
452.Pp
453The ALGs are built-in.
454If NPF is used as kernel module, then they come as kernel modules too.
455In such case, the ALG kernel modules can be autoloaded through the
456configuration, using the
457.Cm alg
458keyword.
459.Pp
460For example:
461.Pp
462.Dl alg \*qicmp\*q
463.Pp
464Alternatively, the ALG kernel modules can be loaded manually, using
465.Xr modload 8 .
466.Ss Procedures
467A rule procedure is defined as a collection of extension calls (it
468may have none).
469Every extension call has a name and a list of options in the form of
470key-value pairs.
471Depending on the call, the key might represent the argument and the value
472might be optional.
473Available options:
474.Bl -tag -width "Cm log: Ar interface" -offset indent
475.It Cm log : Ar interface
476Log events.
477This requires the
478.Pa npf_ext_log
479kernel module, which would normally get
480auto-loaded by NPF.
481The specified npflog interface would also be auto-created once the
482configuration is loaded.
483The log packets can be written to a file using the
484.Xr npfd 8
485daemon.
486.It Cm normalize : Ar option1 Ns Op Li \&, Ar option2 ...
487Modify packets according to the specified normalization options.
488This requires the
489.Pa npf_ext_normalize kernel
490module, which would normally get auto-loaded by NPF.
491.El
492.Pp
493The available normalization options are:
494.Bl -tag -width "Cm \*qmin-mss\*q Ar value" -offset indent
495.It Cm \*qmax-mss\*q Ar value
496Enforce a maximum value for the Maximum Segment Size (MSS) TCP option.
497Typically, for
498.Dq MSS clamping .
499.It Cm \*qmin-ttl\*q Ar value
500Enforce a minimum value for the IPv4 Time To Live (TTL) parameter.
501.It Cm \*qno-df\*q
502Remove the Don't Fragment (DF) flag from IPv4 packets.
503.It Cm \*qrandom-id\*q
504Randomize the IPv4 ID parameter.
505.El
506.Pp
507For example:
508.Bd -literal -offset indent
509procedure "someproc" {
510	log: npflog0
511	normalize: "random-id", "min-ttl" 64, "max-mss" 1432
512}
513.Ed
514.Pp
515In this case, the procedure calls the logging and normalization modules.
516.Ss Parameter settings
517NPF supports a set of dynamically tunable configuration-wide parameters.
518For example:
519.Bd -literal -offset indent
520set state.tcp.timeout.time_wait 0  # destroy the state immediately
521.Ed
522.Pp
523See
524.Xr npf-params 7
525for the list of parameters and their details.
526.Ss Misc
527Text after a hash
528.Pq Sq #
529character is considered a comment.
530The backslash
531.Pq Sq \e
532character at the end of a line marks a continuation line,
533i.e., the next line is considered an extension of the present line.
534.Sh GRAMMAR
535The following is a non-formal BNF-like definition of the grammar.
536The definition is simplified and is intended to be human readable,
537therefore it does not strictly represent the formal grammar.
538.Bd -literal
539# Syntax of a single line.  Lines can be separated by LF (\\n) or
540# a semicolon.  Comments start with a hash (#) character.
541
542syntax		= var-def | set-param | alg | table-def |
543		  map | group | proc | comment
544
545# Variable definition.  Names can be alpha-numeric, including "_"
546# character.
547
548var-name	= "$" . string
549interface	= interface-name | var-name
550var-def		= var "=" ( var-value | "{" value *[ "," value ] "}" )
551
552# Parameter setting.
553set-param	= "set" param-value
554
555# Application level gateway.  The name should be in double quotes.
556
557alg		= "alg" alg-name
558alg-name	= "icmp"
559
560# Table definition.  Table ID shall be numeric.  Path is in the
561# double quotes.
562
563table-id	= <table-name>
564table-def	= "table" table-id "type" ( "ipset" | "lpm" | "const" )
565		  [ "file" path ]
566
567# Mapping for address translation.
568
569map		= map-common | map-ruleset
570map-common	= "map" interface
571		  ( "static" [ "algo" map-algo ] | "dynamic" )
572		  [ map-flags ] [ proto ]
573		  map-seg ( "->" | "<-" | "<->" ) map-seg
574		  [ "pass" [ proto ] filt-opts ]
575map-ruleset	= "map" "ruleset" group-opts
576
577map-algo	= "ip-hash" | "round-robin" | "netmap" | "npt66"
578map-flags	= "no-ports"
579map-seg		= ( addr-mask | interface ) [ port-opts ]
580
581# Rule procedure definition.  The name should be in the double quotes.
582#
583# Each call can have its own options in a form of key-value pairs.
584# Both key and values may be strings (either in double quotes or not)
585# and numbers, depending on the extension.
586
587proc		= "procedure" proc-name "{" *( proc-call [ new-line ] ) "}"
588proc-opts	= key [ " " val ] [ "," proc-opts ]
589proc-call	= call-name ":" proc-opts new-line
590
591# Group definition and the rule list.
592
593group		= "group" ( "default" | group-opts ) "{" rule-list "}"
594group-opts	= name-string [ "in" | "out" ] [ "on" interface ]
595rule-list	= [ rule new-line ] rule-list
596
597npf-filter	= [ "family" family-opt ] [ proto ] ( "all" | filt-opts )
598static-rule	= ( "block" [ block-opts ] | "pass" )
599		  [ "stateful" | "stateful-all" ]
600		  [ "in" | "out" ] [ "final" ] [ "on" interface ]
601		  ( npf-filter | "pcap-filter" pcap-filter-expr )
602		  [ "apply" proc-name ]
603
604dynamic-ruleset	= "ruleset" group-opts
605rule		= static-rule | dynamic-ruleset
606
607tcp-flag-mask	= tcp-flags
608tcp-flags	= [ "S" ] [ "A" ] [ "F" ] [ "R" ]
609block-opts	= "return-rst" | "return-icmp" | "return"
610
611family-opt	= "inet4" | "inet6"
612proto-opts	= "flags" tcp-flags [ "/" tcp-flag-mask ] |
613		  "icmp-type" type [ "code" icmp-code ]
614proto		= "proto" protocol [ proto-opts ]
615
616filt-opts	= "from" filt-addr [ port-opts ] "to" filt-addr [ port-opts ]
617filt-addr	= [ "!" ] [ interface | addr-mask | table-id | "any" ]
618
619port-opts	= "port" ( port-num | port-from "-" port-to | var-name )
620addr-mask	= addr [ "/" mask ]
621.Ed
622.\" -----
623.Sh FILES
624.Bl -tag -width Pa -compact
625.It Pa /dev/npf
626control device
627.It Pa /etc/npf.conf
628default configuration file
629.It Pa /usr/share/examples/npf
630directory containing further examples
631.El
632.\" -----
633.Sh EXAMPLES
634.Bd -literal
635$ext_if = { inet4(wm0) }
636$int_if = { inet4(wm1) }
637
638table <blocklist> type ipset file "/etc/npf_blocklist"
639table <limited> type lpm
640
641$services_tcp = { http, https, smtp, domain, 6000, 9022 }
642$services_udp = { domain, ntp, 6000 }
643$localnet = { 10.1.1.0/24 }
644
645alg "icmp"
646
647# These NAT rules will dynamically select the interface address(es).
648map $ext_if dynamic 10.1.1.0/24 -> ifaddrs($ext_if)
649map $ext_if dynamic proto tcp 10.1.1.2 port 22 <- ifaddrs($ext_if) port 9022
650
651procedure "log" {
652	# The logging facility can be used together with npfd(8).
653	log: npflog0
654}
655
656group "external" on $ext_if {
657	pass stateful out final all
658
659	block in final from <blocklist>
660	pass stateful in final family inet4 proto tcp to $ext_if \e
661		port ssh apply "log"
662	pass stateful in final proto tcp to $ext_if \e
663		port $services_tcp
664	pass stateful in final proto udp to $ext_if \e
665		port $services_udp
666	pass stateful in final proto tcp to $ext_if \e
667		port 49151-65535  # passive FTP
668	pass stateful in final proto udp to $ext_if \e
669		port 33434-33600  # traceroute
670}
671
672group "internal" on $int_if {
673	block in all
674	block in final from <limited>
675
676	# Ingress filtering as per BCP 38 / RFC 2827.
677	pass in final from $localnet
678	pass out final all
679}
680
681group default {
682	pass final on lo0 all
683	block all
684}
685.Ed
686.\" -----
687.Sh SEE ALSO
688.Xr bpf 4 ,
689.Xr npf 7 ,
690.Xr npf-params 7 ,
691.Xr pcap-filter 7 ,
692.Xr npfctl 8 ,
693.Xr npfd 8
694.Pp
695.Lk http://rmind.github.io/npf/ "NPF documentation website"
696.Sh HISTORY
697NPF first appeared in
698.Nx 6.0 .
699.Sh AUTHORS
700NPF was designed and implemented by
701.An Mindaugas Rasiukevicius .
702