FRRouting (FRR) es la suite de enrutamiento dinámico de código abierto más usada en Linux: implementa BGP, OSPF, IS-IS y otros protocolos, y se gestiona con una shell (vtysh) muy parecida a la de los equipos de red tradicionales. En este tutorial instalarás FRR en Ubuntu 24.04, establecerás una sesión eBGP con un proveedor de tránsito, anunciarás tu propio prefijo y aplicarás filtros de entrada y salida. Al final añadirás un segundo proveedor para tener conectividad multihomed.

Requisitos previos

Para seguir esta guía necesitas:

  • Un servidor con Ubuntu 24.04 LTS y un usuario no root con privilegios sudo.
  • Un número de sistema autónomo (ASN) propio o asignado por tu proveedor, y un prefijo IP que tengas derecho a anunciar (con su objeto ROA/route registrado si vas a anunciarlo en Internet).
  • Los datos de la sesión que te facilita el proveedor: IP del vecino, su ASN y, si lo exige, la contraseña MD5.
  • Conocimientos básicos de direccionamiento IP y del funcionamiento de BGP.

En los ejemplos se usan valores de documentación que debes sustituir por los tuyos:

DatoValor de ejemplo
Tu ASN65001
Tu prefijo198.51.100.0/24
IP de tu servidor en el enlace203.0.113.2
Proveedor A (IP / ASN)203.0.113.1 / 65002
Proveedor B (IP / ASN)192.0.2.1 / 65003

Paso 1: Instalar FRRouting desde el repositorio oficial

Ubuntu incluye FRR en sus repositorios, pero el repositorio oficial del proyecto ofrece versiones estables más recientes. Descarga la clave de firma en /etc/apt/keyrings:

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://deb.frrouting.org/frr/keys.gpg | sudo tee /etc/apt/keyrings/frrouting.gpg > /dev/null

Añade el repositorio para tu versión de Ubuntu (noble en la 24.04):

echo "deb [signed-by=/etc/apt/keyrings/frrouting.gpg] https://deb.frrouting.org/frr $(lsb_release -sc) frr-stable" | sudo tee /etc/apt/sources.list.d/frr.list

Instala FRR junto con frr-pythontools, que aporta el script frr-reload.py usado para aplicar cambios sin reiniciar las sesiones:

sudo apt update
sudo apt install frr frr-pythontools

Comprueba la versión instalada:

sudo vtysh -c "show version"
FRRouting 10.x.y (your_hostname) on Linux(6.8.0-xx-generic).

Paso 2: Activar el daemon de BGP

FRR ejecuta un daemon por protocolo. zebra (que instala las rutas en el kernel) y staticd arrancan siempre, pero bgpd viene desactivado. Actívalo en /etc/frr/daemons:

sudo sed -i 's/^bgpd=no/bgpd=yes/' /etc/frr/daemons
grep ^bgpd /etc/frr/daemons
bgpd=yes

Reinicia el servicio para que arranque bgpd y verifica su estado:

sudo systemctl restart frr
systemctl status frr --no-pager

La salida debe mostrar active (running) y, en el árbol de procesos, bgpd, zebra y staticd.

Paso 3: Preparar el sistema

Si el servidor va a reenviar tráfico entre interfaces (por ejemplo, porque detrás hay otras máquinas que usan tu prefijo), activa el reenvío IP de forma persistente:

echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/99-routing.conf
sudo sysctl --system
sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

BGP usa TCP en el puerto 179. Si tienes UFW activo, permite las conexiones solo desde la IP del vecino:

sudo ufw allow from 203.0.113.1 to any port 179 proto tcp

Paso 4: Crear la configuración de BGP

FRR guarda toda la configuración en un único archivo, /etc/frr/frr.conf. Editarlo directamente permite revisar la configuración completa y guardarla en control de versiones. Ábrelo:

sudo nano /etc/frr/frr.conf

Sustituye su contenido por la configuración base. Todavía no incluye filtros, así que el vecino aún no intercambiará rutas:

