NPF.CONF(5)               NetBSD File Formats Manual               NPF.CONF(5)

NAME
     npf.conf -- NPF packet filter configuration file

DESCRIPTION
     npf.conf is the default configuration file for NPF packet filter.  It can
     contain definitions, grouped rules, rule procedures, and tables.

   Definitions
     Definitions are general purpose keywords which can be used in the ruleset
     to make it more flexible and easier to manage.  Most commonly, defini-
     tions are used to define one of the following: IP addresses, networks,
     ports, or interfaces.  Definitions can contain multiple elements.

   Groups
     Having one huge ruleset for all interfaces or directions might be ineffi-
     cient; therefore, NPF requires that all rules be defined within groups.
     Groups can be thought of as higher level rules which have subrules.  The
     main properties of a group are its interface and traffic direction.
     Packets matching group criteria are passed to the ruleset of that group.
     If a packet does not match any group, it is passed to the default group.
     The default group must always be defined.

   Rules
     Rules, which are the main part of NPF configuration, describe the crite-
     ria used to inspect and make decisions about packets.  Currently, NPF
     supports filtering on the following criteria: interface, traffic direc-
     tion, protocol, IPv4 address or network, TCP/UDP port or range, TCP
     flags, and ICMP type/code.  Supported actions are blocking or passing the
     packet.

     Each rule has a priority, which is set according to its order in the
     ruleset.  Rules defined first are accordingly inspected first.  All rules
     in the group are inspected sequentially, and the last matching dictates
     the action to be taken.  Rules, however, may be explicitly marked as
     final (that is, "quick").  In such cases, processing stops after encoun-
     tering the first matching rule marked as final.  If there is no matching
     rule in the custom group, then rules in the default group will be
     inspected.

     Stateful filtering is supported using the "keep state" keyword.  In such
     cases, state (a session) is created and any further packets of the con-
     nection are tracked.  Packets in backwards stream, after having been con-
     firmed to belong to the same connection, are passed without ruleset
     inspection.  Rules may have associated rule procedures (described in a
     later section), which are applied for all packets of a connection.

     Definitions (prefixed with "$") and tables (specified by an ID within
     "<>" marks) can be used in the filter options of rules.

   Rule procedures and normalisation
     Rule procedures are provided to perform packet transformations and vari-
     ous additional procedures on the packets.  It should be noted that rule
     procedures are applied for the connections, that is, both for packets
     which match the rule and for further packets of the connection, which are
     passed without ruleset inspection.  Currently, two facilities are sup-
     ported: traffic normalisation and packet logging.  Packet normalisation
     has the following functionality: IP ID randomisation, IP_DF flag cleans-
     ing, TCP minimum TTL enforcement, and maximum MSS enforcement ("MSS
     clamping").  If a matching rule is going to drop the packet, normalisa-
     tion functions are not performed.  Packet logging is performed both in
     packet passing and blocking cases.  Note that the logging interface has
     to be created manually, using ifconfig(8) routine, for example:

     ifconfig npflog0 create

   Network address translation
     Rules for address translation can be added.  Translation is performed on
     the specified interface, assigning the specified address of said inter-
     face.  There are three types of translation: Network Address Port Trans-
     lation (NAPT) - a regular NAT, also known as "outbound NAT"; Port for-
     warding (redirection) - also known as "inbound NAT"; Bi-directional NAT -
     a combination of inbound and outbound NAT.

     Minimal filtering criteria on local network and destination are provided.
     Note that address translation implies routing, therefore IP forwarding is
     required to be enabled: net.inet.ip.forwarding = 1.  See sysctl(7) for
     more details.

   Tables
     Certain configurations might use very large sets of IP addresses or
     change sets frequently.  Storing large IP sets in the configuration file
     or performing frequent reloads can have a significant performance cost.

     In order to achieve high performance, NPF has tables.  NPF tables provide
     separate storage designed for large IP sets and frequent updates without
     reloading the entire ruleset.  Tables can be managed dynamically or
     loaded from a separate file, which is useful for large static tables.
     There are two types of storage: "tree" (red-black tree is used) and
     "hash".

GRAMMAR
     line            = ( def | table | nat | group | rproc )

     def             = ( <name> "=" "{ a, b, ... }" | "<text>" | "$<interface>" )
     iface           = ( <interface> | def )

     table           = "table" <tid> "type" ( "hash" | "tree" )
                       ( "dynamic" | "file" <path> )

     nat             = "nat" iface filt-opts "->" <addr>
     binat           = "binat" iface filt-opts "->" <addr>
     rdr             = "rdr" iface filt-opts "->" <addr> port-opts

     rproc           = "procedure" <name> procs
     procs           = "{" op1 <newline>, op2 <newline>, ... "}"
     op              = ( "log" iface | "normalise" "(" norm-opt1 "," norm-opt2 ... ")" )
     norm-opt        = [ "random-id" | "min-ttl" <num> | "max-mss" <num> | "no-df" ]

     group           = "group" "(" ( "default" | group-opts ) ")" ruleset
     group-opts      = "interface" iface "," [ "in" | "out" ]

     ruleset         = "{" rule1 <newline>, rule2 <newline>, ... "}"

     rule            = ( "block" block-opts | "pass" ) [ "in" | out" ] [ "quick" ]
                       [ "on" iface ] [ "family" fam-opt ] [ "proto" <protocol> ]
                       ( "all" | filt-opts ) [ "keep state" ] [ "apply" rproc ] }

     fam-opt         = [ "inet" | "inet6" ]
     block-opts      = [ "return-rst" | "return-icmp" | "return" ]
     filt-addr       = iface | def | <addr/mask> | <tid>
     port-opts       = [ "port" ( <port-num> | <port-from> "-" <port-to> | def ) ]
     filt-opts       = [ "from" filt-addr [ port-opts ] ] [ "to" filt-addr [ port-opts ] ]
     proto-opts      = [ "flags" <tcp_flags> | "icmp-type" <type> "code" <code> ]

FILES
     /dev/npf       control device
     /etc/npf.conf  default configuration file

EXAMPLES
     $ext_if = "wm0"
     $int_if = "wm1"

     $services_tcp = { http, https, smtp, domain, 6000 }
     $services_udp = { domain, ntp, 6000 }

     table <1> type hash file "/etc/npf_blacklist"
     table <2> type tree dynamic

     nat $ext_if from 192.168.0.0/24 to any -> $ext_if

     procedure "log" {
             log: npflog0
     }

     procedure "rid" {
             normalise: "random-id"
     }

     group (name "external", interface $ext_if) {
             block in quick from <1>
             pass out quick from $ext_if keep state apply "rid"

             pass in quick family inet proto tcp to $ext_if port ssh apply "log"
             pass in quick proto tcp to $ext_if port $services_tcp
             pass in quick proto udp to $ext_if port $services_udp
             pass in quick proto tcp to $ext_if port 49151-65535     # Passive FTP
             pass in quick proto udp to $ext_if port 33434-33600     # Traceroute
     }

     group (name "internal", interface $int_if) {
             block in all
             pass in quick from <2>
             pass out quick all
     }

     group (default) {
             block all
     }

SEE ALSO
     npfctl(8), npf_ncode(9)

HISTORY
     NPF first appeared in NetBSD 6.0.

NetBSD 5.0                     February 5, 2012                     NetBSD 5.0