Configuring RPKI-based Route Origin Validation on Mikrotik
About a week ago, Mikrotik announced that the latest version of their OS - I mean, the beta version of RouterOSv7 - now has support for RPKI Origin Validation.
I have decided to try to configure it and report here.
Unfortunately, IPv6 BGP in RouterOSv7 Beta 8 is broken, in which it does not send any network announcement to the other peer in the BGP session. This means that at the time of this writing, my whole IPv6 configuration is broken, because I can't originate any IPv6 announcement from my network.
Anyway, on with the experiment. First of all we need to find our canary, a network that is covered by a ROA that makes it invalid. There is a route announced by Cloudflare that we can use, and it's all described in this article:
[admin@r1.btl.ch.as58280.net] /ipv6/route> print where dst-address="2606:4700:7000::/48" Flags: D - DYNAMIC; I - INACTIVE, A - ACTIVE; b - BGP, m - MODEM Columns: DST-ADDRESS, GATEWAY, DISTANCE DST-ADDRESS GA DI DIb 2606:4700:7000::/48 :: 20 DIb 2606:4700:7000::/48 :: 20
As you can see, we are now receiving it. I am receiving a full IPv6 feed from OpenFactory - AS58299 at the moment.
We have to do work in three stages:
- Install a validator. In this case we will use routinator from NLNetLabs. It's really easy to install, fast, and will fit here;
- Set up a connection to the validator from the router. In this case I am running a RB4011;
- Use the information we obtain from the validator to filter out the invalid networks.
1. Install routinator
I have been using FreeBSD for about 20 years, so I will go ahead with it. Routinator can also be installed on any Linux flavour.
On FreeBSD, we have a package, so I will go ahead with pkg.
root@routinator /root> pkg install routinator
Then configure to init it for the TALs
sudo -u routinator -g routinator routinator -c /usr/local/etc/routinator/routinator.conf init sudo -u routinator -g routinator routinator -c /usr/local/etc/routinator/routinator.conf init --accept-arin-rpa
The first command actually errored out, so I first copy the config file manually, and then re-run those two commands.
root@routinator /root> cp /usr/local/etc/routinator/routinator.conf.example /usr/local/etc/routinator/routinator.conf
Additionally, I didn't have sudo, so I ran the commands as root and then I changed the owner of all the directories to be the routinator user.
I also changed the configuration so that the directory structure is more in line with what FreeBSD uses as standard hierarchy.
You can find the complete file here
The last thing to do is to configure routinator to run in rc.conf and then run it:
root@routinator /root> echo 'routinator_enable="YES"' >> /etc/rc.conf root@routinator /root> /usr/local/etc/rc.d/routinator start
and now we have routinator running and listening on 45.129.224.37 port 3323.
This instance of routinator is available to use, and I'll soon setup a hostname for it.
2. Configure the RTR Session
Then, on to configuring our router. As you can see, we have a specific menu for RPKI:
[admin@r1.btl.ch.as58280.net] /routing/bgp> .. -- go up to routing advertisements -- connection -- peer-cache -- rpki -- template --
The work we have to do is divided in two parts:
- Setting up communication to the routinator instance; and
- Setting up our filters so that we filter based on RPKI.
First of all, we have to configure the RTR Session. We will connect to the routinator instance we have set up previously, so here:
[admin@r1.btl.ch.as58280.net] /routing/bgp/rpki> add address=45.129.224.37 port=3323 preference=1
and I got an error while trying to print the entries:
[admin@r1.btl.ch.as58280.net] /routing/bgp/rpki> print Flags: X - disabled 0 ;;; group name must be specified address=45.129.224.37 port=3323 preference=1 [admin@r1.btl.ch.as58280.net] /routing/bgp/rpki> set 0 group= Group ::= [admin@r1.btl.ch.as58280.net] /routing/bgp/rpki> set 0 group=validator [admin@r1.btl.ch.as58280.net] /routing/bgp/rpki> print Flags: X - disabled 0 group=validator address=45.129.224.37 port=3323 preference=1 [admin@r1.btl.ch.as58280.net] /routing/bgp/rpki>
Turns out you can configure groups of validators to talk to, and I later on discovered that in your filters you can point to these specific groups. That looks like an interesting feature.
3. Configure the filters
Let's go ahead and see what we need to do next with the filters.
[admin@r1.btl.ch.as58280.net] /routing/filter/rule> add action=accept chain=in-v6 rpki-verify=validator rpki-match=valid [admin@r1.btl.ch.as58280.net] /routing/filter/rule> add chain=in-v6 action=reject match-rpki=invalid
and then we need to add this filter chain to the template we use for BGP. In /routing/bgp/template/ I have the following:
[admin@r1.btl.ch.as58280.net] /routing/bgp/template> print Flags: * - default, X - disabled, I - inactive 0 * ;;; reserved AS value name="default" instance=default 1 name="stucchinet4" routing-table=main as=58280 address-families=ip,ipv6 output.filter=out-v4 .network=45.129.224.0/22 2 name="stucchinet6" routing-table=main instance=default apply-changes=auto as=58280 address-families=ipv6 output.filter="" .network=""
And especially for the IPv6 template, I have no input.filter set, yet. So let's go ahead and add it:
[admin@r1.btl.ch.as58280.net] /routing/bgp/template> set 2 input.filter=in-v6 [admin@r1.btl.ch.as58280.net] /routing/bgp/template> print Flags: * - default, X - disabled, I - inactive 0 * ;;; reserved AS value name="default" instance=default 1 name="stucchinet4" routing-table=main as=58280 address-families=ip,ipv6 output.filter=out-v4 .network=45.129.224.0/22 2 name="stucchinet6" routing-table=main instance=default apply-changes=auto as=58280 address-families=ipv6 output.filter="" .network="" input.filter=in-v6
and there it is.
4. Check the result
Let's now check if Origin Validation gets applied:
[admin@r1.btl.ch.as58280.net] /routing/bgp/template> /ipv6 route/ [admin@r1.btl.ch.as58280.net] /ipv6/route> print where dst-address="2606:4700:7000::/48" [admin@r1.btl.ch.as58280.net] /ipv6/route>
Here we go! The prefix is not visible anymore and gets filtered out.
You might have to disable and re-enable the BGP Session for the filter to kick in.
This is the end. Besides the issues with IPv6 BGP, it seems that Mikrotik is going towards a nice result with this, so I hope they work quickly on making RouterOS v7 available for production, and hopefully this will increase RPKI adoption around the World, and will make Job Snijders happy... :)
Comments
Comments powered by Disqus