Securing BGP routing with RPKI and ROA’s
Securing BGP has been on the todo list of the IETF and the community at large for many years. Over the years we’ve seen several proposals, the Resource Public Key Infrastructure (RPKI) is the latest and most successful initiative. RPKI solves one of the most fundemental problems. It allows us to verify whether an Autonomous System (AS) is authorized to announce a specific prefix. This January AfriNIC, LACNIC and RIPE launched their RPKI services, APNIC already started offering this service last year. ARIN should start to offer this service somewhere this year.
As this will become an important technology in securing inter-domain routing, I’ve decided to try to get some hands-on experience with this. In this article I’ll describe my understanding of the current state of the RPKI and introduce the BGPmon ROA validation service.
RPKI building blocks
The main building blocks in the RPKI infrastructure are trust-anchors, ROA’s and validators. Trust-anchors used today are the RIR’s (RIPE, APNIC, LACNIC, AFRINIC). These are the organization that hand out the network resources and therefor are our point of trust. Route Origin Authorization or ROA’s are documents used to link a set of prefixes with an origin ASN. These ROA’s are created by ISP’s, or more accurately the maintainers/administrators of an Autonomous system or Network. The result is signed by the resource holders private key and this signing than creates a chain of trust which allows us to authorize (validate) BGP announcements. Below you’ll find an example ROA, note that a single ROA can contain multiple prefixes and has only one origin AS.
Today, in order to verify BGP announcements, we can only rely on the numerous IRR databases and hope that this information is valid. The RPKI system is not intended to replace the current IRR systems, instead it complements this system.
As you probably know many IRR databases allow you to add any route object to the database. For example you could add a route object for 220.127.116.11/24 with your own origin AS. If your upstream uses the IRR to automatically create prefix-filters, you would now be allowed to announce 18.104.22.168/24. With this new RPKI infrastructure providers, or scripts, can do an additional validations step, to check if the AS in question is authorized to announce this network.
BGP router validation
Eventually the goal is to have BGP capable routers validate prefixes against ROA’s. Based on the result one might change the local-preference of this route add a tag, or whatever you think is best. The key thing is that you’ll have the ability to distinguish authorized announcement from non-authorized routes. So if you have a choice between multiple paths, one with a authorized origin AS and non with a non authorized origin AS you can prefer the path with the authorized origin AS.
Routers won’t do the actual certificate validation, this would take to much resources. Instead they’ll talk to a remote validator that will answer the router’s question:
I just received an announcement for 22.214.171.124/24 with origin AS 15169, is this an authorized announcement?
The remote server will answer this with one of the answers below (as specified in the RFC’s / IETF Drafts):
Code 0: Roa found, validation succeeded
Code 1: No Roa found (resource is not yet signed)
Code 2: Roa found, but validation failed. For example because of an incorrect origin AS or prefixlength.
Validating ROA’s, A proof of concept
In order to gain some experience with RPKI and ROA’s, I’ve decided to develop a ROA validator.
The current implementation relies heavily on the validator written by ripe. This validator fetches all ROA’s from the 4 trust anchors and stores the results locally. As a first implementation I’ve extended the current BGPmon whois service with ROA support. For each query the found prefixes will be checked for a ROA. The output of this whois query will now show and additional line with the results of the ROA validation. See example below:
$ whois -h whois.bgpmon.net 126.96.36.199 Prefix: 188.8.131.52/23 Prefix description: LACNIC Country code: UY Origin AS: 28001 Origin AS Name: LACNIC - Latin American and Caribbean IP address RPKI status: ROA validation successful
If you would like to check just the ROA or receive more information about a ROA, you can use the -–roa feature. This will return the validation code as specified in the RFC’s / IETF Drafts.
In the case of a valid validation it will also print the details of the ROA. In the case of failed validation (2) it will show why it failed. For example it could be an incorrect prefix length or perhaps an invalid origin AS.
Below an example of how to use the bgpmon whois service to validate ROA’s.
$ whois -h whois.bgpmon.net " --roa 28001 184.108.40.206/23" 0 - Valid ------------------------ ROA Details ------------------------ Origin ASN: AS28001 Not valid Before: 2011-01-07 02:00:00 Not valid After: 2012-08-05 03:00:00 Trust Anchor: repository.lacnic.net Prefixes: 220.127.116.11/23 (max length /24) 2001:13c7:7012::/47 (max length /47) 18.104.22.168/22 (max length /24) 2001:13c7:7002::/48 (max length /48)
I believe that this service will be useful for those who just want to play around with ROA’s and get some experience, but also for those who are be implementing a proof of concept ROA validation in routers or other real time validation software, perhaps even in the IRRToolSet
The next step is to add ROA functionality to the BGPmon.net monitoring service. This will allow BGPmon.net users to monitor in real-time if the ROA for your prefix is still valid and will alert you in case we detect any announcements that causes the ROA validation process to fail.
So are we safe now?
ROA’s will help us make the Internet routing infrastructure more secure. By having the ability to check if the origin AS is really authorized to announce this prefix, we should be able to prevent most of the accidental hijacks. However it’s also important to realize that it’s only a first step. For example it’s still possible to bypass this form of security by spoofing (prepending) the origin AS. This works because complete path attestation against the AS_PATH is not (yet?) possible.
Last but not least, this technology and the available software is still relatively new, so please feel free to play and test with it. Let me know if you find any bugs or if you have any suggestions for improvement.