frr defaults traditional
hostname your_hostname
log syslog informational
service integrated-vtysh-config
!
ip route 198.51.100.0/24 blackhole
!
router bgp 65001
 bgp router-id 203.0.113.2
 neighbor 203.0.113.1 remote-as 65002
 neighbor 203.0.113.1 description Proveedor-A-AS65002
 neighbor 203.0.113.1 password your_bgp_password
 !
 address-family ipv4 unicast
  network 198.51.100.0/24
 exit-address-family
exit
!

Qué hace cada bloque:

  • ip route 198.51.100.0/24 blackhole crea una ruta estática hacia la nada para tu prefijo. FRR solo anuncia con network los prefijos que existen en la tabla de rutas, y esta ruta garantiza que el anuncio sea estable aunque las subredes internas cambien. El tráfico hacia direcciones más específicas que sí existan seguirá usando sus rutas.
  • bgp router-id identifica al router; lo habitual es usar una IP propia estable.
  • neighbor ... remote-as define el vecino eBGP. Elimina la línea password si tu proveedor no usa autenticación MD5.
  • network declara el prefijo que quieres anunciar.

Valida la sintaxis antes de aplicarla y recarga la configuración:

sudo /usr/lib/frr/frr-reload.py --test /etc/frr/frr.conf
sudo systemctl reload frr

Comprueba el estado de la sesión:

sudo vtysh -c "show bgp summary"
IPv4 Unicast Summary:
BGP router identifier 203.0.113.2, local AS number 65001 vrf-id 0
Neighbor        V         AS   MsgRcvd   MsgSent   TblVer  InQ OutQ  Up/Down State/PfxRcd   PfxSnt Desc
203.0.113.1     4      65002        12        10        0    0    0 00:01:32       (Policy) (Policy) Proveedor-A-AS65002

La sesión está establecida (hay tiempo en Up/Down), pero aparece (Policy): FRR aplica por defecto el RFC 8212, que impide recibir o enviar rutas a un vecino eBGP sin una política explícita. Es el comportamiento correcto; lo resolverás en el siguiente paso con filtros en lugar de desactivar la comprobación.

Paso 5: Filtrar rutas con prefix-lists y route-maps

Un filtro de salida garantiza que solo anuncias tus prefijos, y uno de entrada descarta rutas que nunca deberías aceptar de un proveedor: tu propio prefijo, redes privadas y prefijos demasiado específicos. Vuelve a abrir /etc/frr/frr.conf:

sudo nano /etc/frr/frr.conf

Añade las prefix-lists y route-maps antes del bloque router bgp, y enlázalas al vecino dentro de address-family ipv4 unicast. El archivo completo queda así:

frr defaults traditional
hostname your_hostname
log syslog informational
service integrated-vtysh-config
!
ip route 198.51.100.0/24 blackhole
!
ip prefix-list MIS-PREFIJOS seq 10 permit 198.51.100.0/24
!
ip prefix-list DESDE-PROVEEDOR seq 5 deny 198.51.100.0/24 le 32
ip prefix-list DESDE-PROVEEDOR seq 10 deny 10.0.0.0/8 le 32
ip prefix-list DESDE-PROVEEDOR seq 15 deny 100.64.0.0/10 le 32
ip prefix-list DESDE-PROVEEDOR seq 20 deny 127.0.0.0/8 le 32
ip prefix-list DESDE-PROVEEDOR seq 25 deny 169.254.0.0/16 le 32
ip prefix-list DESDE-PROVEEDOR seq 30 deny 172.16.0.0/12 le 32
ip prefix-list DESDE-PROVEEDOR seq 35 deny 192.168.0.0/16 le 32
ip prefix-list DESDE-PROVEEDOR seq 40 deny 224.0.0.0/3 le 32
ip prefix-list DESDE-PROVEEDOR seq 100 permit 0.0.0.0/0 le 24
!
route-map PROVEEDOR-A-IN permit 10
 match ip address prefix-list DESDE-PROVEEDOR
 set local-preference 100
exit
!
route-map PROVEEDOR-A-OUT permit 10
 match ip address prefix-list MIS-PREFIJOS
