⬆️ ⬇️

RPKI integration into BGP on Juniper routers

In this post I wanted to put together all the information on the RPKI certification system, but the topic turned out to be quite extensive, besides I came across several articles in the Russian-language part of the Internet which describe in detail how RPKI works (links to these articles at the end of the post). With examples of setting up and using RPKI on the living gland, everything is getting worse. Therefore, I decided to make an article in the style of HOW-TO. The information presented in the article can help providers automate the process of checking received prefixes from clients and eliminate errors in filters. Anyone who is interested in protecting dynamic routing with RPKI tools and setting up the RPKI cache server on Linux, please ask for cat.



Theory



First, a few terms:



RPKI (Resource Public Key Infrastructure) is a hierarchical public key system (PKI) designed to provide security for global routing on the Internet. RPKI uses the X.509 PKI ( RFC5280 ) certificate architecture with an additional extension that allows the use of IP addresses and AS numbers ( RFC3779 ). The certificate structure allows you to determine the order of distribution of Internet resources (IP addresses and autonomous systems numbers). Internet resources are initially distributed by IANA through the Regional Internet Registries (RIRs), which in turn distribute them to the Local Internet Registries (LIRs), and they in turn distribute the Internet resources among their customers. The RPKI system is built in the same way. Each subsequent distribution of Internet resources is accompanied by the creation of a certificate that is signed with the key of the “parent”, that is, the organization that originally provided these Internet resources. The totality of such certificates attached to each Internet resource constitute a database by which you can verify the accuracy of the information. Such databases are located on public RPKI repositories of all RIRs.



ROA (Route Origin Authorization) - permission to create a route. In accordance with the specification, ROA contains the number of an authorized AS, a list of IP prefixes that this AS has permission to announce and a certificate describing the corresponding information resources. You can read more about the certification system in the article "Certification of Addressable Internet Resources" link to which you will find at the end of the post.

')

Although prefixes can be checked by each router separately for a direct RPKI session, this approach is not recommended because it requires a lot of router resources (demanding cryptographic operations when retrieving RPKI data). To use this data, the best practice is to support your local RPKI cache server, which will synchronize your database with public RPKI repositories. The received data is processed and verified on the cache server. Next, the cache server generates prefix-to-AS entries. The generated database is downloaded to the router via a secure TCP connection using the RPKI-RTR protocol. Thus, the router is not required to process cryptographic information and operate on RPKI data. Subsequently, the router uses a ready-made table for checking prefixes.



On the router, the database is presented in the format of RV (route validation) records. The RV database contains a collection of RV records available for the router to download from the RPKI cache server. An RV record consists of: a prefix, a maximum prefix length, and an AS source. This entry is used to check each route with which the prefix field of the RV entry matches. It also checks the maximum length of the record specified in the RV and the correspondence of the AS number. RV recording is a simplified form of ROA recording. Since the ROA entries themselves are not used to validate routes, the cache server exports the already generated RV entries to the router.



Steps to check the route for RV records:



All prefixes are checked by the router regardless of the state of the local RV records database. If the database is empty at the time of the check, the status will be set to unknown on all prefixes, as there is no information about this prefix in the database. Each time the database is updated, the router resets the timer on the cache server, thus setting a baseline for changes in the database and stores in its memory the version of the database. When reconnecting, the router sends the version of the database that is in its memory to the cache server and if the version is not current, an update will occur.



The prefix received by eBGP based on the verification can take on three states:



Practice



First we need to configure the RPKI cache server with which our router will communicate. For these purposes, the RIPE NCC developed their application RPKI validator running on UNIX-like OS and consisting of two parts:

  1. Web interface for working with the RPKI database
  2. Daemon to work with the router


Java 7 is required to install it. All further steps to install the RPKI validator will be done on Ubuntu 12.04.



Install Java 7:

sudo apt-get remove openjdk* sudo add-apt-repository ppa:webupd8team/java sudo apt-get update sudo apt-get install oracle-java7-installer export JAVA_HOME=/usr/lib/jvm/java-7-oracle #    bashrc echo "export JAVA_HOME=/usr/lib/jvm/java-7-oracle" >> /etc/bash.bashrc 


Install the validator itself from the RIPE page:

 cd /tmp wget https://certification.ripe.net/content/static/validator/rpki-validator-app-2.15-dist.tar.gz tar -xzvf /tmp/rpki-validator-app-2.15-dist.tar.gz -O <_> 


Run validator:

 cd <_> ./rpki-validator.sh start 


In response, we will see:

 [ info ] Starting rpki-validator... [ info ] writing logs under log directory [ info ] Web user interface is available on port 8080 [ info ] Routers can connect on port 8282 [ info ] Writing PID 15860 to validator.pid 


As you can see from the message, the validator daemon occupies two ports:



You can check the operation of the RPKI validator using curl using the API:

 curl http://localhost:8080/api/v1/validity/AS174/89.207.56.0/21 


