KPN FTTH with OpenBSD

If you have an XGSPON fiber-to-the-home ("glasvezel") connection from KPN or XS4ALL (Dutch ISPs), then you probably have an RJ45 connection in your "meterkast". Ever wondered what's on there? I certainly have!

I'm replacing the Fritzbox my provider supplied (or Experia box, KPN box) with an OpenBSD box. This will let me satisfy my curiosity and maybe the nanny as well. It turns out that the Pihole DNS server on my LAN is not reachable from the guest WiFi. This makes sense, but not having DNS made the nanny unhappy.

Another reason I'm doing this is that I'm curious about OpenBSD. I've been looking for a good excuse to play with it and for me this is it. At work we're using FreeBSD and I am curious about the differences and mostly about PF on OpenBSD vs FreeBSD.

So this will be a small series of articles on KPN + OpenBSD. In this one we'll focus on getting internet connectivity on the router and setting up a basic firewall. In the next articles we'll add internet access for LAN clients, IPTV and a caching DNS server:

  1. Basic internet connectivity
  2. Serving the local network
  3. Adding IPTV

🌐 Configuring network interfaces

The router should be connected directly to the fiber ONT box (Optical Network Termination) in your "meterkast" with an RJ45 cable. VLAN6 on this cable is where KPN delivers internet access over PPPOE. I'm assuming this cable is connected to interface em0 in your OpenBSD box.

So let's configure em0. It should be brought up on boot and we need a VLAN with id 6. If we don't bring up em0 (and vlan6), then the PPPOE session will not start later. Note that we don't need IP addresses on these interfaces.

echo 'description "KPN FTTH (wan)" up' > /etc/hostname.em0
cat > /etc/hostname.vlan6 <<EOF
parent em0 vnetid 6
description "KPN vlan6 (internet)"
mtu 1508
up
EOF

sh /etc/netstart

Note the vlan6 interface has an increased MTU at 1508 bytes. KPN can do a 1500 MTU in the PPPOE and a PPPOE header is 8 bytes. So to do 1500 "inside" the PPPOE, we need 1508 "outside". Without the larger MTU on the VLAN interface the PPPOE MTU would sit at 1492. If hosts on your LAN are using 1500 (which they typically would) then that mismatch could lead to lots of fragmented packets.

So next up is the PPPOE connection on vlan6.

cat > hostname.pppoe0 <<EOF
inet 0.0.0.0 255.255.255.255 NONE \\
mtu 1500 \\
pppoedev vlan6 authproto pap \\
authname internet authkey internet \\
description "KPN PPPOE internet" \\
up
dest 0.0.0.1
!/sbin/route add default -ifp pppoe0 0.0.0.1
EOF


sh /etc/netstart

Note that 0.0.0.0 and 0.0.0.1 are magical placeholders. Read pppoe(4) to understand what they mean. Also note that it does not matter what you enter as authname and authkey.

You should now be in business with internet access on your OpenBSD box! Your ifconfig(8) should look something like this:

$ ifconfig
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
description: KPN FTTH (wan)
media: Ethernet autoselect (1000baseT full-duplex)
status: active
pppoe0: flags=8851<UP,POINTOPOINT,RUNNING,SIMPLEX,MULTICAST> mtu 1500
description: KPN PPPOE internet
dev: vlan6 state: session
sid: 0x1234 PADI retries: 0 PADR retries: 0 time: 00:10:18
sppp: phase network authproto pap
dns: 195.121.97.202 195.121.97.203
groups: pppoe egress
status: active
inet $YOUR_PUBLIC_IP --> $KPN_PPPOE_CONCENTRATOR netmask 0xffffffff
vlan6: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1508
description: KPN vlan6 (internet)
encap: vnetid 6 parent em0 txprio packet rxprio outer
media: Ethernet autoselect (1000baseT full-duplex)
status: active

And you should be able to ping ..

$ ping openbsd.org
PING openbsd.org (199.185.178.80): 56 data bytes
64 bytes from 199.185.178.80: icmp_seq=0 ttl=244 time=125.237 ms
...

If DNS is not working check /etc/resolv.conf. It should have been updated by resolvd(8) to something like this:

nameserver 195.121.97.202 # resolvd: pppoe0
nameserver 195.121.97.203 # resolvd: pppoe0
lookup file bind

If you can't ping e.g. 1.1.1.1 either, then check your PPPOE connection:

ifconfig pppoe0 debug
tail -f /var/log/messages
# turn off debugging messages when done:
ifconfig pppoe0 -debug

🔥 Basic firewall

Now let's quickly set up a very basic firewall that blocks all incoming traffic except echo requests (pings) and SSH.

mv /etc/pf.conf /etc/pf.conf.bak
cat > /etc/pf.conf <<EOF
wan = "pppoe0"

table <martians> { \\
0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 \\
172.16.0.0/12 192.0.0.0/24 192.0.2.0/24 224.0.0.0/3 \\
192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 \\
203.0.113.0/24 }

set skip on lo0

match out on \$wan inet from ! (\$wan:network) nat-to (\$wan)

block return log
block drop in log quick on \$wan from { <martians>, urpf-failed }

pass out from (self)
pass in inet proto icmp to (self) icmp-type echoreq
pass in inet proto tcp to (self) port 22
EOF

Load the new rules and make sure the firewall is enabled:

pfctl -vf /etc/pf.conf
pfctl -e

Note, PF will happily load rules for interfaces that do not exist. So make sure your interface names are correct!


🗣 Comments

I manually review comments so it may take a while for your comment to get published.