IPv4 + IPv6 Router and PF Firewall

This article details how to configure a IPv4/IPv6 dual-stack Internet gateway router and secure it with PF.

The configuration requires that your Internet Service Provider already supports and is providing you with IPv6 Internet connectivity and addresses via Router Advertisement messages.

  • The system will be configured to work as a CPE (Customer Premises Equipment) which needs RA messages from the upstream network for network configuration and acts as a router for the LAN simultaneously. For more information about this kind of configuration, see RFC 6204.
  • The rc.conf statement ipv6_cpe_wanif="iface" causes sysctl variables net.inet6.ip6.rfc6204w3 and net.inet6.ip6.no_radr to be set to 1. This configures the specified "iface" to accept RA messages and the default router information in them, and configures the other interfaces to ignore default router information in any received RA messages, even if the ACCEPT_RTADV flag is set on those interfaces. See rc.conf(5) for more information.
  • Request from your ISP an IPv6 prefix delegation. This will be a /64 or /56 block of Internet routable IPv6 addresses you can assign to your LAN clients. Assign one of these addresses to the router's internal interface: Prefix Delegation IPv6 address


Configure System Startup

NOTE: The System Startup section is not 100% complete at the moment as it lacks the precise configuration to request a prefix delegation via DHCP. This can be accomplished by installing the isc-dhcp client (contained in port net/dual-dhclient) and correctly configuring the DHCP request sent to your ISP to also assign and reply with a /64 or /56 prefix delegation. The current information in this section can be adapted as needed and the firewall section that follows is 100% complete.

Configure the network interfaces, enable routing, and enable PF firewall by adding the following to /etc/rc.conf:

ifconfig_re1="inet netmask"
ifconfig_re1_ipv6="inet6 Prefix Delegation IPv6 address prefixlen 64"

# PF


Configure the Firewall Rules

Edit /etc/pf.conf

#### Macros ####
ext_if = re0
int_if = re1

# ICMP Types
icmp_types = "{ echorep, unreach, squench, echoreq, timex, paramprob }"
icmp6_types = "{ unreach, toobig, timex, paramprob, echoreq, echorep, neighbradv, neighbrsol, routeradv, routersol }"

# Private Networks
priv_nets = "{,,,, }"

#### Options ####
set block-policy drop
set skip on lo0

# Scrub
scrub in on $ext_if

nat on $ext_if from to any -> ($ext_if)
### Block ### block log all # Antispoof antispoof log for $ext_if
block in log on $ext_if from $priv_nets
block in log from { urpf-failed, no-route } ### Allow ### # Allow all traffic on internal interface pass quick on $int_if # Allow all traffic out on external interface(s) pass out on $ext_if # Allow IPv6 fragments pass inet6 proto ipv6-frag # ICMP pass in on $ext_if inet proto icmp all icmp-type $icmp_types pass in on $ext_if inet6 proto icmp6 all icmp6-type $icmp6_types allow-opts ### Inbound Services ### # pass in on $ext_if proto tcp to port http


When both IPv4 and IPv6 connectivity are confirmed working you can begin assigning IPv6 addresses from your assigned prefix delegation routed /64 block.
rtadvd(8) - router advertisement daemon is a quick and easy way to automatically configure IPv6 addresses for your LAN systems and devices.

To install and configure a dual-stack DHCP server solution for stateful address assignments, refer to: ISC DHCP IPv4 & IPv6 Server on a Dual-Stack Network

To install the dual-stack dhcp client port net/dual-dhclient, refer to: IPv4 and IPv6 Client Addresses via DHCP on a Dual-Stack Network