where AS174 is the AS number, 89.207.56.0/21 is the AS prefix requiring verification. In response, we get:

 { "validated_route":{ "route":{ "origin_asn":"AS174", "prefix":"89.207.56.0/21" }, "validity":{ "state":"Valid", "description":"At least one VRP Matches the Route Prefix", "VRPs":{ "matched":[{ "asn":"AS174", "prefix":"89.207.56.0/21", "max_length":21 }], "unmatched_as":[{ "asn":"AS3257", "prefix":"89.207.56.0/21", "max_length":21 },{ "asn":"AS41073", "prefix":"89.207.56.0/21", "max_length":21 }], "unmatched_length":[] } } } } 




Having come to the address <ip_address_server>: 8080 in the browser, we will see the management interface.

image



On the “Trust Anchors” tab there is a list of all RPKI root servers.

image



On the ROAs tab, a list of all prefixes with RPKI signatures installed (all known ROAs). The interface allows you to search by any parameter, for example, the AS number (AS174 - provider Cogent).

image



On the BGP Preview tab, a list of all prefixes with or without ROA. This tab is convenient for checking all prefixes of any AS.

image



The interface also provides an API for remotely retrieving data.

image



Next, configure the Juniper router itself to work with the RPKI cache server.



We configure the session with the RPKI cache server to check the prefixes. In the example, RPKI validator is running on the server 192.168.0.10:8282 and the router accesses it from the address 192.168.0.1 :

 {master}[edit] user@router# show | compare [edit routing-options] + validation { + group RPKI-validator { + session 192.168.0.10 { + refresh-time 120; + hold-time 180; + port 8282; + local-address 192.168.0.1; + } + } + } 


If you use RE protection on your Juniper router, then you also need to add rules allowing traffic from the RPKI cache server:

 {master}[edit] user@router# show | compare | display omit [edit policy-options] + prefix-list RPKI-servers { + apply-path "routing-options validation group <*> session <*>"; + } + prefix-list RPKI-locals { + apply-path "routing-options validation group <*> session <*> local-address <*>"; + } [edit firewall family inet] + filter accept-rpki { + apply-flags omit; + interface-specific; + term accept-rpki { + from { + source-prefix-list { + RPKI-servers; + } + destination-prefix-list { + RPKI-locals; + } + protocol tcp; + } + then { + count accept-rpki; + accept; + } + } + } [edit interfaces lo0 unit 0 family inet filter] - input-list [ accept-bgp accept-common-services discard-all ]; + input-list [ accept-rpki accept-bgp accept-common-services discard-all ]; 


After applying the configuration, the session will be established:

 {master}[edit] user@router# run show validation session detail Session 192.168.0.10, State: up, Session index: 2 Group: RPKI-validator, Preference: 100 Local IPv4 address: 192.168.0.1, Port: 8282 Refresh time: 120s Hold time: 180s Record Life time: 3600s Serial (Full Update): 16 Serial (Incremental Update): 16 Session flaps: 0 Session uptime: 00:00:16 Last PDU received: 00:00:14 IPv4 prefix count: 7061 IPv6 prefix count: 1109 


RV database of the router will be updated:

 user@router> show validation database | last 20 2a04:71c0::/29-32 200086 192.168.0.10 valid 2a04:81c0::/29-48 48526 192.168.0.10 valid 2a04:8400::/32-64 41887 192.168.0.10 valid 2a04:8d40::/29-32 50304 192.168.0.10 valid 2a04:8f00::/29-29 49531 192.168.0.10 valid 2a04:92c0::/29-29 62240 192.168.0.10 valid 2a04:93c0::/32-48 60251 192.168.0.10 valid 2a04:9fc0::/29-32 24904 192.168.0.10 valid 2a04:a5c0::/29-29 199789 192.168.0.10 valid 2c0f:f668::/32-32 37519 192.168.0.10 valid 2c0f:f970::/32-32 37596 192.168.0.10 valid 2c0f:f9b0::/32-32 37390 192.168.0.10 valid 2c0f:f9b8:a::/48-48 37674 192.168.0.10 valid 2c0f:f9b8:f::/48-48 16265 192.168.0.10 valid 2c0f:faf8::/32-32 37403 192.168.0.10 valid 2c0f:fbf0::/28-28 32653 192.168.0.10 valid 2c0f:fc00::/27-27 3741 192.168.0.10 valid 2c0f:feb0::/32-32 37100 192.168.0.10 valid IPv4 records: 7061 IPv6 records: 1109 


The established session can also be viewed in the RPKI validator web management interface.

image



We configure policy-statement for check of prefixes on a router. To build flexible prefix filters, Juniper recommends creating special BGP communities:



