In this post I will share how I configured my OpenBSD router for IPv6 with DHCP-PD.
Introduction
My ISP provide IPv6 with a static DHCP-PD setup.
This means the ISP router delegate IPv6 prefixes on demand to internal routers.
It took me some time to find the good combinaison of configuration on OpenBSD to get everything working.
Overview
IPv6 is unlike IPv4 in the sense that routing is mostly auto-configured using the "IPv6 Neighbor Discovery Protocol".
This is an ICMP6 based protocol. I won't explain here how it works, you can find that on the net, but I'll just explain what is required for it to work in this particular setup.
What is important, is that NDP doesn't provide a specific IP to a device, instead the device pick the network prefix and happen the address it sees fit behind (can be mac address or something else).
In many environment, this is not desirable and DHCP is used to attribue an additional IP (this is different from IPv4) that has been selected for the device.
I won't linger more and just share the configuration.
Configuration
wan
is connected to the ISP router and lan
to my local network.
Interfaces
/etc/hostname.lan
In this file, no inet6 configuration is required, dhcp will configure it.
/etc/hostname.wan
In this file, just add a simple ipv6 auto configuration entry.
inet6 autoconf
PF
/etc/pf.conf
It requires a few important rules
# IPv6 REQUIRES ICMP to work, yes, some icmp packet type are not required
# but it is simpler to just allow it
# If you want to be more restrictive, start with that and add exception
# later on
pass on any inet6 proto icmp6 all
# Allow the ISP router to send us DHCP packets
pass in on $wan inet6 proto udp from fe80::/10 port dhcpv6-server \
to fe80::/10 port dhcpv6-client no state
DHCPCD
Dhcpcd will be the dhcpv6 client:
Install the package:
pkg_add dhcpcd
Modify the start script:
/etc/rc.d/dhcpcd
Changes the flags:
daemon_flags="-Mq -C resolv.conf -c /etc/dhcpcd_up.sh"
This will prevent resolv.conf
from being touched and call our own up hook:
/etc/dhcpcd_up.sh
In this file, you can put the following:
route sourceaddr -inet6 <the static dhcp address your router gets>
This will force the router to use the DHCP given address (which, while being DHCP is actually static) for outbound packets.
Of course you also need to configure /etc/resolv.conf
manually
And finally:
/etc/dhcpcd.conf
noipv4
noipv4ll
noipv6rs
allowinterfaces lan wan
interface wan
ia_na 1
ia_pd 2 lan/0
This will request a prefix from the server and allocate it to the lan interface.
At this stage, the wan interface should be fully configured. The lan interface should have an IP but not act as a router yet.
You notice there is noipv6rs
in the configuration as we use the kernel
autoconfiguration above (in /etc/hostname.wan
). It is important to do it this
way otherwise dhcpcd
will segfault.
DHCPD v6
Now we need to run a dhcpd 6 server and router advertisement on the lan interface.
For this, we install the isc-dhcp-server package.
pkg_add isc-dhcp-server
And configure it:
/etc/rc.d/isc_dhcpd6
(create it)
#!/bin/ksh
daemon="/usr/local/sbin/dhcpd"
daemon_flags="-6 -cf /etc/dhcpd6.conf -user _isc-dhcp -group _isc-dhcp"
. /etc/rc.d/rc.subr
rc_reload=NO
rc_pre() {
mkdir -p /var/db/dhcp/
touch /var/db/dhcp/dhcpd6.leases
}
rc_cmd $1
/etc/dhcp6.conf
(create it)
# IPv6 address valid lifetime
# (at the end the address is no longer usable by the client)
# (set to 30 days, the usual IPv6 default)
default-lease-time 2592000;
# IPv6 address preferred lifetime
# (at the end the address is deprecated, i.e., the client should use
# other addresses for new connections)
# (set to 7 days, the usual IPv6 default)
preferred-lifetime 604800;
dhcpv6-lease-file-name "/var/db/dhcp/dhcpd6.leases";
# T1, the delay before Renew
# (default is 1/2 preferred lifetime)
# (set to 1 hour)
option dhcp-renewal-time 3600;
# T2, the delay before Rebind (if Renews failed)
# (default is 3/4 preferred lifetime)
# (set to 2 hours)
option dhcp-rebinding-time 7200;
# Enable RFC 5007 support (same than for DHCPv4)
allow leasequery;
# Global definitions for name server address(es) and domain search list
option dhcp6.name-servers <dns ipv6>;
option dhcp6.domain-search "example.com", "example2.com";
# Set preference to 255 (maximum) in order to avoid waiting for
# additional servers when there is only one
option dhcp6.preference 255;
# Server side command to enable rapid-commit (2 packet exchange)
option dhcp6.rapid-commit;
# The delay before information-request refresh
# (minimum is 10 minutes, maximum one day, default is to not refresh)
# (set to 6 hours)
option dhcp6.info-refresh-time 21600;
subnet6 <delegated prefix>::/64 {
range6 <delegated prefix>::1000 <delegated prefix>::ffff;
}
RAD
Finally, enable the router advertisement daemon:
/etc/rad.conf
managed address configuration yes
other configuration yes
dns {
nameserver {
<dns ip>
}
}
interface lan
NOTE: The order of the configuration in this file is important. If you do
not put managed
first, the router advertisement packets will not have the
managed flag set, which in turn will not trigger dhcpv6 requests from clients.
Finish notes
Of course, don't forget to enable all those daemon with rcctl
and start them.
Also disable dhcpleased
and any other dhcp client/server you might have
running. If you want to have ipv4 dhcp, also use isc-dhcp with an ipv4
configuration, but other dhcp server/client might break the ipv6 configuration.