{"id":3052,"date":"2021-01-23T13:03:12","date_gmt":"2021-01-23T17:03:12","guid":{"rendered":"http:\/\/arielantigua.com\/weblog\/?p=3052"},"modified":"2021-01-23T13:04:34","modified_gmt":"2021-01-23T17:04:34","slug":"vrf-en-linux-con-bird-para-ospf-bgp","status":"publish","type":"post","link":"https:\/\/arielantigua.com\/weblog\/2021\/01\/vrf-en-linux-con-bird-para-ospf-bgp\/","title":{"rendered":"VRF en Linux con BIRD para OSPF\/BGP"},"content":{"rendered":"<p>VRF en Linux con BIRD para OSPF\/BGP.<\/p>\n<p>Desde hace mucho tiempo estoy jugando con BGP, inicialmente ten\u00eda BGP en pfSense, algo sencillo y con solo algunas rutas, eso fue en los tiempos de dn42.<\/p>\n<p>En el 2016 encontr\u00e9 una comunidad de varios entusiastas de redes al nivel de Internet y pude conseguir un ASN registrado en RIPE.<\/p>\n<p>Muchas cosas han cambiado desde esos d\u00edas, he aprendido y experimentado, aprender es la raz\u00f3n de ser de <a href=\"https:\/\/aanetworks.org\">aaNetworks<\/a>. Lo complicado de mi red con direcciones <a href=\"https:\/\/arielantigua.com\/weblog\/2019\/10\/as207036-por-que-y-para-que\/\">IP Publicas y ASN<\/a> es que localmente en mi casa no hay forma posible de tener una sesi\u00f3n BGP y publicar los prefijos desde ah\u00ed (imag\u00ednate que CLARO te permita hacer un t\u00fanel L2TP a un router con BGP!), dependo de VPS con Linux y BIRD.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/interpip.es\/wp-content\/uploads\/2020\/08\/153703.jpg?fit=479%2C273&amp;ssl=1\" \/><\/p>\n<p><!--more--><\/p>\n<p><strong>Estado actual.<\/strong><\/p>\n<p>Usando wireguard se interconectan <a href=\"https:\/\/arielantigua.com\/weblog\/home-lab\/\"><em>4<\/em> VPS y <em>1<\/em> servidor f\u00edsico en mi casa<\/a>, todos ejecutan BIRD, de esta manera pueden establecer sesiones BGP tanto internas (iBGP) como externas (eBGP) para anunciar los prefijos.<\/p>\n<p>Con OSPF se distribuyen direcciones de enlaces (\/30) y direcciones en lo (loopback con \/32), es m\u00e1s f\u00e1cil montar una sesi\u00f3n BGP apuntando a las direcciones en la loopback, se elimina tener que crear una inmensidad de sesiones ya que la direcci\u00f3n en loopback puede ser alcanzada por cualquiera de los routers en el \u00e1rea de OSPF.<\/p>\n<p>El problema que \u00faltimamente tengo es cuando la mejor ruta para alc\u00e1zar uno de los VPS es aprendida por iBGP, esto significa el doble de perdida de paquetes y latencia. Investigando y probando mucho, decid\u00ed que la mejor manera de \u201csolucionar el problema\u201d era usando tablas de rutas dedicadas (Policy Based Routing), una para los enlaces wireguard y otra para las rutas aprendidas en BGP. Esto resolv\u00eda el problema, pero introdujo unos nuevos que no son de mi agrado.<\/p>\n<p><strong>Nuevos problemas.<\/strong><\/p>\n<ol>\n<li>De manera manual ten\u00eda que introducir los origines o destinos de mi red interna en ambas tablas.<\/li>\n<li>Se debe agregar otra IP \/32 en la loopback para poder monitorear los VPS.<\/li>\n<li>La tabla para las rutas aprendidas por OSPF deb\u00edan ser copiadas a la tabla donde se guardaban las rutas aprendidas por BGP.<\/li>\n<li>\u00a0En el traceroute salen asteriscos\u2026 GRAVE!!<\/li>\n<\/ol>\n<p><strong>Soluci\u00f3n.<\/strong><\/p>\n<p>VRF en Linux ya lleva un tiempo algo estable y gracias al trabajo mayormente realizado por Cumulus Network esto ha mejorado bastante. Esta funcionalidad esta lista para ser usada en las distribuciones recientes de Linux, en mi caso he usado Ubuntu y Debian.<\/p>\n<p>Procedemos a inicializar un VRF con el comando:<\/p>\n<pre>ip link add name vrf_mesh type vrf table 10<\/pre>\n<p>Activamos el VRF:<\/p>\n<pre>ip link set dev vrf_mesh up<\/pre>\n<p>Ya contamos con un VRF e incluso tenemos una interface disponible para asignar un IP, esta interface es utilizada cuando queremos hacer route leaking de un VRF a otro.<\/p>\n<pre>Si hacemos: ip vrf show<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"368\" height=\"120\" class=\"wp-image-3053\" src=\"https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-15.png\" srcset=\"https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-15.png 368w, https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-15-300x98.png 300w\" sizes=\"auto, (max-width: 368px) 100vw, 368px\" \/><\/p>\n<pre>Para tener consistencia con relaci\u00f3n al VRF y las tablas de enrutamiento de Linux, debemos definir una entrada en \/etc\/iproute2\/rt_tables<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"263\" height=\"250\" class=\"wp-image-3054\" src=\"https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-16.png\" \/><\/p>\n<p>Hasta este punto se podr\u00eda decir que todo es igual a PBR, la diferencia est\u00e1 en los pr\u00f3ximos pasos donde movemos interfaces hacia el VRF, este proceso autom\u00e1ticamente asigna todas las rutas existentes al VRF, incluso la direcci\u00f3n IP deja de estar disponible en la tabla main, si existen servicios que usan estas IP directamente, fallaran ya que la IP no est\u00e1 disponible.<\/p>\n<pre>ip link set dev enp2s0 vrf vrf_mesh up<\/pre>\n<p>Lo revisamos con<\/p>\n<pre>ip -br link show type vrf<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"888\" height=\"115\" class=\"wp-image-3055\" src=\"https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-17.png\" srcset=\"https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-17.png 888w, https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-17-300x39.png 300w, https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-17-768x99.png 768w\" sizes=\"auto, (max-width: 888px) 100vw, 888px\" \/><\/p>\n<pre>ip link show<\/pre>\n<p>Nos mostrara todas las interfaces en el servidor, adem\u00e1s nos deja ver cuales est\u00e1n en un VRF<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1471\" height=\"354\" class=\"wp-image-3056\" src=\"https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-18.png\" srcset=\"https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-18.png 1471w, https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-18-300x72.png 300w, https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-18-1024x246.png 1024w, https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-18-768x185.png 768w\" sizes=\"auto, (max-width: 1471px) 100vw, 1471px\" \/><\/p>\n<pre><em>master vrf_mesh<\/em><\/pre>\n<p>Es lo que queremos ver!<\/p>\n<p>Un cambio realizado por esta configuraci\u00f3n est\u00e1 en las reglas que controlan donde se buscara el pr\u00f3ximo salto para alcanzar un host.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"696\" height=\"157\" class=\"wp-image-3057\" src=\"https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-19.png\" srcset=\"https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-19.png 696w, https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-19-300x68.png 300w\" sizes=\"auto, (max-width: 696px) 100vw, 696px\" \/><\/p>\n<p>L3mdev-table fue agregado cuando creamos nuestro VRF, la idea es primero buscar dentro de esta tabla dependiendo del estado de la interface, si esta es parte de un VRF o no. Otro cambio que se debe hacer y este es de forma manual, es mover el lookup local hacia abajo, esto evitara que se haga la b\u00fasqueda en la tabla main y posiblemente enviar el tr\u00e1fico a la tabla equivocada, es muy \u00fatil cuando se tienen varios VRF y prefijos duplicados.<\/p>\n<p><strong>Listo, ahora le toca a BIRD llevar sus rutas al VRF.<\/strong><\/p>\n<p>Esta configuraci\u00f3n fue la m\u00e1s complicada ya que el soporte de VRF en BIRD no est\u00e1 muy bien documentado y todo fue basado en prueba y error.<\/p>\n<p>Gran parte de la configuraci\u00f3n de BIRD ya ten\u00eda definida tablas de enrutamiento para funcionar con PBR, lo que hice fue cambiarlo todo a una misma tabla, en este caso la tabla 10.<\/p>\n<p>Algo que confunde un poco es que en BIRD se deben definir tabla para IPv4 e IPv6 pero no pueden tener el mismo nombre, es algo interno de BIRD y no refleja que en el Kernel podemos tener rutas de IPv4 e IPv6 en la misma tabla.<\/p>\n<p>El cambio es simple. Luego que se entiende que se debe hacer, debemos agregar vrf \u201cnombre_vrf\u201d en todas las entradas de protocol que queremos que participen del VRF, dentro de cada versi\u00f3n de IP se debe agregar la tabla donde se colocaran las rutas aprendidas, esa es la raz\u00f3n por la que se definen dos tablas en la configuraci\u00f3n. Otro proceso adicional es usar el protocol kernel para copiar las rutas que se agregaron a las tablas internas de BIRD a la tabla 10 del kernel, esa es la tabla que en mi caso usa el VRF.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1041\" height=\"470\" class=\"wp-image-3058\" src=\"https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-20.png\" srcset=\"https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-20.png 1041w, https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-20-300x135.png 300w, https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-20-1024x462.png 1024w, https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-20-768x347.png 768w\" sizes=\"auto, (max-width: 1041px) 100vw, 1041px\" \/><\/p>\n<p>Una de las limitantes de BIRD y VRF es que BIRD desconoce que existe un VRF en Linux y no tienen integraci\u00f3n. Se dice que en nuevas versiones esto mejorara.<\/p>\n<p>Ya tengo rutas en mi VRF, cual es la diferencia?<\/p>\n<p>Anteriormente no pod\u00eda hacer tareas tales como ping o traceroute desde las direcciones IP que usando rules estaban dentro de una de las tablas de enrutamiento. Con VRF es mucho m\u00e1s sencillo.<\/p>\n<pre>ip vrf exec vrf_mesh traceroute 1.1.1.1<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"907\" height=\"220\" class=\"wp-image-3059\" src=\"https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-21.png\" srcset=\"https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-21.png 907w, https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-21-300x73.png 300w, https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-21-768x186.png 768w\" sizes=\"auto, (max-width: 907px) 100vw, 907px\" \/><\/p>\n<p>En la tabla main del equipo solo se puede observar la ruta por defecto que es usada para subir los t\u00faneles wireguard.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"712\" height=\"101\" class=\"wp-image-3060\" src=\"https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-22.png\" srcset=\"https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-22.png 712w, https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-22-300x43.png 300w\" sizes=\"auto, (max-width: 712px) 100vw, 712px\" \/><\/p>\n<p>Si consulto la tabla 10 donde est\u00e1 funcionando el VRF.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"913\" height=\"299\" class=\"wp-image-3061\" src=\"https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-23.png\" srcset=\"https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-23.png 913w, https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-23-300x98.png 300w, https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-23-768x252.png 768w\" sizes=\"auto, (max-width: 913px) 100vw, 913px\" \/><\/p>\n<p>Demasiadas rutas para mostrar en un screenshot, vamos a contarlas.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"753\" height=\"138\" class=\"wp-image-3062\" src=\"https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-24.png\" srcset=\"https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-24.png 753w, https:\/\/arielantigua.com\/weblog\/wp-content\/uploads\/2021\/01\/word-image-24-300x55.png 300w\" sizes=\"auto, (max-width: 753px) 100vw, 753px\" \/><\/p>\n<p>Al final todo esto es para que mis VM\/contenedores con direcciones ip publicas puedan llegar a Internet y ser alcanzados desde Internet.<\/p>\n<p>referencias:<\/p>\n<p><a href=\"https:\/\/stbuehler.de\/blog\/article\/2020\/02\/29\/using_vrf__virtual_routing_and_forwarding__on_linux.html\">Stefan&#8217;s Blog &#8211; Using VRF (Virtual Routing and Forwarding) on Linux<\/a><\/p>\n<p><a href=\"https:\/\/github.com\/Mellanox\/mlxsw\/wiki\/Virtual-Routing-and-Forwarding-(VRF)\">Virtual Routing and Forwarding (VRF) \u00b7 Mellanox\/mlxsw Wiki \u00b7 GitHub<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>VRF en Linux con BIRD para OSPF\/BGP. Desde hace mucho tiempo estoy jugando con BGP, inicialmente ten\u00eda BGP en pfSense, algo sencillo y con solo algunas rutas, eso fue en los tiempos de dn42. En el 2016 encontr\u00e9 una comunidad de varios entusiastas de redes al nivel de Internet y pude conseguir un ASN registrado [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[123,24,7,33,34,124],"tags":[142,138],"class_list":["post-3052","post","type-post","status-publish","format-standard","hentry","category-bgp","category-debian","category-general","category-ipv6","category-networking","category-ubuntu","tag-bgp","tag-ipv6"],"_links":{"self":[{"href":"https:\/\/arielantigua.com\/weblog\/wp-json\/wp\/v2\/posts\/3052","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/arielantigua.com\/weblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/arielantigua.com\/weblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/arielantigua.com\/weblog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/arielantigua.com\/weblog\/wp-json\/wp\/v2\/comments?post=3052"}],"version-history":[{"count":0,"href":"https:\/\/arielantigua.com\/weblog\/wp-json\/wp\/v2\/posts\/3052\/revisions"}],"wp:attachment":[{"href":"https:\/\/arielantigua.com\/weblog\/wp-json\/wp\/v2\/media?parent=3052"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/arielantigua.com\/weblog\/wp-json\/wp\/v2\/categories?post=3052"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/arielantigua.com\/weblog\/wp-json\/wp\/v2\/tags?post=3052"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}