Telekom VDSL via OpenBSD
Last Updated:
Self-Hosting is on everyone’s1 lips. If you feel included, you might have already thought about replacing your commercial provider-supplied router with your personal server. In my case I am running a OpenBSD machine. Why OpenBSD? Mainly out of curiosity. I am a long-time Linux user and always wanted to learn more about the BSD systems. OpenBSD was the choice as it’s main priority is security which is a good fit for a network router. It’s also well-known for simplicity and verbose documentation (manpages).
This blog post shows how to configure a dual-stack WAN interface (i.e., IPv4 and IPv6 connectivity) via PPPoE in OpenBSD. Of course, our OpenBSD box should act as a router for our LAN interface which connects an arbitrary number of internal clients. We follow a three step procedure:
- Configure the WAN interface via PPPoE
- Configure a IPv6 DHCP Prefix Delegation (IPv6 PD) for the LAN interfaces.
- Enable the Router Advertisement Daemon (RAD) to propagate delegated IPv6 prefixes into the internal network clients.
Hardware Requirements
OpenBSD is a very lightweight operating system, hence, you can can use relatively cheap and low-power machines. I personally use a Protectli FW4B. Power consumption varies around 6–8 watts which is a good bang for the buck.
Furthermore, we need a modem to dial in via PPPoE. I am using a Draytek Vigor 165 but there are no restrictions to other models, as long as it meets your ISP’s requirements.
PPPoE Connection
The following instructions are for Deutsche Telekom AG but the overall concept can be adopted to other providers as long as connection is established via PPPoE.
Note: I assume that the modem is connected to the OpenBSD box via interface
em0
.
$ cat /etc/hostname.em0
up
As T-VDSL requires VLAN ID 7 to dial in, we first create a corresponding VLAN interface.
$ cat /etc/hostname.vlan7
vnetid 7 parent em0 up
The PPPoE connection is then configured as follows. You need to edit according to your personal login data, following the pattern of Anschlusskennung, T-Online-Nr and Password, without brackets. Be careful here, as otherwise your connection won’t work.
$ cat /etc/hostname.pppoe0
inet 0.0.0.0 255.255.255.255 NONE \
pppoedev vlan7 authproto pap \
authname '[Anschlusskennung][T-Online-Nr][0001]@t-online.de' \
authkey '[Password]' \
up
dest 0.0.0.1
inet6 eui64
!/sbin/route add default -ifp pppoe0 0.0.0.1
!/sbin/route add -inet6 default -ifp pppoe0 fe80::%pppoe0
inet6 autoconf
The addresses 0.0.0.0
and 0.0.0.1
serve as placeholder addresses for
dynamic address configuration, i.e. they will be replaced with addresses
suggested by the ISP. Further note that we configure default routes both for
IPv4 and IPv6 to route external traffic via pppoe0
.
The inet6 eui64
and inet6 autoconf
statements are necessary to obtain a
IPv6 address on our WAN interface via DHCP prefix delegation, as discussed
below.
You might now either restart your machine or simply run the following to create all network interface.
# sh /etc/netstart
After successful execution you need to be a little bit patient and wait for establishment of the PPPoE connection. A successful connection looks as follows:
$ ifconfig pppoe0
pppoe0: flags=48851<UP,POINTOPOINT,RUNNING,SIMPLEX,MULTICAST,AUTOCONF6TEMP> mtu 1492
index 10 priority 0 llprio 3
dev: vlan7 state: session
sid: 0x63 PADI retries: 5 PADR retries: 0 time: 1d 11:15:17
sppp: phase network authproto pap
dns: 217.237.xxx.xxx 217.237.xxx.xxx
groups: pppoe egress
status: active
inet6 fe80::2e0:67ff:abcd:ef12%pppoe0 --> prefixlen 64 scopeid 0xa
inet 217.238.xxx.xxx --> 62.155.242.144 netmask 0xffffffff
Note that I anonymized my personal IP addresses. You can also see the DNS
servers of your provider. If resolvd
is running which should be enabled by
default these DNS servers should be automatically added to /etc/resolv.conf
.
You can now connect to any publicly reachable client on the internet, however
only using IPv4.
IPv6 DHCP Prefix Delegation
We briefly discussed IPv6 while configuring the PPPoE interface above. Now we add IPv6 connectivity to our OpenBSD box and internal network.
While OpenBSD provides IPv6 connectivity via SLAAC already in the base system, it does not provide a DHCPv6 client which understands prefix delegation. A popular choice for is DHCPCD.
# pkg_add dhcpcd
Now we need to configure etc/dhcpcd.conf
, which is additionally annotated to
understand necessary options
# Use the same DUID + IAID as set in DHCPv6 for DHCPv4 ClientID as per RFC4361.
duid
# Persist interface configuration when dhcpcd exits.
persistent
# Rapid commit support.
# Safe to enable by default because it requires the equivalent option set
# on the server to actually work.
option rapid_commit
# A ServerID is required by RFC2131.
require dhcp_server_identifier
# Generate Stable Private IPv6 Addresses based from the DUID
slaac private
# only IPv6
waitip 6
ipv6only
noipv6rs
# Only touch interfaces pppoe0 and em1
allowinterfaces pppoe0 em1
interface pppoe0
ipv6rs # request delegated IPv6 prefix from ISP via NDP RS
iaid 1
ia_pd 2 em1/0/64 # request prefix for em1 (LAN network)
The noipv6rs
is really import as we use the kernel auto configuration in the
pppoe0 interface.
Start dhcpcd
using this configuration:
# rcctl enable dhcpcd; rcctl start dhcpcd;
After some time we obtain a globally unique IPv6 address on our PPPoE
interface, as well as on our LAN interface. We can check this either via
ifconfig
, or by looking into our system logs (actual addresses are anonymized).
# tail -f /var/log/daemon
Mar 19 11:22:58 openbsd dhcpcd[90804]: pppoe0: soliciting an IPv6 router
Mar 19 11:22:58 openbsd dhcpcd[90804]: pppoe0: Router Advertisement from fe80::231:46ff:xxxx:xxxx
Mar 19 11:22:58 openbsd dhcpcd[90804]: pppoe0: adding address 2003:ec:97ff:2axx:xxxx:xxxx:xxxx:xxxx/64
Mar 19 11:22:58 openbsd dhcpcd[90804]: pppoe0: adding route to 2003:ec:97ff:2axx::/64
Mar 19 11:22:58 openbsd dhcpcd[90804]: pppoe0: adding default route via fe80::231:46ff:xxxx:xxxx
Mar 19 11:23:00 openbsd dhcpcd[90804]: pppoe0: REPLY6 received from fe80::231:46ff:xxxx:xxxx
Mar 19 11:23:00 openbsd dhcpcd[90804]: pppoe0: delegated prefix 2003:ec:974a:1230::/56
We can see that our dhcpcd
daemon received a /56
IPv6 subnet via prefix
delegation and propagated that to our LAN interface. You can now ping any
publicly reachable IPv6 client on the internet.
IPv6 Prefix Delegation in the OpenBSD base system
With the OpenBSD 7.6 release, dhcp6leased was introduced as a daemon for IPv6 prefix delegation. I refer to a detailed blog post from the OpenBSD developer to learn more about the implementation details.
It again shows why I like OpenBSD. It’s easy to configure and comes with sane defaults to hide complex implementation details.
Below is the configuration snippet
# cat /etc/dhcp6leased.conf
request rapid commit
request prefix delegation on pppoe0 for {
em1
}
I switched from dhcpcd
on my machine to dhcp6leased
.
Router Advertisement Daemon
The last step is to propagate our IPv6 prefix to the clients connected on our internal network. OpenBSD base comes with a router advertisement daemon (RAD) which provides necessary functionality.
As always, let’s first configure the daemon: /etc/rad.conf
$ cat /etc/rad.conf
# Use the interface IPv6 address to discover the prefix to announce.
interface em1
That’s all we need. The rad
daemon now listens for ICMP6 router solicitations
on the LAN interface em1
to announce our delegated IPv6 prefix. The clients
generate their own globally reachable IPv6 addresses using
SLAAC.
Do not forget to enable and start the daemon using rcctl
.
In my case I can see now that my laptop, which is connected via WiFi to
the OpenBSD box em1
interface, receives the delegated /64
prefix and generates an IPv6 address via
SLAAC. On the OpenBSD box, we can see the necessary network traffic via
tcpdump
.
# tcpdump -n -e -v -ttt -i em1 icmp6
Mar 19 13:14:09.918688 70:56:81:b2:34:f3 33:33:00:00:00:02 86dd 70: fe80::1c63:2501:xxxx:xxxx > ff02::2: icmp6: router solicitation (src lladdr: 70:56:81:b2:34:f3) [icmp6 cksum ok] [flowlabel 0x69a4e] (len 16, hlim 255)
Mar 19 13:14:09.919372 00:e0:67:xx:xx:xx 70:56:81:b2:34:f3 86dd 102: fe80::2e0:67ff:fe1e:15c9 > fe80::1c63:2501:xxxx:xxxx: icmp6: router advertisement(chlim=0, pref=medium, router_ltime=1800, reachable_time=0, retrans_time=0)(prefix info: LA valid_ltime=2592000, preferred_ltime=604800, prefix=2003:ec:972a:xxxx::/64) [icmp6 cksum ok] (len 48, hlim 255)
The laptop sends an IPv6 router solicitation via multicast to our OpenBSD
router. The router then announces a /64
IPv6 subnet, which the laptop uses to
generate its globally unique IPv6 addresses via SLAAC.
Final Notes and Conclusion
It is clear that this post alone does not suffice to obtain a fully functional dual-stack OpenBSD router. For example, I did not mention anything about firewall rules for OpenBSD PF, or about IPv4 DHCP configuration. For this I would suggest to look into the official OpenBSD FAQ which covers all necessary configuration and is always up-to-date..
I conclude this post with some personal judgements. For me, IPv4 is still way easier to understand compared to IPv6. The reason is that in IPv6, everything is intended to be automated with many protocols involved such as SLAAC, DHCPv6 PD, etc. And most importantly, the IPv6 address space is not distinguished into private and public segments anymore. However, the easy part in IPv4 is that private subnets are statically assigned. In contrast, if my IPv6 prefix changes – which happens occasionally – all IPv6 addresses in the internal network change as well. I know that I can mimic static IPv6 addresses via ULA, but that adds additional complexity as I need to run an additional DHCPv6 server on my router.
But, I have learned a lot about IPv6 which probably won’t be the case if I would not host my personal router via OpenBSD. And maybe I’ll appreciate IPv6 more in the near future.
-
With everybody I mean a small fraction of people in my own bubble. ↩︎