exit
!
router bgp 65001
 bgp router-id 203.0.113.2
 neighbor 203.0.113.1 remote-as 65002
 neighbor 203.0.113.1 description Proveedor-A-AS65002
 neighbor 203.0.113.1 password your_bgp_password
 !
 address-family ipv4 unicast
  network 198.51.100.0/24
  neighbor 203.0.113.1 route-map PROVEEDOR-A-IN in
  neighbor 203.0.113.1 route-map PROVEEDOR-A-OUT out
  neighbor 203.0.113.1 maximum-prefix 1200000
 exit-address-family
exit
!

Puntos importantes de esta política:

  • Las prefix-lists terminan con un deny implícito, así que MIS-PREFIJOS solo deja salir tu /24 y DESDE-PROVEEDOR descarta todo lo que no case con alguna entrada permit.
  • permit 0.0.0.0/0 le 24 acepta la ruta por defecto y cualquier prefijo de longitud /24 o menor, que es lo que se propaga en la tabla global.
  • Un route-map también rechaza por defecto lo que no casa con ninguna entrada permit.
  • maximum-prefix corta la sesión si el vecino envía más rutas de las esperadas. Ajusta el valor: si tu proveedor solo te envía una ruta por defecto, usa un número bajo como 10.

Valida y aplica los cambios:

sudo /usr/lib/frr/frr-reload.py --test /etc/frr/frr.conf
sudo systemctl reload frr

Comprueba de nuevo el resumen. Ahora deben aparecer contadores en lugar de (Policy):

sudo vtysh -c "show bgp summary"
Neighbor        V         AS   MsgRcvd   MsgSent   TblVer  InQ OutQ  Up/Down State/PfxRcd   PfxSnt Desc
203.0.113.1     4      65002       530        15        0    0    0 00:04:10            1        1 Proveedor-A-AS65002

Verifica exactamente qué anuncias y qué aceptas del vecino:

sudo vtysh -c "show bgp ipv4 unicast neighbors 203.0.113.1 advertised-routes"
sudo vtysh -c "show bgp ipv4 unicast neighbors 203.0.113.1 routes"
   Network          Next Hop            Metric LocPrf Weight Path
*> 198.51.100.0/24  0.0.0.0                  0         32768 i

Total number of prefixes 1

La primera orden solo debe listar tu prefijo. Si aparece cualquier otra red, revisa el route-map de salida antes de continuar.

Paso 6: Añadir un segundo proveedor (multihoming)

Con dos proveedores, si uno cae el tráfico se mueve al otro. Es habitual preferir uno de ellos para el tráfico de entrada alargando artificialmente el AS path que ves a través del otro (AS path prepending), y marcar con local-preference el preferido para el tráfico de salida.

Abre de nuevo el archivo:

sudo nano /etc/frr/frr.conf

Añade los route-maps del proveedor B junto a los del proveedor A:

route-map PROVEEDOR-B-IN permit 10
 match ip address prefix-list DESDE-PROVEEDOR
 set local-preference 90
exit
!
route-map PROVEEDOR-B-OUT permit 10
 match ip address prefix-list MIS-PREFIJOS
 set as-path prepend 65001 65001
exit
!

Y añade el vecino dentro del bloque router bgp 65001, junto al primero:

 neighbor 192.0.2.1 remote-as 65003
 neighbor 192.0.2.1 description Proveedor-B-AS65003
 !
 address-family ipv4 unicast
  neighbor 192.0.2.1 route-map PROVEEDOR-B-IN in
  neighbor 192.0.2.1 route-map PROVEEDOR-B-OUT out
  neighbor 192.0.2.1 maximum-prefix 1200000
 exit-address-family

Con esta política, para el tráfico saliente prefieres las rutas del proveedor A (local-preference 100 frente a 90), y el resto de Internet ve tu prefijo con un AS path más largo a través de B, por lo que el tráfico entrante también llega preferentemente por A. Como DESDE-PROVEEDOR y MIS-PREFIJOS se aplican a los dos vecinos, nunca reanunciarás las rutas de un proveedor al otro.

