Concepts
IPv6 is an entirely new version of the Internet Protocol; it is not backwards compatible with IPv4
A 128-bit address space means no more NAT; every device can have a publically routable address
Each network interface has an address from the fe80::/10
subnet which is used for communication on the local link
Your ISP will delegate you a prefix – a big subnet – of public IP addresses through DHCPv6 that you can use in your network
Hosts can configure themselves with IPv6 addresses automatically from a router through a process called SLAAC without the need for a stateful DHCPv6 server on the network
The Neighbor Discovery Protocol performs the rough equivalent of ARP, as well as Router Discovery for SLAAC. This important protocol uses ICMPv6 packets (and therefore these packets must not be blocked by the firewall)
Requirements
RFC 7084, Basic Requirements for IPv6 Customer Edge Routers, specifies how an IPv6 router should function in a residential environment. With the OpenBSD router guide as the starting point, the changes required are:
On the external interface: act as a DHCPv6 client to receive a Prefix Delegation
On the internal interfaces: serve Router Advertisements for local hosts, which is necessary for SLAAC
Adjust the firewall ruleset to allow the Neighbor Discovery Protocol and DHCPv6 to function
Firewall
First enable IPv6 forwarding to let the host act as a router.
Then update the PF ruleset.
- Add the IPv6 non-routable ranges to the “martians” table
- Do not block link-local addresses (
fe80::/10
) since Neighbor Discovery and DHCPv6 require link-local communication - Remove the
inet
parameter on the main pass rules to allow both IPv4 and IPv6 traffic - Allow Neighbor and Router Discovery on the external interface
- The relevant ICMPv6 types are Router Solicitation, Router Advertisement, Neighbor Solicitation and Neighbor Advertisement (types 133–136). We should never see an incoming Router Solicitation from the ISP; the other three types should be allowed in.
- Allow DHCPv6 traffic from the ISP for prefix delegation
- The DHCPv6 request is sent to a multicast address and the ISP router replies with its own link-local address as the source address, so state matching doesn't catch it. An explicit pass rule is required for the reply.
ICMP
You can allow ping for diagnostics.
For everything else, read RFC 4890, Recommendations for Filtering ICMPv6 Messages in Firewalls, and decide if any other packet types have a place in your network.
Other Considerations
If you have multiple subnets, assign Unique Local Addresses (ULAs). This maintains communication between the subnets even when the externally allocated global prefix changes or becomes unavailable.
For opening ports, if your prefix delegation doesn’t change often you can just pass through the relevant traffic:
pass in on egress inet6 proto tcp to 2001:db8::2 port { 80 443 }
Otherwise do the same kind of port forwarding as for the IPv4 example with a rdr-to
to a static ULA
The antispoof
rules should be replaced by a strict uRPF check:
block in log quick from urpf-failed
This blocks any packet that comes in on an interface other that that which holds the route back to the packet’s source address.
The match in all scrub
rule is unnecessary – unless a host on your network generates fragmented packets with the “dont‑fragment” flag set
DHCPv6
The OpenBSD base system does not have a DHCPv6 client at present.
Install the dhcpcd
package for prefix delegation to obtain a chunk of public addresses for the local network.
Configure dhcpcd
to request a prefix from the ISP and assign prefixes to all the internal interfaces.
See dhcpcd.conf(5) and the pkg-readme for details. RFC 8415 explains the jargon.
SLAAC
The rad
daemon serves Router Advertisements. Hosts on the local network use these to assign themselves IPv6 addresses, which means that you often don’t need to run a DHCPv6 server.
Other nodes on your network (such as a wireless access point in bridge mode) might also be sending router advertisements. Check the output of ndp -an
for nodes with the R
(Router) flag set. Any misbehaving nodes might need to have forwarding
sysctl’s turned off to stop them generating unnecessary traffic.
DNS
The unbound
DNS resolver will function well with the same configuration as shown in the FAQ example. It will run over IPv4, but that doesn’t matter – the DNS responses will have the appropriate AAAA
records which contain IPv6 addresses.
There are a few knobs you can tweak – unrelated to IPv6 – that can improve your network.
Protection from DNS Rebinding
DNS rebinding attacks subvert the same-origin policy and convert browsers into open network proxies. These attacks can circumvent firewalls to access internal documents and services […]
Networks can be protected against firewall circumvention by forbidding external host names from resolving to internal IP addresses.
Use the private-address
server option in unbound.conf
to protect against these attacks. Specify all possible subnets which can be used for internal networks. Any public internet domain names which resolve to the IPv4 or IPv6 subnets specified in this option are removed from the DNS response.
A future version of unbound
may have this on by default.
DNS Filtering (Blocking Ads)
Choose which type of hosts you wish to block, such as from one of the lists maintained by StevenBlack.
Automate fetching your chosen blocklist, and converting it into a form that is suitable for unbound
. Adapt this dnsblock.sh script and let it run regularly (such as by calling it from /etc/weekly.local
). Use the include
server option to insert the blocklist rules in the main unbound config file.
Done
Reboot and enjoy.