Vladimir Sedach

Have Emacs - Will Hack

July 31, 2018

IPv6 home LAN with OpenBSD part 2: connecting to the IPv6 Internet

The previous post covered how to set up IPv6 on a LAN. The next step is to connect the LAN to the Internet.

My ISP hands out IPv6 addresses using DHCPv6. I have read that most ISPs do the same. DHCPv6 can be used to hand out either individual addresses (non-temporary address allocation) or whole network prefixes (prefix delegation). My ISP hands out generous /8 prefixes.

The router's LAN-facing interface, vether0, will be assigned an IP address by the DHCPv6 client prefix-delegation request. vether0 will hand out /64 host addresses to hosts on the LAN using IPv6 autoconfiguration.

The most complicated part of the configuration turned out to be the DHCPv6 client settings. I found I had to request a non-temporary address lease for the egress interface, in addition to a lease for my network prefix. The prefix goes to your local network, so the router becomes reachable on both the address leased to the egress interface (em3), and on one or more of the addresses assigned from the prefix to the internal interface (vether0).

OpenBSD 6.3 does not come with a DHCPv6 client, but there are several ones available in ports. I went with wide-dhcpv6.

/etc/dhcp6c.conf
interface em3 {
	send ia-pd 0;
	send ia-na 1;
};

id-assoc pd 0 {
	prefix ::/56 604800 604800;
	prefix-interface vether0 {
		sla-id 1;
		sla-len 8;
	};
};

id-assoc na 1 {
};

sla-len should match the prefix value (they should add up to 64, the number of bits identifying the network part of a global unicast address). The two 604800 (one week in seconds) values are the preferred and valid lifetimes, respectively, that you would like to request for the prefix. Your ISP will probably ignore them. Check the output of dhcp6c to see what actual values to use. sla-id is the actual prefix number that will be assigned on that interface. It can be anything from 0 up to the size of the prefix you are assigned. Of course you get control of the whole prefix and can use the rest of the subnets too.

You can check the configuration and see what the DHCPv6 server hands out to you by running dhcp6c(8) in the foreground with a debug flag: dhcp6c -D -f em3. Note the preferred and valid lifetime values assigned. You don't want to hand out addresses to hosts on your network for longer than the ISP leases you the prefix, because the prefix might change next time you go to renew the lease.

Route setup is done with autoconf and not DHCPv6 (unlike IPv4, where DHCP is responsible for providing the default gateway), so you still need to turn on autoconf for the egress interface to get the default route automatically configured.

/etc/hostname.em3
inet6 autoconf
!/usr/local/sbin/dhcp6c $if

The wide-dhcpv6 package does not come with an rc.d file; sticking it in hostname.X works.

At this point, vether0 should be assigned an address from the leased prefix, and route -n show should show the link-local address of your ISP router as the default route:

Internet6:
Destination                        Gateway                        Flags   Refs      Use   Mtu  Prio Iface
default                            fe80::AAAA:AAAA:AAAA:AAAA%em3  UGS        0       11     -    56 em3

Now you can start handing out IPv6 addresses on your internal network:

/etc/rtadvd.conf
vether0:\
	:pltime=43200:
	:vltime=86400:

Here we specify the auto-configured address valid time to one day, with a preferred lifetime of 12 hours. These lifetimes should be shorter than the lifetimes of the prefix delegation from DHCPv6.

/etc/rc.conf.local
rtadvd_flags=vether0

Note that rtadvd(8) will be replaced with rad(8) in OpenBSD 6.4.

Don't forget to make sure pf NAT is applied only to IPv4 (inet) traffic:

/etc/pf.conf
pass out on em3 inet from vether0:network to any nat-to (em3)

Run pfctl -s rules to look for any other rules that are being inadvertently applied to IPv6 traffic, and to see which rules are not and should be.

On the client side:

/etc/hostname.bge0
inet6 autoconf

route -n show should show the link-local address of vether0 as the default route:

Internet6:
Destination                        Gateway                        Flags   Refs      Use   Mtu  Prio Iface
default                            fe80::BBBB:BBBB:BBBB:BBBB%bge0 UGS        0       18     -    56 bge0

Hopefully now you can view this site via IPv6. I recommend installing the SixOrNot Firefox extension and configuring it to display which protocol you are using to load a website.