OpenBSD version: 7.1 Arch: Any NSFP: Do this if you run production...
The problem of route hijacks and accidental announcements
The Internet used to be a rather friendly place of people building things that work. While, for most parts, this is still true, it has also become something used by far more people; on all levels. And with far more people, you usually also find far more stuff going on that is not exactly ‘well intentioned’. On the Internet, these things usually coincide when not so nice people not so interested in building things figure out some of the fundamental protocols making the Internet work somewhere rests a lot of its functionality and security on… well,… trust.
This hurt us with, for example, amplification attacks. The idea that somebody would simply pretend to have a certain source address was wild… they would not get answers; Instead, the replies to anything they’d ask for would land elsewhere… and well, that was than exactly the point (we will get to this issue in one of the next posts).
For routing on the Internet, that moment hit when people realized that what routes you announce is basically an honor system. There is no inherent mechanism in BGP that makes sure an AS only announces IP addresses it is allowed to announce.
While ‘not announcing what you are supposed to announce’ caused some problems in the early Internet, it only got interesting when less well intentioned actors figured out that announcing (more specific) prefixes of somebody else can actually yield you control over traffic to those destinations. In turn, this means getting certificates for hosts in such hijacked netblocks, or whatever you can do with IP addresses of a credit card company.
It is fun to deploy the R-P-K-I
While, technically, IRR databases could already be a great source of information for who is allowed to announce what, these databases are, traditionally, a mess. Furthermore, they are generally not cryptographically signed and lack a common interface that provide ‘please just give me a complete list of who should announce what’.
The solution to this is the Resource Public Key Infrastructure (RPKI). First spec’ed out in RFC6810, it provides an infrastructure to sign prefixes of certain sizes and the information which AS is supposed to announce them. With RFC8210, we then also have a protocol to make these signatures show up on routers.
So, there we have it. A tree shaped–as all good things should be–system which enables us to tell the world who is allowed to announce our prefixes.
A bit of politics
When it comes to RPKI, there is sadly also a lot of politics and opinions involved. I honestly do not really want to take a position here. However, it might be good to summarize the main points:
- a) RPKI could also be used as an infrastructure to retract prefixes, especially if nation states would figure out they might be able to apply pressure to RIRs here.
- b) RPKI only works if everyone is doing it (a bit like IPv6 and all the other nice future things)
While the former is a discussion i am not really keen on getting into at the moment, the latter should be quiet obvious: (Especially on OpenBSD) it is fast, it is easy, and–most of all–it is free. So, just do it. This entails signing one’s routes as well as rejecting prefixes that are invalid, i.e., prefixes that are signed for one (or multiple) ASes, but are announced by another AS. At the moment (given kind of limited adoption) dropping unsigned prefixes will make your Internet rather small. ;-)
Enabling RPKI route validation in OpenBGPd
To be honest, it is nearly harder to not enable RPKI in your OpenBGPd than it is to do it. First, to generate a route-map for OpenBGPD, we just have to uncomment the already existing entry in root’s crontab on our router:
~ * * * * -ns rpki-client -v && bgpctl reload
Next, if we are already running a config build based on the default one
/etc/examples/bgpd.conf, everything should be already in place. In
that config, we have the following two lines doing the magic:
17 include "/var/db/rpki-client/openbgpd" ... 118 # deny RPKI invalid, built by rpki-client(8), see root crontab 119 deny quick from ebgp ovs invalid
So, after you enabled the cronjob, once every hour
rpki-client will run to
/var/db/rpki-client/openbgpd; If that run is successful, it will
automatically reload your bgpd, and your bgpd will reject signed prefixes
announced by unsigned ASes.
To see if things worked after your first run of
rpki-client and subsequent
bgpctl reload, just browse to https://isbgpsafeyet.com/ from
an IP in your AS and run the test.
As I said: Quick. Easy. Free.
Configuring RPKI for your own prefixes
Again, this is relatively simple; All five RIRs offer a hosted CA solution for your RPKI setup (AFRINIC, APNIC, ARIN, LACNIC, and RIPE NCC). While this is strictly speaking not the most self-hosted solution, I would argue that for this specific piece of infrastructure it is pretty much fine. ;-)
From there, it is usually just a couple of times clicking ‘yes’ before you have a panel in your RIR’s portal that allows you to configure Route Origin Authorizations (ROAs) for your prefixes. At the RIPE NCC (and I guess at the others too) there is even a convenient ‘here is what i currently see in the GRT, do you just want to add ROAs for that’ feature.
There is a bit more to this, for example, you can set the minimum and maximum
prefix size for your prefixes; This can come in handy if you have a
IPv6 space and don’t want to add individual ROAs for each /48 you allocate from
that. However, for this post, that is a bit out of scope, and there are far
better, and far better and more in-depth explanations for setting
up RPKI with more bells and whistles. Similarly, RIRs usually offer a reporting
feature which will let you know if announcements–from you or ‘others’–show
up that are not covered by the ROAs you configured.
In summary, the take away is: Even though it needs some more clicks than making OpenBGPd drop invalid prefixes, it is still Quick, Easy, and Free.
Quick. Easy. Free.
Do it. :-)