NPF.CONF(5) | NetBSD File Formats Manual | NPF.CONF(5) |
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 encountering 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 connection are tracked. Packets in backwards stream, after having been confirmed 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.
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.
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".
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 | "normalize" "(" 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 ] [ "inet" | "inet6" ] [ "proto" <protocol> ] ( "all" | filt-opts [ "flags" <tcp_flags> > ) [ "keep state" ] [ "apply" rproc } block-opts = [ "return-rst" | "return-icmp" | "return" ] filt-opts = [ "from" ( iface | def | <addr/mask> | <tid> ) port-opts ] [ "to" ( iface | def | <addr/mask> | <tid> ) port-opts ] port-opts = [ "port" ( <port-num> | <port-from> ":" <port-to> | def ) ] proto-opts = [ "flags" <tcp_flags> | "icmp-type" <type> "code" <code> ]
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" { normalize (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 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 }
March 22, 2011 | NetBSD 5.99 |