{"id":2634,"date":"2019-12-20T16:45:35","date_gmt":"2019-12-20T15:45:35","guid":{"rendered":"https:\/\/beufa.net\/?p=2634"},"modified":"2020-08-06T08:28:55","modified_gmt":"2020-08-06T07:28:55","slug":"rpki-use-routinator-rtr-cache-validator-cisco-ios-xr","status":"publish","type":"post","link":"https:\/\/beufa.net\/fr\/blog\/rpki-use-routinator-rtr-cache-validator-cisco-ios-xr\/","title":{"rendered":"RPKI &#8211; Use Routinator with Cisco IOS-XR"},"content":{"rendered":"\n<p>While digging about how to drop invalid ROA, I tested <a rel=\"noreferrer noopener\" aria-label=\"routinator (opens in a new tab)\" href=\"https:\/\/github.com\/NLnetLabs\/routinator\" target=\"_blank\">Routinator<\/a> setup. Installing Routinator RPKI-RTR Cache validator is pretty easy using their documentation.<\/p>\n\n\n\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><div style=\"position:absolute;top:-20px;right:0px;cursor:pointer\" class=\"copy-simple-code-block\"><svg aria-hidden=\"true\" role=\"img\" focusable=\"false\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20\" height=\"20\" viewbox=\"0 0 20 20\" class=\"dashicon dashicons-admin-page\"><path d=\"M6 15V2h10v13H6zm-1 1h8v2H3V5h2v11z\"><\/path><\/svg><\/div><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"sh\" data-theme=\"ambiance\" data-fontsize=\"13\" data-lines=\"Infinity\" data-showlines=\"false\" data-copy=\"true\">curl https:\/\/sh.rustup.rs -sSf | sh\nsource ~\/.cargo\/env\ncargo install routinator\nroutinator init\n# Follow instructions provided\nroutinator server --rtr 127.0.0.1:3323<\/pre><\/div>\n\n\n\n<p>When this is done, you can then start configuration on the router. I almost work daily on Cisco IOS-XR platform (on ASR9K hardware). And in fact, there are some tricks to do for this to work, as IOS-XR support only RTR protocol over Secure Transport (SSH for example).<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Configure RPKI server and secure transport<\/h4>\n\n\n\n<p>On the RPKI server, you should create a new user for SSH secure transport for RTR protocol<\/p>\n\n\n\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><div style=\"position:absolute;top:-20px;right:0px;cursor:pointer\" class=\"copy-simple-code-block\"><svg aria-hidden=\"true\" role=\"img\" focusable=\"false\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20\" height=\"20\" viewbox=\"0 0 20 20\" class=\"dashicon dashicons-admin-page\"><path d=\"M6 15V2h10v13H6zm-1 1h8v2H3V5h2v11z\"><\/path><\/svg><\/div><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"sh\" data-theme=\"ambiance\" data-fontsize=\"13\" data-lines=\"Infinity\" data-showlines=\"false\" data-copy=\"true\">adduser rpki<\/pre><\/div>\n\n\n\n<p>Then you should setup a sub-system on sshd_config<\/p>\n\n\n\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><div style=\"position:absolute;top:-20px;right:0px;cursor:pointer\" class=\"copy-simple-code-block\"><svg aria-hidden=\"true\" role=\"img\" focusable=\"false\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20\" height=\"20\" viewbox=\"0 0 20 20\" class=\"dashicon dashicons-admin-page\"><path d=\"M6 15V2h10v13H6zm-1 1h8v2H3V5h2v11z\"><\/path><\/svg><\/div><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"sh\" data-theme=\"ambiance\" data-fontsize=\"13\" data-lines=\"Infinity\" data-showlines=\"false\" data-copy=\"true\"># cat \/etc\/ssh\/sshd_config\n[...]\nPermitRootLogin no\n# needed for user RPKI\nPasswordAuthentication yes\n[...]\n# Define an `rpki-rtr` subsystem which is actually `netcat` used to proxy STDIN\/STDOUT to a running `routinator rtrd -a -l 127.0.0.1:3323`\nSubsystem       rpki-rtr        \/bin\/nc 127.0.0.1 3323\n[...]\n# Certain routers may use old KEX algos and Ciphers which are no longer enabled by default.\n# These examples are required in IOS-XR 5.3 but no longer enabled by default in OpenSSH 7.3\nCiphers +3des-cbc\nKexAlgorithms +diffie-hellman-group1-sha1<\/pre><\/div>\n\n\n\n<p>When you&#8217;ve done this, we can move on the IOS-XR side to setup RPKI server.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Configure IOS-XR RPKI server<\/h4>\n\n\n\n<p>To configure IOS-XR, you&#8217;ll need first to setup RPKI server using SSH username and password (which will be not shown after commit in the configuration).<\/p>\n\n\n\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><div style=\"position:absolute;top:-20px;right:0px;cursor:pointer\" class=\"copy-simple-code-block\"><svg aria-hidden=\"true\" role=\"img\" focusable=\"false\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20\" height=\"20\" viewbox=\"0 0 20 20\" class=\"dashicon dashicons-admin-page\"><path d=\"M6 15V2h10v13H6zm-1 1h8v2H3V5h2v11z\"><\/path><\/svg><\/div><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"sh\" data-theme=\"ambiance\" data-fontsize=\"13\" data-lines=\"Infinity\" data-showlines=\"false\" data-copy=\"true\">router bgp 64567\n!\n rpki server 1.2.3.4\n  username rpki\n  password rpkipassword\n  transport ssh port 22\n  refresh-time 3600\n  response-time 600<\/pre><\/div>\n\n\n\n<p>When this is done, you will need to setup SSH client, as yes, IOS-XR ssh client is still using Cisco SSH v1.99 protocol version ! You can also setup vrf source and interface source if needed. Take care, some releases, like eXR (IOS-XR x64 version) in 6.1.x will not support ssh client v2 option &#8230;<\/p>\n\n\n\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><div style=\"position:absolute;top:-20px;right:0px;cursor:pointer\" class=\"copy-simple-code-block\"><svg aria-hidden=\"true\" role=\"img\" focusable=\"false\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20\" height=\"20\" viewbox=\"0 0 20 20\" class=\"dashicon dashicons-admin-page\"><path d=\"M6 15V2h10v13H6zm-1 1h8v2H3V5h2v11z\"><\/path><\/svg><\/div><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"sh\" data-theme=\"ambiance\" data-fontsize=\"13\" data-lines=\"Infinity\" data-showlines=\"false\" data-copy=\"true\">ssh client v2\nssh client vrf myVRF\nssh client source-interface Loopback10<\/pre><\/div>\n\n\n\n<p>Then after, connection should be established <\/p>\n\n\n\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"sh\" data-theme=\"ambiance\" data-fontsize=\"13\" data-lines=\"Infinity\" data-showlines=\"false\" data-copy=\"false\">bgp[1064]: %ROUTING-BGP-5-RPKI_ADJCHANGE : 1.2.3.4 UP\n\nRP\/0\/RP0\/CPU0:router#sh bgp rpki summary\n\nRPKI cache-servers configured: 1\nRPKI database\n  Total IPv4 net\/path: 97550\/105601\n  Total IPv6 net\/path: 15818\/17522\n\nRP\/0\/RP0\/CPU0:router#sh bgp rpki server 1.2.3.4\n\nRPKI Cache-Server 1.2.3.4\n  Transport: SSH port 22\n  Connect state: ESTAB\n  Conn attempts: 1\n  Total byte RX: 4080600\n  Total byte TX: 7652\nSSH information\n  Username: rpki\n  Password: *****\n  SSH PID: 674259340\nRPKI-RTR protocol information\n  Serial number: 727\n  Cache nonce: 0x79CA\n  Protocol state: DATA_END\n  Refresh  time: 3600 seconds\n  Response time: 600 seconds\n  Purge time: 60 seconds\n  Protocol exchange\n    ROAs announced: 131296 IPv4   23152 IPv6\n    ROAs withdrawn:  25695 IPv4    5630 IPv6\n    Error Reports :      0 sent       0 rcvd<\/pre><\/div>\n\n\n\n<p>Then now, you can enable ROV on IOS-XR, based on the RPKI table<\/p>\n\n\n\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"sh\" data-theme=\"ambiance\" data-fontsize=\"13\" data-lines=\"Infinity\" data-showlines=\"false\" data-copy=\"false\">RP\/0\/RP0\/CPU0:router#sh bgp rpki table\n\n  Network               Maxlen          Origin-AS         Server\n  1.0.0.0\/24            24              13335             1.2.3.4\n  1.1.1.0\/24            24              13335             1.2.3.4\n  1.6.132.240\/29        29              9583              1.2.3.4\n  1.9.0.0\/16            24              4788              1.2.3.4\n  1.9.12.0\/24           24              65037             1.2.3.4\n  1.9.21.0\/24           24              24514             1.2.3.4\n[...]<\/pre><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">Enable Route Origin Validation on IOS-XR<\/h4>\n\n\n\n<p>As stated in the Cisco documentation :<a rel=\"noreferrer noopener\" aria-label=\" BGP Prefix Origin Validation Based on RPKI (opens in a new tab)\" href=\"https:\/\/www.cisco.com\/c\/en\/us\/td\/docs\/routers\/asr9000\/software\/asr9k-r6-2\/routing\/configuration\/guide\/b-routing-cg-asr9000-62x\/b-routing-cg-asr9000-62x_chapter_010.html#concept_A84818AD41744DFFBD094DA7FCD7FE8B\" target=\"_blank\"> BGP Prefix Origin Validation Based on RPKI<\/a>, and thanks to a Cisco SE, I&#8217;ve discover that <em>&#8220;Starting from Release 6.5.1, origin-as validation is disabled by default, you must enable it per address family&#8221;<\/em>.<\/p>\n\n\n\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><div style=\"position:absolute;top:-20px;right:0px;cursor:pointer\" class=\"copy-simple-code-block\"><svg aria-hidden=\"true\" role=\"img\" focusable=\"false\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20\" height=\"20\" viewbox=\"0 0 20 20\" class=\"dashicon dashicons-admin-page\"><path d=\"M6 15V2h10v13H6zm-1 1h8v2H3V5h2v11z\"><\/path><\/svg><\/div><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"sh\" data-theme=\"ambiance\" data-fontsize=\"13\" data-lines=\"Infinity\" data-showlines=\"false\" data-copy=\"true\">router bgp 64567\n !\n address-family ipv4 unicast\n  bgp origin-as validation enable\n  bgp bestpath origin-as use validity\n  bgp bestpath origin-as allow invalid\n !\n address-family ipv6 unicast\n  bgp origin-as validation enable\n  bgp bestpath origin-as use validity\n  bgp bestpath origin-as allow invalid\n !<\/pre><\/div>\n\n\n\n<p>In fact, if you enable &#8220;<em>bgp bestpath origin-as use validity<\/em>&#8220;, you should take care on how the BGP Best Path Selection is modified. See Patel NANOG presentation about <a rel=\"noreferrer noopener\" aria-label=\"Cisco\u2019s Origin Validation Implementation  (opens in a new tab)\" href=\"https:\/\/archive.nanog.org\/sites\/default\/files\/Patel.pdf\" target=\"_blank\">Cisco\u2019s Origin Validation Implementation<\/a>. Reading this, BGP will prefer <em>Valid<\/em> pathes over <em>Not-known<\/em> path (over <em>Invalid<\/em> ones if you allow it). It means eBGP paths received on iBGP sessions will probably will be removed sooner from Best Path Selection algorithm, even if Local-Pref or Med is preferred on iBGP received paths due to a higher priority on the tie break for RPKI ROV.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote has-text-align-left is-layout-flow wp-block-quote-is-layout-flow\"><p>bgp  bestpath origin-as use validity behavior<\/p><cite><em>During BGP best path selection, the default behavior,  if neither of the above options is configured, is that the system will  prefer prefixes in the following order:<\/em><br \/><em>Those with a validation state of valid.<\/em><br \/><em>Those with a validation state of not found.<\/em><br \/><em>Those with a validation state of invalid (which, by default, will not be installed in the routing table).<\/em><br \/><em>These preferences override metric, local preference, and other choices made during the bestpath computation<\/em>.<\/cite><\/blockquote>\n\n\n\n<p>You should use the useful command to understand and check impact. <\/p>\n\n\n\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"sh\" data-theme=\"ambiance\" data-fontsize=\"13\" data-lines=\"Infinity\" data-showlines=\"false\" data-copy=\"false\">RP\/0\/RP0\/CPU0:router# sh bgp 1.1.1.0\/24 bestpath-compare<\/pre><\/div>\n\n\n\n<p>On my side, I prefer to drop invalid using route policies on the eBGP sessions, so I can keep control. So I do not use bestpath validation :<\/p>\n\n\n\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><div style=\"position:absolute;top:-20px;right:0px;cursor:pointer\" class=\"copy-simple-code-block\"><svg aria-hidden=\"true\" role=\"img\" focusable=\"false\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20\" height=\"20\" viewbox=\"0 0 20 20\" class=\"dashicon dashicons-admin-page\"><path d=\"M6 15V2h10v13H6zm-1 1h8v2H3V5h2v11z\"><\/path><\/svg><\/div><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"sh\" data-theme=\"ambiance\" data-fontsize=\"13\" data-lines=\"Infinity\" data-showlines=\"false\" data-copy=\"true\">router bgp 64567 bgp origin-as validation time 30\nrouter bgp 64567 address-family ipv4 unicast bgp origin-as validation enable\nrouter bgp 64567 address-family ipv4 unicast bgp bestpath origin-as allow invalid\nrouter bgp 64567 address-family ipv6 unicast bgp origin-as validation enable\nrouter bgp 64567 address-family ipv6 unicast bgp bestpath origin-as allow invalid<\/pre><\/div>\n\n\n\n<p>To drop invalid on each eBGP sessions, I simply use the following standard route-policy : <\/p>\n\n\n\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><div style=\"position:absolute;top:-20px;right:0px;cursor:pointer\" class=\"copy-simple-code-block\"><svg aria-hidden=\"true\" role=\"img\" focusable=\"false\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20\" height=\"20\" viewbox=\"0 0 20 20\" class=\"dashicon dashicons-admin-page\"><path d=\"M6 15V2h10v13H6zm-1 1h8v2H3V5h2v11z\"><\/path><\/svg><\/div><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"sh\" data-theme=\"ambiance\" data-fontsize=\"13\" data-lines=\"Infinity\" data-showlines=\"false\" data-copy=\"true\">route-policy RP_DROP_RPKI_INVALID\n  if validation-state is invalid then\n    drop\n  endif\nend-policy<\/pre><\/div>\n\n\n\n<p>This RPL is called at start when dropping some Bogons Prefixes (aka Martians) or ASN.<\/p>\n\n\n\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"sh\" data-theme=\"ambiance\" data-fontsize=\"13\" data-lines=\"Infinity\" data-showlines=\"false\" data-copy=\"false\">route-policy RP_EBGP_PEER_IN\n  apply RP_DROP_BOGONS\n  apply RP_DROP_DEFAULT_ROUTE\n  apply RP_DROP_RPKI_INVALID\n  [...]\nend-policy<\/pre><\/div>\n\n\n\n<p>Then you&#8217;ve done \ud83d\ude09 Next article : <a href=\"https:\/\/beufa.net\/blog\/rpki-more-routinator\/\" target=\"_blank\" rel=\"noreferrer noopener\">how to setup Routinator with configuration file and SLURM exceptions file.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>While digging about how to drop invalid ROA, I tested Routinator setup. Installing Routinator RPKI-RTR Cache validator is pretty easy using their documentation. When this&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/beufa.net\/fr\/blog\/rpki-use-routinator-rtr-cache-validator-cisco-ios-xr\/\">Continue reading<span class=\"screen-reader-text\">RPKI &#8211; Use Routinator with Cisco IOS-XR<\/span><\/a><\/div>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24],"tags":[93,103,73,123,107,122,124,120,121],"class_list":["post-2634","post","type-post","status-publish","format-standard","hentry","category-reseau","tag-bgp","tag-ios-xr","tag-network","tag-roa","tag-route-policy","tag-routinator","tag-rov","tag-rpki","tag-rtr","entry"],"_links":{"self":[{"href":"https:\/\/beufa.net\/fr\/wp-json\/wp\/v2\/posts\/2634","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/beufa.net\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/beufa.net\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/beufa.net\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/beufa.net\/fr\/wp-json\/wp\/v2\/comments?post=2634"}],"version-history":[{"count":10,"href":"https:\/\/beufa.net\/fr\/wp-json\/wp\/v2\/posts\/2634\/revisions"}],"predecessor-version":[{"id":2683,"href":"https:\/\/beufa.net\/fr\/wp-json\/wp\/v2\/posts\/2634\/revisions\/2683"}],"wp:attachment":[{"href":"https:\/\/beufa.net\/fr\/wp-json\/wp\/v2\/media?parent=2634"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/beufa.net\/fr\/wp-json\/wp\/v2\/categories?post=2634"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/beufa.net\/fr\/wp-json\/wp\/v2\/tags?post=2634"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}