Setting up ospf on OpenBSD
OpenBSD & ospfd
So, in a previous article we looked at setting up IPSec ikev2 tunnels between some nodes, all conncted via sec interfaces.
Now that we have connectivity, the next step is to distribute some routes. Let’s revisit our network diagram, with some IP ranges shown:
┌──────────────┐ ┌──────────────┐
│ │ │ │
10.0.0.0/24│ reachout │ │ outreach │ 10.0.1.0/24
└──────▲───────┘ └──────▲───────┘
sec0 │100.64.0.2 sec0 │ 100.64.1.2
│ │
│ │
│ │
│ │
│ │
│100.64.0.1 │100.64.1.1
sec0 │ ┌───────────────┐ │ sec1
└───┤ ├────┘
│ fw0 │
┌────────x►──▲─────────▲─x◄───────────┐
│ │ │ │
│ │ │ │
┌─────────┴──┐ ┌───────┴────┐ ┌──┴─────────┐ ┌──┴─────────┐
│vlan100 │ │vlan200 │ │vlan210 │ │vlan220 │
│172.16.100 │ │172.16.200 │ │172.16.210 │ │172.16.220 │
└────────────┘ └────────────┘ └────────────┘ └────────────┘
We could simply edit the route tables by hand to create connectivity between all of our hosts, but that soon starts to get messy and complicated - everytime you spring up a new network, you will have to run round and change the configuration on each of the boxes. Assuming you wanted to do that, the easiest way would be to add another line to our hostname.if files, like this:
inet 192.168.168.2/30
inet6 fe80::aaaa
group trusted
up
!route add 10.0.0.0/23 192.168.168.1
ospfd
OpenBSD comes with an OSPF daemon out of the box, and it’s very simple to configure - we just need to run it on our sec
interfaces we’ve set up, but it’s not tied to those types of interface - it will work on wg
tunnels for example, as well as physical interfaces etc.
Let’s start with the config file - there’s an example one in /etc/examples
. We’ll unpick it a bit at a time.
# $OpenBSD: ospfd.conf,v 1.2 2018/08/07 07:06:20 claudio Exp $
# macros
id="100.64.0.1"
# global configuration
router-id $id
#redistribute connected
redistribute default
redistribute 172.23.132.224/28
redistribute 172.20.53.104/32
redistribute 172.22.119.1/32
The first thing to notice is the id
line - it’s not actually important what this is set to, but it’s good practice to at least pick one of your own IP addresses. Nodes will exchange messages using this as the ID.
Next up, redistribute default
. This means that you want a default route to be shared (i.e. 0.0.0.0/0
) in case you want to tell other hosts to use you as a default gateway - they won’t automatically do that though, we will cover that later.
After that, we’re distributing some actual routes.
Going back to our example above, if we wanted to share a route to reachout
and outreach
of how to get to the vlan100
and vlan200
networks, we’d just pop in the appropriate entry:
redistribute 172.16.100.0/24
redistribute 172.16.200.0/24
Naturally, we can condense all these routes into a single line if we wanted to share all of the networks on the host:
redistribute 172.16.0.0/16
After that, we just need to configure what interfaces we want to send our routes on:
# areas
area 0.0.0.5 {
interface sec0 {
auth-type simple
auth-key SOMERANDHEX
#type p2p
}
interface sec1 {
auth-type simple
auth-key SOMERANDHEX
#type p2p
}
}
That’s it, with the exception we need to configure the remote hosts with their own configurations. At this point you may need to create some pf.conf
rules to allow the traffic - ospf has it’s own protocol:
pass in on sec0 proto ospf all
pass out on sec0 proto ospf all
Start the ospfd
daemon on both the nodes, either via the rcctl
command or by running it from the command line as ospfd -dvv
. There’s a corresponding ospfctl
command which you can use to interact with the daemon, for exampe ospfctl reload
will force a reload of the config file in case you’ve made changes. Nice!
First up, lets see how everthing is currently looking:
zsh 571 % ospfctl show
Router ID: 100.64.0.1
Uptime: 4d18h21m
RFC1583 compatibility flag is disabled
SPF delay is 1000 msec(s), hold time between two SPFs is 5000 msec(s)
Number of external LSA(s) 22 (Checksum sum 0x99321)
Number of areas attached to this router: 1
Area ID: 0.0.0.5
Number of interfaces in this area: 2
Number of fully adjacent neighbors in this area: 2
SPF algorithm executed 29 time(s)
Number LSA(s) 3 (Checksum sum 0x1ab98)
Next, who are we connected to?
zsh 572 % ospfctl show neigh
ID Pri State DeadTime Address Iface Uptime
100.64.1.1 1 FULL/P2P 00:00:31 192.168.168.1 sec1 3d06h06m
100.64.1.2 1 FULL/P2P 00:00:39 100.64.0.2 sec0 05:18:58
Note the difference between the ID
and the Addresses
- the ID is taken from the config, the actual connection address is used as the Address.
However, whats really of interest to us is what routes have we recieved from our neighbours?
zsh 573 % ospfctl show rib
Destination Nexthop Path Type Type Cost Uptime
100.64.0.1 0.0.0.0 C Intra-Area Router 0 4d18h24m
100.64.1.1 192.168.168.1 Intra-Area Router 10 3d06h08m
100.64.1.2 100.64.0.2 Intra-Area Router 10 05:20:45
100.64.0.1/32 100.64.0.2 Intra-Area Network 20 05:20:45
100.64.0.2/32 0.0.0.0 C Intra-Area Network 10 05:20:50
100.64.1.1/32 100.64.0.2 Intra-Area Network 20 05:20:40
100.64.1.2/32 192.168.168.1 Intra-Area Network 20 05:20:40
192.168.168.1/32 0.0.0.0 C Intra-Area Network 10 3d06h08m
192.168.168.2/32 192.168.168.1 Intra-Area Network 20 3d06h08m
0.0.0.0/0 192.168.168.1 Type 1 ext Network 110 3d06h08m
172.16.0.0/24 100.64.0.2 Type 1 ext Network 110 05:20:45
172.16.100.0/24 100.64.0.2 Type 1 ext Network 110 05:20:45
172.16.200.0/24 100.64.0.2 Type 1 ext Network 110 05:20:45
172.16.210.0/24 100.64.0.2 Type 1 ext Network 110 05:20:45
172.16.220.0/24 100.64.0.2 Type 1 ext Network 110 05:20:45
172.20.53.97/32 192.168.168.1 Type 1 ext Network 110 3d06h08m
172.20.53.102/32 192.168.168.1 Type 1 ext Network 110 3d06h08m
172.23.132.250/32 100.64.0.2 Type 1 ext Network 110 05:20:45
172.23.132.252/32 192.168.168.1 Type 1 ext Network 110 3d06h08m
172.23.132.253/32 192.168.168.1 Type 1 ext Network 110 3d06h08m
172.23.132.254/32 192.168.168.1 Type 1 ext Network 110 3d06h08m
192.168.23.0/25 100.64.0.2 Type 1 ext Network 110 05:20:45
192.168.23.1/32 100.64.0.2 Type 1 ext Network 110 05:20:45
192.168.23.3/32 100.64.0.2 Type 1 ext Network 110 05:20:45
192.168.23.8/32 100.64.0.2 Type 1 ext Network 110 05:20:45
192.168.23.14/32 100.64.0.2 Type 1 ext Network 110 05:20:45
We’ve saved ourselves quite some time in not having to create those routes manually!
Let’s look at our routing tables next:
zsh 577 [1] % netstat -rn | head -10 && netstat -rn | grep 172.16.200
Routing tables
Internet:
Destination Gateway Flags Refs Use Mtu Prio Iface
default 10.0.0.1 UGS 8 3529968 - 8 vio0
default 192.168.168.1 UG 0 0 - 32 sec1
224/4 127.0.0.1 URS 0 84174 32768 8 lo0
10.0.0/24 10.0.0.225 UCn 1 0 - 4 vio0
10.0.0.1 00:00:17:27:1e:5a UHLch 1 600 - 3 vio0
10.0.0.225 02:00:17:00:f1:93 UHLl 0 3853356 - 1 vio0
172.16.200/24 100.64.0.2 UG 0 0 - 32 sec0
If you look at the Prio
field, you’ll see some routes have a Priority of 8
- these are static routes someone has manually defined. But some of them are a priority of 32
- these are ospf routes. In a future article, we’ll look at BGP, and those have a priority of 48
. Lower is more preferred.
Now, remember we had distribute default
in our config? We can see we have a default gateway set on this host, now we have two default routes. However, we will only ever use the one we manually configured because of the prio
setting. If you removed your static default route, you’d wind up using the one with the next highest priority, in the case we’d route all traffic for unknown destinations to the 192.168.168.1
gateway.
ospf6d
Setting up IPv6 ospf is done via the ospf6d
command - you are expected to run both at the same time. They work slightly differently, but the major difference is that there is no auth in this daemon. That said, there’s not really any auth in the previous one, so I wouldn’t worry too much about it.
zsh 578 % sudo more /etc/ospf6d.conf
redistribute default
redistribute fd1f:abc9:4ab::/48
redistribute 2001:470:6b54::1/48
area 0.0.0.0 {
interface sec0 {
type p2p
}
interface sec1 {
type p2p
}
}
There’s a few other shortcomings in this daemon - for example there is no reload functionality in ospf6ctl
. No matter.
zsh 579 % ospf6ctl show
Router ID: 10.0.0.225
Uptime: 4d00h31m
SPF delay is 1 sec(s), hold time between two SPFs is 5 sec(s)
Number of external LSA(s) 33
Number of areas attached to this router: 1
Area ID: 0.0.0.0
Number of interfaces in this area: 2
Number of fully adjacent neighbors in this area: 2
SPF algorithm executed 21 time(s)
Number LSA(s) 6
zsh 580 % ospf6ctl show neigh
ID Pri State DeadTime Iface Uptime
10.0.1.29 1 FULL/P2P 00:00:33 sec1 4d00h31m
172.16.0.250 1 FULL/P2P 00:00:33 sec0 05:29:16
zsh 581 % ospf6ctl show rib
Destination Nexthop Path Type Type Cost Uptime
::10.0.1.29 fe80::bbbb%sec1 Inter-Area Router 10 4d00h31m
::172.16.0.250 fe80::aaaa%sec0 Inter-Area Router 10 05:29:36
fd1f:abc9:4ab:a000::/64 fe80::aaaa%sec0 Intra-Area Network 65545 05:29:36
fd1f:abc9:4ab:b000::/64 fe80::bbbb%sec1 Intra-Area Network 65545 4d00h31m
fd1f:abc9:4ab:b000::/64 fe80::aaaa%sec0 Intra-Area Network 65545 05:29:36
fd1f:abc9:4ab:c000::/64 fe80::bbbb%sec1 Intra-Area Network 65545 4d00h31m
2001:470:b412::/64 fe80::aaaa%sec0 Type 1 ext Network 110 05:29:36
2001:470:b412:100::/64 fe80::aaaa%sec0 Type 1 ext Network 110 05:29:36
2001:470:b412:210::/64 fe80::aaaa%sec0 Type 1 ext Network 110 05:29:36
fd1f:abc9:4ab::/48 fe80::bbbb%sec1 Type 1 ext Network 110 4d00h31m
fd1f:abc9:4ab::/48 fe80::aaaa%sec0 Type 1 ext Network 110 05:29:36
fd1f:abc9:4ab:2000:100::2/128 fe80::bbbb%sec1 Type 1 ext Network 110 4d00h31m
fd1f:abc9:4ab:2000:200::/72 fe80::bbbb%sec1 Type 1 ext Network 110 4d00h31m
fd1f:abc9:4ab:2000:200::1/128 fe80::bbbb%sec1 Type 1 ext Network 110 4d00h31m
fd1f:abc9:4ab:2000:300::2/128 fe80::bbbb%sec1 Type 1 ext Network 110 4d00h31m
fd1f:abc9:4ab:3000::/64 fe80::aaaa%sec0 Type 1 ext Network 110 05:29:36
fd1f:abc9:4ab:3100::/64 fe80::aaaa%sec0 Type 1 ext Network 110 05:29:36
fd1f:abc9:4ab:3200::/64 fe80::aaaa%sec0 Type 1 ext Network 110 05:29:36
fd1f:abc9:4ab:3210::/64 fe80::aaaa%sec0 Type 1 ext Network 110 05:29:36
fd1f:abc9:4ab:3220::/64 fe80::aaaa%sec0 Type 1 ext Network 110 05:29:36
fd1f:abc9:4ab:a000::1/128 fe80::aaaa%sec0 Type 1 ext Network 110 05:29:36
fd1f:abc9:4ab:a000::2/128 fe80::aaaa%sec0 Type 1 ext Network 110 05:29:36
fd1f:abc9:4ab:b000::1/128 fe80::bbbb%sec1 Type 1 ext Network 110 4d00h31m
fd1f:abc9:4ab:b000::1/128 fe80::aaaa%sec0 Type 1 ext Network 110 05:29:36
fd1f:abc9:4ab:b000::2/128 fe80::bbbb%sec1 Type 1 ext Network 110 4d00h31m
fd1f:abc9:4ab:b000::2/128 fe80::aaaa%sec0 Type 1 ext Network 110 05:29:36
fd1f:abc9:4ab:c000::1/128 fe80::bbbb%sec1 Type 1 ext Network 110 4d00h31m
fd1f:abc9:4ab:c000::2/128 fe80::bbbb%sec1 Type 1 ext Network 110 4d00h31m
That’s it!