that allow the router to tag prefixes based on the results of the check. This mechanism is convenient to use on border routers that parse ebGP prefixes. For example, such a border router can mark all prefixes with such a community, and then all AS routers connected to it via iBGP, without additional checking through the RPKI cache server, will build their routing tables, trusting this community. This method allows you to configure the RPKI-RTR session only on some routers and thereby reduce the load on the RPKI cache server. Also, the policy will set different local-preference for prefixes based on the results of the check. This will allow the routing table to be built according to the IETF recommendations , setting the lowest priority to those prefixes that have not passed the test.



Create a policy:

 {master}[edit] user@router# show | compare [edit policy-options] + policy-statement RPKI-validation { + term valid { + from { + protocol bgp; + validation-database valid; + } + then { + local-preference 110; + validation-state valid; + community add origin-validation-state-valid; + next policy; + } + } + term invalid { + from { + protocol bgp; + validation-database invalid; + } + then { + local-preference 90; + validation-state invalid; + community add origin-validation-state-invalid; + next policy; + } + } + term unknown { + from protocol bgp; + then { + local-preference 100; + validation-state unknown; + community add origin-validation-state-unknown; + next policy; + } + } + } [edit policy-options] + community origin-validation-state-invalid members 0x43:100:2; + community origin-validation-state-unknown members 0x43:100:1; + community origin-validation-state-valid members 0x43:100:0; 


The community configuration uses the AS number equal to 100, it should be replaced with your AS number.



View the router routing table:

 {master} user@router> show route protocol bgp validation-state valid | last 12 2c0f:faf8::/32 *[BGP/170] 2d 01:27:30, localpref 110 AS path: 174 30844 37105 37403 37403 I, validation-state: valid > to 2001:978:2:b4::1:1 via ae0.12 2c0f:fbf0::/28 *[BGP/170] 2d 01:27:30, localpref 110 AS path: 174 6939 3741 32653 I, validation-state: valid > to 2001:978:2:b4::1:1 via ae0.12 2c0f:fc00::/27 *[BGP/170] 2d 01:27:30, localpref 110 AS path: 174 3356 3741 I, validation-state: valid > to 2001:978:2:b4::1:1 via ae0.12 2c0f:feb0::/32 *[BGP/170] 2d 01:27:30, localpref 110 AS path: 174 37100 ?, validation-state: valid > to 2001:978:2:b4::1:1 via ae0.12 {master} user@router> show route protocol bgp validation-state invalid | last 12 2a03:f85:1::/48 *[BGP/170] 2d 01:27:36, localpref 90 AS path: 174 34305 I, validation-state: invalid > to 2001:978:2:b4::1:1 via ae0.12 2a03:f86:4::/48 *[BGP/170] 2d 01:27:36, localpref 90 AS path: 174 174 54020 59692 I, validation-state: invalid > to 2001:978:2:b4::1:1 via ae0.12 2a03:f87:ffff::/48 *[BGP/170] 2d 01:27:36, localpref 90 AS path: 174 9002 57169 I, validation-state: invalid > to 2001:978:2:b4::1:1 via ae0.12 2a03:bb40::/32 *[BGP/170] 2d 01:27:36, localpref 90 AS path: 174 174 I, validation-state: invalid > to 2001:978:2:b4::1:1 via ae0.12 {master} user@router> show route protocol bgp validation-state unknown | last 12 2c0f:ff40::/26 *[BGP/170] 2d 01:29:56, localpref 100 AS path: 174 6939 10474 I, validation-state: unknown > to 2001:978:2:b4::1:1 via ae0.12 2c0f:ff90::/32 *[BGP/170] 2d 01:29:56, localpref 100 AS path: 174 174 6453 15808 I, validation-state: unknown > to 2001:978:2:b4::1:1 via ae0.12 2c0f:ffa0::/32 *[BGP/170] 01:39:27, localpref 100 AS path: 174 9498 37273 I, validation-state: unknown > to 2001:978:2:b4::1:1 via ae0.12 2c0f:ffd8::/32 *[BGP/170] 2d 01:29:56, localpref 100 AS path: 174 174 33762 I, validation-state: unknown > to 2001:978:2:b4::1:1 via ae0.12 


The results of these commands show that the routing table gives priority to valid routes.



Reality



Unfortunately, at the moment many providers are avoiding schemes using RPKI, since only a small part of the prefixes from the world full-view routing table have certificates. In addition, not all customers have the desire to configure ROA records for their networks. Providers most often use the proven scheme for automatically updating prefix filters based on whois data, running a script once or twice a day. Such a scheme implies full trust in the whois database, which in turn is updated by the customers themselves and may differ from different RIRs. Small regional providers may not care about filters at all, relying on peer filters, and thus be sources of attacks on Traffic Attracting . The situation is also aggravated by the need for additional costs for the installation and maintenance of the RPKI cache server. Probably, until a significant critical mass is reached, this technology will remain in a “paper” form, because, in the opinion of many, the costs of implementation do not pay off the result.



Links


Source: https://habr.com/ru/post/211146/



All Articles