# $NetBSD: host-npf.conf,v 1.2.4.4 2012/12/15 23:31:07 riz Exp $
#
# this is an example of NPF rules for a host (i.e., not routing) with
# two network interfaces, wired and wifi
#
# it does both IPv4 and IPv6 and allows for DHCP in v4 and SLAAC in v6
# it also does IPSEC on the wifi
#

$wired_if = "wm0"
$wired_v4 = { inet4(wm0) }
$wired_v6 = { inet6(wm0) }

$wifi_if = "iwn0"
$wifi_v4 = { inet4(iwn0) }
$wifi_v6 = { inet6(iwn0) }

$dhcpserver = { 198.51.100.1 }

# sample udp service
$services_udp = { ntp }

# sample mixed service
$backupsrv_v4 = { 198.51.100.11 }
$backupsrv_v6 = { 2001:0DB8:404::11 }
$backup_port = { amanda }

# watching a tcpdump of npflog0, when it only logs blocks,
# can be very helpful for building the rules you actually need
procedure "log" {
     log: npflog0
}

group (name "wired", interface $wired_if) {

	# not being picky about our own address here
	pass in  final family inet6 proto ipv6-icmp all
	pass out final family inet6 proto ipv6-icmp all
	pass in  final family inet  proto icmp      all

	pass in  final family inet proto tcp \
		from $dhcpserver port bootps to $wired_v4 port bootpc
	pass in  final family inet proto udp \
		from $dhcpserver port bootps to $wired_v4 port bootpc

	pass in final family inet6 proto tcp to $wired_v6 port ssh

	pass in final family inet  proto tcp flags S/SA \
		from $backupsrv_v4 to $wired_v4 port $backup_port 
	pass in final family inet  proto udp \
		from $backupsrv_v4 to $wired_v4 port $backup_port
	pass in final family inet6 proto tcp flags S/SA \
		from $backupsrv_v6 to $wired_v6 port $backup_port 
	pass in final family inet6 proto udp \
		from $backupsrv_v6 to $wired_v6 port $backup_port

	pass stateful in final family inet6 proto udp to $wired_v6 \
		port $services_udp
	pass stateful in final family inet  proto udp to $wired_v6 \
		port $services_udp

	# only SYN packets need to generate state
	pass stateful out final family inet6 proto tcp flags S/SA \
		from $wired_v6
	pass stateful out final family inet  proto tcp flags S/SA \
		from $wired_v4
	# pass the other tcp packets without generating extra state
	pass out final family inet6 proto tcp from $wired_v6
	pass out final family inet  proto tcp from $wired_v4

	# all other types of traffic, generate state per packet
	pass stateful out final family inet6 from $wired_v6
	pass stateful out final family inet  from $wired_v4

}

group (name "wifi", interface $wifi_if) {
	# linklocal
	pass in  final family inet6 proto ipv6-icmp  to fe80::/10
	pass out final family inet6 proto ipv6-icmp from fe80::/10

	# administrative multicasts
	pass in  final family inet6 proto ipv6-icmp  to ff00::/10
	pass out final family inet6 proto ipv6-icmp from ff00::/10

	pass in  final family inet6 proto ipv6-icmp to $wifi_v6
	pass in  final family inet  proto icmp      to $wifi_v6

	pass in  final family inet proto tcp \
		from any port bootps to $wifi_v4 port bootpc
	pass in  final family inet proto udp \
		from any port bootps to $wifi_v4 port bootpc

        pass in final family inet6 proto tcp flags S/SA to $wifi_v6 port ssh 

        pass in final family inet6 proto udp to $wifi_v6 port $services_udp
        pass in final family inet  proto udp to $wifi_v4 port $services_udp

	# IPSEC
	pass in final family inet6 proto udp to $wifi_v6 port isakmp
	pass in final family inet  proto udp to $wifi_v4 port isakmp
	pass in family inet6 proto esp all
	pass in family inet  proto esp all

	# only SYN packets need to generate state
        pass stateful out final family inet6 proto tcp flags S/SA \
		from $wifi_v6
        pass stateful out final family inet  proto tcp flags S/SA \
		from $wifi_v4
	# pass the other tcp packets without generating extra state
        pass out final family inet6 proto tcp from $wifi_v6
        pass out final family inet  proto tcp from $wifi_v4

	# all other types of traffic, generate state per packet
        pass stateful out final family inet6 from $wifi_v6
        pass stateful out final family inet  from $wifi_v4
}

group (default) {
	pass final on lo0 all
	block all apply "log"
}
