# NetBSD npf.conf
#
# Processing order in NPF is:
# 1. state inspection
# 2. rule inspection (if no state)
# 3. NAT
# 4. rule procedure.

# interface names
$inet_nic = "wm0"
$dmz_nic  = "wm1"
$air_nic  = "wm2"
$prv_nic  = "wm3"
$wprv_nic  = "athn0"
$vpn_nic0 = "tun0"

# interface addresses
#$inet_v4 = inet4(wm0)
$inet_addrs = ifaddrs(wm0)
$dmz_addrs = ifaddrs(wm1)
$air_addrs = ifaddrs(wm2)
$prv_addrs = ifaddrs(wm3)
$wprv_addrs = ifaddrs(athn0)

$prv_net = { 192.168.29.0/24 }
$dmz_net = { 172.29.12.0/24 }
$air_net = { 172.29.13.0/24 }
$wprv_net = { 172.29.14.0/24 }

#==============
# Tables
#==============
# Currently, tables support three data storage types: hash, tree, or cdb.
# Tables of type "hash" and "cdb" can only contain IP addresses.  Also, the
# latter can only be static. Tables of type "tree" can contain subnets
# npfctl: warning - table type "tree" is deprecated and may be deleted in
# the future; please use the "lpm" type instead.
table <blacklist> type lpm file "/etc/ip-blacklist-52k"


#==========================
# NAT
# Packet redirection rules (rdr, nat, and binat) are not
# "last rule to match wins", but rather first matching rule wins.
#==========================
# The following mapping types are available:
#
#   ->      outbound NAT (translation of the source)
#   <-      inbound NAT (translation of the destination)
#   <->     bi-directional NAT (combination of inbound and outbound NAT)
#
# source NAT from prv_net to the address of the external interface.
# Note: if $inet_nic has multiple IP addresses (e.g. IPv6 as well),
# then the translation address has to be specified explicitly.
map $inet_nic dynamic $prv_net -> $inet_addrs
# same for source $dmz_net
map $inet_nic dynamic $dmz_net -> $inet_addrs
# same for source $air_net
map $inet_nic dynamic $air_net -> $inet_addrs
map $inet_nic dynamic $wprv_net -> $inet_addrs

procedure "log" {
    log: npflog0
}

#==========================
# Filtering
#==========================
# NPF requires that all rules be defined within groups.  Groups can be
# thought of as higher level rules which can contain subrules.  Groups may
# have the following options: name, interface, and 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 for packets received on $inet_nic
# Note the filter sees packets before translation
group "external-in" in on $inet_nic {
    block return in final proto tcp from <blacklist> to any port {ssh, smtp, http, https}

    pass in final family inet4 proto icmp      all

    # pass ssh from outside to router
    #!!! logging ssh connections is probably a bad idea. hundreds of doorknob rattlers every day
    pass stateful in final family inet4 proto tcp to $inet_addrs port ssh
#        apply "log"
}

# rules for packets sent on $inet_nic
group "external-out" out on $inet_nic {
    pass out all
}

group "private" on $prv_nic {
    # permit any machine on prv_net to send packets through the firewall
    pass in from $prv_net to any
    pass out all
}

group default {
    pass final on lo0 all
    block return all apply "log"
    # Allow incoming IPv4 pings
    pass in family inet4 proto icmp icmp-type echo all
}
