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