Permite el puerto 179 para el nuevo vecino, valida y aplica:

sudo ufw allow from 192.0.2.1 to any port 179 proto tcp
sudo /usr/lib/frr/frr-reload.py --test /etc/frr/frr.conf
sudo systemctl reload frr

Comprueba que el anuncio hacia B lleva el prepend:

sudo vtysh -c "show bgp ipv4 unicast neighbors 192.0.2.1 advertised-routes"

La columna Path debe mostrar 65001 65001 i para tu prefijo (el tercer 65001 lo añade BGP al enviar la ruta).

Paso 7: Etiquetar anuncios con comunidades BGP

Las comunidades son etiquetas (ASN:valor) que viajan con la ruta. Muchos proveedores publican comunidades de acción que te permiten, por ejemplo, bajar la preferencia de tu prefijo en su red o no anunciarlo a ciertos peers. FRR envía comunidades estándar a todos los vecinos por defecto, así que basta con añadirlas en el route-map de salida.

Por ejemplo, si el proveedor B documenta que la comunidad 65003:70 baja la local-preference de la ruta en su red, añádela a su route-map de salida en /etc/frr/frr.conf:

route-map PROVEEDOR-B-OUT permit 10
 match ip address prefix-list MIS-PREFIJOS
 set as-path prepend 65001 65001
 set community 65003:70
exit

Aplica el cambio:

sudo /usr/lib/frr/frr-reload.py --test /etc/frr/frr.conf
sudo systemctl reload frr

La comunidad se añade al enviar la ruta, así que no aparece en tu tabla BGP local. Para confirmarla, consulta tu prefijo en el looking glass del proveedor B, donde verás 65003:70 entre las comunidades de la ruta. Las comunidades que recibes de tus proveedores sí las ves en local, consultando cualquier ruta aprendida:

sudo vtysh -c "show bgp ipv4 unicast 8.8.8.0/24"

La línea Community: de la salida muestra las etiquetas que ha puesto el proveedor, por ejemplo para indicar en qué punto de su red aprendió la ruta.

Solución de problemas

La sesión se queda en Active o Connect. El TCP al puerto 179 no se establece. Comprueba la conectividad con el vecino, el firewall y si llegan paquetes:

ping -c 3 203.0.113.1
sudo tcpdump -ni any host 203.0.113.1 and tcp port 179

Si ves SYN salientes sin respuesta, revisa con el proveedor que tiene configurado tu ASN y tu IP.

La sesión sube y cae continuamente. Mira el último error de la sesión y los logs:

sudo vtysh -c "show bgp neighbors 203.0.113.1" | grep -i -A2 "last reset"
sudo journalctl -u frr --since "15 min ago"

Errores frecuentes son un ASN incorrecto (Bad Peer AS), una contraseña MD5 que no coincide (en ese caso la sesión ni siquiera llega a abrirse y el kernel registra fallos de MD5) o que se ha superado maximum-prefix. Tras corregir un corte por maximum-prefix, reinicia la sesión con sudo vtysh -c "clear bgp 203.0.113.1".

Los cambios de política no se reflejan. FRR aplica los route-maps a las rutas nuevas. Para reevaluar las existentes sin cortar la sesión, usa un soft reset:

sudo vtysh -c "clear bgp ipv4 unicast 203.0.113.1 soft"

Tu prefijo no aparece en advertised-routes. Comprueba que la ruta blackhole está en la tabla (ip route show 198.51.100.0/24) y que el prefijo del network coincide exactamente con el de MIS-PREFIJOS.

Conclusión

Has instalado FRRouting en Ubuntu 24.04, establecido sesiones eBGP con dos proveedores, anunciado tu prefijo con filtros estrictos de entrada y salida y usado prepending, local-preference y comunidades para controlar el tráfico. Como siguientes pasos, añade la configuración equivalente para IPv6 (address-family ipv6 unicast con ipv6 prefix-list), activa la validación RPKI con el módulo bgpd_rpki y guarda /etc/frr/frr.conf en un repositorio para revisar cada cambio antes de aplicarlo.