Filtrado de rutas BGP: Prefix Lists, Filtros AS-Path, Rechazo de Bogons y GTSM
Referencia práctica para endurecer sesiones BGP en Linux con filtros por capas. Cubre prefix-lists, rechazo de bogons, filtrado AS-path, límites max-prefix y GTSM en sintaxis de BIRD2 y FRR con pasos de verificación.
RPKI valida que un AS está autorizado a originar un prefijo. No protege contra route leaks, inyección de bogons, explosión de tabla por un peer mal configurado, ni paquetes BGP falsificados desde hosts no adyacentes. Este artículo cubre los filtros que gestionan todo lo que RPKI no hace.
Cada filtro se muestra en sintaxis de BIRD2 y FRR, con ejemplos IPv4 e IPv6. Cada sección explica qué previene el filtro, da la configuración y muestra cómo verificar que funciona.
Si todavía no has configurado la validación de origen RPKI, hazlo primero. Ver RPKI ROA Setup for BGP.
Para la configuración básica de sesiones BGP, ver BIRD2 BGP Configuration on Linux (BIRD2) o FRR BGP Configuration on Linux (FRR). Este artículo asume que ya tienes una sesión BGP funcionando y quieres endurecerla.
¿Por qué BGP necesita filtrado de rutas más allá de RPKI?
El filtrado de rutas BGP es la práctica de aceptar o rechazar anuncios BGP basándose en prefijo, AS-path o atributos de origen. Previene route leaks, hijacks de prefijos, inyección de bogons y explosión de la tabla de enrutamiento. RPKI cubre solo la validación de origen. Sin filtros adicionales, tu router queda expuesto a todas las demás categorías de incidentes BGP.
Esto es lo que previene cada capa:
| Tipo de filtro | Amenaza bloqueada | Qué ocurre sin él |
|---|---|---|
| Rechazo de prefijos bogon | Espacio privado/reservado en DFZ | Tu router reenviará tráfico a espacio RFC 1918. Black hole. |
| Rechazo de prefijos pequeños | Hijacks más específicos (/25+, /49+) | Un atacante anuncia un /32 cubriendo parte de un /24 que aceptas. Su ruta gana por longest match. |
| Filtrado de ASNs bogon en AS-path | ASNs privados/reservados en paths | Rutas con AS 65535 o AS 4200000000 se filtran en tu tabla. Reenvías tráfico basado en paths inválidos. |
| Límite de longitud de AS-path | Ataques de inflación de path, bloat de tabla | Un peer envía rutas con más de 50 hops de AS. Tu memoria se llena de entradas inútiles. |
| Límite max-prefix | Route leaks, sobrecarga de sesión | Un peer filtra una tabla completa (más de 1M prefijos) en tu sesión. Tu router se queda sin memoria. |
| GTSM (seguridad TTL) | Paquetes BGP falsificados desde hosts remotos | Un atacante a varios hops de distancia inyecta paquetes BGP OPEN o UPDATE en tu sesión. |
| Validación de origen RPKI | Hijacks de origen | Alguien origina tu prefijo desde su AS. Ya cubierto en RPKI ROA Setup for BGP. |
Los incidentes reales muestran por qué importa cada capa. En 2008, Pakistan Telecom anunció rutas más específicas para los prefijos de YouTube con el fin de implementar una orden de censura doméstica. Esas rutas se filtraron a proveedores de tránsito internacionales y bloquearon YouTube globalmente durante horas. Un filtro de bogons o prefijos pequeños en los proveedores de tránsito habría descartado esos anuncios. En junio de 2019, un pequeño ISP en Pennsylvania (AS396531) filtró accidentalmente rutas de Cloudflare, Amazon y Linode a Verizon, que las propagó globalmente. Un límite max-prefix habría cerrado la sesión antes de que el leak se propagara.
¿Cómo filtrar prefijos bogon en BIRD2 y FRR?
Los prefijos bogon son rangos de direcciones que nunca deben aparecer en la tabla de enrutamiento global. Incluyen espacio privado RFC 1918, direcciones link-local, rangos de documentación y bloques reservados. Aceptarlos significa que tu router intentará reenviar tráfico a direcciones que no tienen un destino global legítimo, creando black holes.
Prefijos bogon IPv4
| Prefijo | Referencia | Propósito |
|---|---|---|
| 0.0.0.0/8 | RFC 1122 | Red "This" |
| 10.0.0.0/8 | RFC 1918 | Espacio privado |
| 100.64.0.0/10 | RFC 6598 | NAT de grado operador |
| 127.0.0.0/8 | RFC 1122 | Loopback |
| 169.254.0.0/16 | RFC 3927 | Link-local |
| 172.16.0.0/12 | RFC 1918 | Espacio privado |
| 192.0.2.0/24 | RFC 5737 | TEST-NET-1 |
| 192.88.99.0/24 | RFC 7526 | Relay 6to4 obsoleto |
| 192.168.0.0/16 | RFC 1918 | Espacio privado |
| 198.18.0.0/15 | RFC 2544 | Benchmarking |
| 198.51.100.0/24 | RFC 5737 | TEST-NET-2 |
| 203.0.113.0/24 | RFC 5737 | TEST-NET-3 |
| 224.0.0.0/4 | RFC 5771 | Multicast |
| 240.0.0.0/4 | RFC 1112 | Reservado para uso futuro |
Prefijos bogon IPv6
| Prefijo | Referencia | Propósito |
|---|---|---|
| ::/8 | Varios | Compatibles IPv4, loopback, mapped |
| 100::/64 | RFC 6666 | Discard-only |
| 2001:2::/48 | RFC 5180 | Benchmarking BMWG |
| 2001:10::/28 | RFC 4843 | ORCHID |
| 2001:db8::/32 | RFC 3849 | Documentación |
| 3fff::/20 | RFC 9637 | Documentación |
| 2002::/16 | RFC 7526 | 6to4 obsoleto |
| 3ffe::/16 | RFC 3701 | Antiguo 6bone |
| 5f00::/16 | RFC 9602 | SRv6 SIDs |
| fc00::/7 | RFC 4193 | Unicast local único |
| fe80::/10 | RFC 4291 | Unicast link-local |
| fec0::/10 | RFC 3879 | Site-local obsoleto |
| ff00::/8 | RFC 4291 | Multicast |
Estas listas cambian cuando IANA asigna nuevos bloques o depreca los antiguos. La referencia de bogons de Team Cymru proporciona un feed BGP de fullbogons (espacio no asignado + reservado) que se actualiza automáticamente. Para listas estáticas, consulta periódicamente la NLNOG BGP Filter Guide.
Filtro de bogons en BIRD2
# /etc/bird/bogons.conf - include this from your main bird.conf
define BOGON_PREFIXES_V4 = [
0.0.0.0/8+,
10.0.0.0/8+,
100.64.0.0/10+,
127.0.0.0/8+,
169.254.0.0/16+,
172.16.0.0/12+,
192.0.2.0/24+,
192.88.99.0/24+,
192.168.0.0/16+,
198.18.0.0/15+,
198.51.100.0/24+,
203.0.113.0/24+,
224.0.0.0/4+,
240.0.0.0/4+
];
define BOGON_PREFIXES_V6 = [
::/8+,
0100::/64+,
2001:2::/48+,
2001:10::/28+,
2001:db8::/32+,
3fff::/20+,
2002::/16+,
3ffe::/16+,
5f00::/16+,
fc00::/7+,
fe80::/10+,
fec0::/10+,
ff00::/8+
];
function reject_bogon_prefixes_v4() {
if (net ~ BOGON_PREFIXES_V4) then {
print "REJECTED bogon prefix: ", net, " path: ", bgp_path;
reject;
}
}
function reject_bogon_prefixes_v6() {
if (net ~ BOGON_PREFIXES_V6) then {
print "REJECTED bogon prefix: ", net, " path: ", bgp_path;
reject;
}
}
El + después de cada prefijo significa "este prefijo y todos los más específicos." 10.0.0.0/8+ coincide con 10.0.0.0/8, 10.0.0.0/9, 10.1.0.0/16, etc. Esto atrapa a un atacante que anuncia un /24 dentro del espacio RFC 1918.
Llama a estas funciones en tu filtro de importación:
filter import_from_upstream_v4 {
reject_bogon_prefixes_v4();
# ... other filters ...
accept;
}
protocol bgp upstream_v4 {
local as 64500;
neighbor 198.51.100.1 as 64501;
ipv4 {
import filter import_from_upstream_v4;
export none;
};
}
Filtro de bogons en FRR
! IPv4 bogon prefix-list
ip prefix-list BOGONS_v4 seq 10 deny 0.0.0.0/8 le 32
ip prefix-list BOGONS_v4 seq 20 deny 10.0.0.0/8 le 32
ip prefix-list BOGONS_v4 seq 30 deny 100.64.0.0/10 le 32
ip prefix-list BOGONS_v4 seq 40 deny 127.0.0.0/8 le 32
ip prefix-list BOGONS_v4 seq 50 deny 169.254.0.0/16 le 32
ip prefix-list BOGONS_v4 seq 60 deny 172.16.0.0/12 le 32
ip prefix-list BOGONS_v4 seq 70 deny 192.0.2.0/24 le 32
ip prefix-list BOGONS_v4 seq 80 deny 192.88.99.0/24 le 32
ip prefix-list BOGONS_v4 seq 90 deny 192.168.0.0/16 le 32
ip prefix-list BOGONS_v4 seq 100 deny 198.18.0.0/15 le 32
ip prefix-list BOGONS_v4 seq 110 deny 198.51.100.0/24 le 32
ip prefix-list BOGONS_v4 seq 120 deny 203.0.113.0/24 le 32
ip prefix-list BOGONS_v4 seq 130 deny 224.0.0.0/4 le 32
ip prefix-list BOGONS_v4 seq 140 deny 240.0.0.0/4 le 32
ip prefix-list BOGONS_v4 seq 999 permit 0.0.0.0/0 le 32
! IPv6 bogon prefix-list
ipv6 prefix-list BOGONS_v6 seq 10 deny ::/8 le 128
ipv6 prefix-list BOGONS_v6 seq 20 deny 100::/64 le 128
ipv6 prefix-list BOGONS_v6 seq 30 deny 2001:2::/48 le 128
ipv6 prefix-list BOGONS_v6 seq 40 deny 2001:10::/28 le 128
ipv6 prefix-list BOGONS_v6 seq 50 deny 2001:db8::/32 le 128
ipv6 prefix-list BOGONS_v6 seq 60 deny 3fff::/20 le 128
ipv6 prefix-list BOGONS_v6 seq 70 deny 2002::/16 le 128
ipv6 prefix-list BOGONS_v6 seq 80 deny 3ffe::/16 le 128
ipv6 prefix-list BOGONS_v6 seq 90 deny 5f00::/16 le 128
ipv6 prefix-list BOGONS_v6 seq 100 deny fc00::/7 le 128
ipv6 prefix-list BOGONS_v6 seq 110 deny fe80::/10 le 128
ipv6 prefix-list BOGONS_v6 seq 120 deny fec0::/10 le 128
ipv6 prefix-list BOGONS_v6 seq 130 deny ff00::/8 le 128
ipv6 prefix-list BOGONS_v6 seq 999 permit ::/0 le 128
Las cláusulas le 32 (IPv4) y le 128 (IPv6) coinciden con el prefijo y todos los más específicos, igual que el operador + en BIRD2. La línea final permit en seq 999 permite todo lo que no fue denegado antes.
Aplica la prefix-list a tu neighbor:
router bgp 64500
neighbor 198.51.100.1 remote-as 64501
address-family ipv4 unicast
neighbor 198.51.100.1 prefix-list BOGONS_v4 in
address-family ipv6 unicast
neighbor 2001:db8::1 prefix-list BOGONS_v6 in
Atención. Esa entrada 2001:db8::/32 está en la lista de bogons. No uses direcciones de documentación en producción. Reemplaza las direcciones de neighbor anteriores con las IPs reales de tus peers.
Rechazar prefijos demasiado pequeños
Las rutas más pequeñas que /24 (IPv4) o /48 (IPv6) no se propagarán de forma fiable en el DFZ global. Más importante: aceptarlas te expone a ataques de hijack más específicos. Fíltralas en inbound.
BIRD2:
function reject_small_prefixes_v4() {
if (net.len > 24) then {
print "REJECTED too-small prefix: ", net, " path: ", bgp_path;
reject;
}
}
function reject_small_prefixes_v6() {
if (net.len > 48) then {
print "REJECTED too-small prefix: ", net, " path: ", bgp_path;
reject;
}
}
FRR:
! Add to the same prefix-lists, before the final permit
ip prefix-list BOGONS_v4 seq 150 deny 0.0.0.0/0 ge 25 le 32
ipv6 prefix-list BOGONS_v6 seq 140 deny ::/0 ge 49 le 128
Esto atrapa cualquier prefijo más específico que /24 (IPv4) o /48 (IPv6). Coloca estas líneas antes de las entradas seq 999 permit.
¿Cómo previenen los filtros AS-path los route leaks?
Los filtros AS-path inspeccionan la secuencia de sistemas autónomos que ha recorrido una ruta. Detectan tres problemas: ASNs bogon que nunca deben aparecer en un path, paths excesivamente largos que indican leaks o manipulación, y ASNs privados que no fueron eliminados antes del anuncio.
Filtrado de ASNs bogon
Los ASNs bogon son números reservados que nunca deben aparecer en un path BGP en la internet pública:
| Rango ASN | Referencia | Propósito |
|---|---|---|
| 0 | RFC 7607 | Reservado |
| 23456 | RFC 4893 | AS_TRANS (transición AS de 4 bytes) |
| 64496-64511 | RFC 5398 | Documentación/ejemplos |
| 64512-65534 | RFC 6996 | Uso privado (16-bit) |
| 65535 | RFC 7300 | Último ASN de 16-bit |
| 65536-65551 | RFC 5398 | Documentación/ejemplos (32-bit) |
| 65552-131071 | IANA | Reservado |
| 4200000000-4294967294 | RFC 6996 | Uso privado (32-bit) |
| 4294967295 | RFC 7300 | Último ASN de 32-bit |
BIRD2:
define BOGON_ASNS = [
0,
23456,
64496..64511,
64512..65534,
65535,
65536..65551,
65552..131071,
4200000000..4294967294,
4294967295
];
function reject_bogon_asns()
int set bogon_asns;
{
bogon_asns = BOGON_ASNS;
if (bgp_path ~ bogon_asns) then {
print "REJECTED bogon ASN in path: ", net, " path: ", bgp_path;
reject;
}
}
El operador bgp_path ~ bogon_asns comprueba si algún ASN del path es miembro del conjunto. Un único ASN bogon en cualquier punto del path activa el rechazo.
FRR:
bgp as-path access-list BOGON_ASNS deny _0_
bgp as-path access-list BOGON_ASNS deny _23456_
bgp as-path access-list BOGON_ASNS deny _6449[6-9]_
bgp as-path access-list BOGON_ASNS deny _6450[0-9]_
bgp as-path access-list BOGON_ASNS deny _6451[01]_
bgp as-path access-list BOGON_ASNS deny _64[5-9][1-9][2-9]_
bgp as-path access-list BOGON_ASNS deny _6[5-9][0-9][0-9][0-9]_
bgp as-path access-list BOGON_ASNS deny _[1-9][0-9][0-9][0-9][0-9]_
bgp as-path access-list BOGON_ASNS deny _[1-3][0-9][0-9][0-9][0-9][0-9]_
bgp as-path access-list BOGON_ASNS permit .*
FRR usa coincidencia regex en la cadena AS-path. Los guiones bajos _ coinciden con los delimitadores del AS-path (espacio, inicio, fin). Este enfoque de regex es menos preciso que la coincidencia por conjunto de enteros de BIRD2. Para un enfoque más simple pero menos granular, usa un route-map con la as-path access-list:
route-map IMPORT_FILTER deny 10
match as-path BOGON_ASNS
route-map IMPORT_FILTER permit 100
router bgp 64500
address-family ipv4 unicast
neighbor 198.51.100.1 route-map IMPORT_FILTER in
Nota: los patrones regex anteriores están simplificados. Hacer coincidir el rango completo de ASNs privados de 32-bit (4200000000-4294967294) con regex es propenso a errores. Para despliegues en producción, usa bgpq4 para generar prefix-lists y filtros AS-path a partir de datos IRR, lo que es más preciso y automatizable.
Limitar la longitud del AS-path
Un path BGP legítimo raramente supera los 10-15 ASNs. Los paths más largos suelen indicar un route leak, manipulación del path o prepending incorrecto. Establece un límite estricto.
BIRD2:
function reject_long_paths() {
if (bgp_path.len > 25) then {
print "REJECTED long AS-path (", bgp_path.len, "): ", net, " path: ", bgp_path;
reject;
}
}
FRR:
bgp as-path access-list LONG_PATHS deny ^([0-9]+_){25,}
bgp as-path access-list LONG_PATHS permit .*
route-map IMPORT_FILTER deny 20
match as-path LONG_PATHS
Un límite de 25 es conservador. La mayoría de rutas legítimas tienen paths por debajo de 10. Si recibes una tabla completa, inspecciona los paths más largos en tu RIB antes de elegir un umbral:
# BIRD2
birdc 'show route where bgp_path.len > 15' | head -20
# FRR
vtysh -c "show ip bgp regexp ^([0-9]+_){15,}"
Eliminar ASNs privados en outbound
Si usas iBGP con ASNs privados internamente, asegúrate de que no se filtren hacia tus upstreams.
BIRD2:
filter export_to_upstream_v4 {
# Strip private ASNs before advertising
bgp_path.delete([64512..65534, 4200000000..4294967294]);
# ... your export policy ...
accept;
}
FRR:
router bgp 64500
address-family ipv4 unicast
neighbor 198.51.100.1 remove-private-AS all
La palabra clave all elimina todos los ASNs privados aunque haya ASNs públicos en el path. Sin all, FRR solo elimina los ASNs privados cuando el path contiene exclusivamente ASNs privados.
¿Cuál es el límite max-prefix correcto para una sesión BGP?
Un límite max-prefix es una válvula de seguridad que cierra una sesión BGP si un peer anuncia más prefijos que el umbral configurado. Previene la explosión de la tabla de enrutamiento cuando un peer filtra accidentalmente una tabla completa o es comprometido. Sin él, un único peer mal configurado puede llevar a tu router a quedarse sin memoria.
Establece el límite según lo que esperas de cada peer:
| Tipo de peer | Prefijos esperados (IPv4) | Límite sugerido | Límite sugerido (IPv6) |
|---|---|---|---|
| Upstream tabla completa | ~1.200.000 (marzo 2026) | 1.500.000 | 300.000 |
| Tabla parcial / peer IXP | Variable | 1.5x recuento actual | 1.5x recuento actual |
| Cliente single-homed | 1-10 | 50 | 50 |
| Cliente multi-homed | 10-100 | 200 | 200 |
Consulta el tamaño actual de la tabla completa en bgp.potaroo.net antes de establecer límites para upstreams. Fija el límite en aproximadamente 1.2x el recuento esperado para absorber el crecimiento normal sin falsos disparos.
BIRD2:
protocol bgp upstream_v4 {
local as 64500;
neighbor 198.51.100.1 as 64501;
ipv4 {
import limit 1500000 action restart;
import filter import_from_upstream_v4;
export none;
};
}
protocol bgp customer_v4 {
local as 64500;
neighbor 203.0.113.10 as 64502;
ipv4 {
import limit 50 action disable;
import filter import_from_customer_v4;
export filter export_to_customer_v4;
};
}
BIRD2 ofrece tres acciones cuando se alcanza el límite:
action restart- cierra la sesión y la reinicia tras un retardo. Lo mejor para upstreams.action disable- cierra y deshabilita el protocolo. Requierebirdc enablemanual para restaurar. Lo mejor para clientes donde un límite alcanzado significa algo gravemente incorrecto.action block- deja de importar nuevas rutas pero mantiene la sesión activa. Útil si quieres conservar las rutas existentes mientras investigas.
FRR:
router bgp 64500
neighbor 198.51.100.1 remote-as 64501
address-family ipv4 unicast
neighbor 198.51.100.1 maximum-prefix 1500000 90 restart 5
neighbor 203.0.113.10 remote-as 64502
address-family ipv4 unicast
neighbor 203.0.113.10 maximum-prefix 50 80
En FRR, maximum-prefix 1500000 90 restart 5 significa: avisar al 90% (1.350.000 prefijos), cerrar al llegar a 1.500.000 y reiniciar la sesión tras 5 minutos. Sin la palabra clave restart, FRR cierra la sesión y requiere un clear bgp neighbor manual para restaurarla.
Verificar la configuración de max-prefix
# BIRD2 - check current prefix count and limit
birdc show protocols all upstream_v4 | grep -E "Routes|Limit"
# FRR - check prefix count per neighbor
vtysh -c "show ip bgp summary"
La salida muestra el recuento actual de prefijos junto al límite configurado. Si el recuento está cerca del límite, aumenta el umbral antes de que se dispare.
¿Cómo protege GTSM las sesiones BGP de paquetes falsificados?
GTSM (Generalized TTL Security Mechanism, RFC 5082) restringe los paquetes BGP aceptados a peers directamente conectados comprobando el campo TTL/Hop Limit. Cuando está habilitado, los paquetes BGP se envían con TTL 255. El receptor descarta cualquier paquete BGP con un TTL inferior a 254 (para un peer directamente conectado). Como los routers decrementan el TTL en cada hop, un atacante a más de un hop de distancia no puede enviar paquetes que lleguen con TTL 255.
Esto bloquea la inyección remota de TCP RST, floods SYN dirigidos al puerto BGP 179 y paquetes BGP OPEN/UPDATE elaborados desde atacantes no adyacentes. GTSM es mutuamente excluyente con eBGP multihop en la misma sesión. Ambos peers deben habilitarlo.
BIRD2:
protocol bgp upstream_v4 {
local as 64500;
neighbor 198.51.100.1 as 64501;
ttl security yes;
ipv4 {
import limit 1500000 action restart;
import filter import_from_upstream_v4;
export none;
};
}
FRR:
router bgp 64500
neighbor 198.51.100.1 remote-as 64501
neighbor 198.51.100.1 ttl-security hops 1
hops 1 significa que el peer debe estar exactamente a 1 hop de distancia (directamente conectado). Ajústalo para que coincida con el número real de hops. Para peers eBGP a través de un fabric de switching IXP, hops 1 es correcto. Para sesiones multihop (por ejemplo, BGP sobre un túnel GRE), no puedes usar GTSM. Usa autenticación MD5 en su lugar:
Alternativa MD5 en BIRD2:
protocol bgp multihop_peer {
local as 64500;
neighbor 198.51.100.5 as 64503;
multihop 2;
password "your-md5-secret";
# ...
}
Alternativa MD5 en FRR:
router bgp 64500
neighbor 198.51.100.5 remote-as 64503
neighbor 198.51.100.5 ebgp-multihop 2
neighbor 198.51.100.5 password your-md5-secret
Guarda la contraseña MD5 en un archivo con permisos restringidos (chmod 600) en lugar de en la configuración principal. Para FRR, referenciarla desde /etc/frr/frr.conf, que ya debería ser 640 con propietario frr:frr. Para BIRD2, mantener /etc/bird/bird.conf en 640 con propietario bird:bird.
¿Qué filtros BGP requiere MANRS?
MANRS (Mutually Agreed Norms for Routing Security) define acciones de referencia para operadores de red. Las acciones 1, 3 y 4 son requeridas para convertirse en participante de MANRS. Aquí se explica cómo los filtros de este artículo corresponden a las acciones de MANRS.
Acción 1: Prevenir la propagación de información de enrutamiento incorrecta.
Esta es la acción de filtrado principal. Requiere filtros explícitos a nivel de prefijo en conexiones de clientes y recomienda filtros AS-path para prevenir route leaks.
| Filtro de este artículo | Cobertura de MANRS Acción 1 |
|---|---|
| Filtrado por prefix-list (bogons) | Previene la publicación/aceptación de espacio reservado |
| Rechazo de prefijos pequeños | Bloquea rutas más específicas que indican hijacks |
| Filtrado de ASNs bogon en AS-path | Rechaza rutas con ASNs privados/reservados |
| Límites max-prefix | Detiene la propagación de tablas completas filtradas |
| Filtros de prefijos de cliente | No incluidos en este artículo. Constrúyelos por cliente desde IRR usando bgpq4. |
Acción 2 (recomendada): Prevenir tráfico con direcciones de origen falsificadas.
No es un filtro BGP. Es la validación de direcciones de origen BCP 38/84 (uRPF). Fuera del alcance de este artículo, pero igualmente importante.
Acción 3: Facilitar la comunicación operativa global.
Mantener la información de contacto actualizada en PeeringDB y en la base de datos de tu RIR. No es un filtro, pero los operadores que aplican filtros correctos también tienden a mantener su información de contacto.
Acción 4: Facilitar la información de enrutamiento a escala global.
Publicar la política de enrutamiento en IRR (RIPE, RADB) usando objetos RPSL. Crear ROAs para RPKI. Esto permite a tus peers construir filtros de prefijos precisos para tus anuncios.
La combinación de filtrado de bogons (prefijos + ASNs) + rechazo de prefijos pequeños + límites max-prefix + prefix-lists de clientes cubre la Acción 1 de MANRS. Añade RPKI (RPKI ROA Setup for BGP) y registro IRR para la Acción 4.
Uniendo todo: un filtro de importación completo
Aquí hay un filtro de importación combinado usando todas las técnicas anteriores.
Filtro de importación completo en BIRD2
# /etc/bird/filters.conf
include "/etc/bird/bogons.conf"; # BOGON_PREFIXES_V4, BOGON_PREFIXES_V6, BOGON_ASNS
function import_checks_v4() {
# 1. Reject bogon prefixes
if (net ~ BOGON_PREFIXES_V4) then {
print "REJECT bogon prefix: ", net, " ", bgp_path;
reject;
}
# 2. Reject too-small prefixes
if (net.len > 24) then {
print "REJECT small prefix: ", net, " ", bgp_path;
reject;
}
# 3. Reject bogon ASNs in path
if (bgp_path ~ [0, 23456, 64496..64511, 64512..65534, 65535,
65536..65551, 65552..131071,
4200000000..4294967294, 4294967295]) then {
print "REJECT bogon ASN: ", net, " ", bgp_path;
reject;
}
# 4. Reject excessively long paths
if (bgp_path.len > 25) then {
print "REJECT long path: ", net, " ", bgp_path;
reject;
}
# 5. Reject RPKI invalid (if RPKI is configured)
if (roa_check(rpki4, net, bgp_path.last) = ROA_INVALID) then {
print "REJECT RPKI invalid: ", net, " ", bgp_path;
reject;
}
}
filter import_upstream_v4 {
import_checks_v4();
accept;
}
protocol bgp upstream_v4 {
local as 64500;
neighbor 198.51.100.1 as 64501;
ttl security yes;
ipv4 {
import limit 1500000 action restart;
import filter import_upstream_v4;
export none;
};
}
Filtro de importación completo en FRR
! /etc/frr/frr.conf
! --- Prefix lists (bogons + small prefix rejection) ---
ip prefix-list IMPORT_V4 seq 10 deny 0.0.0.0/8 le 32
ip prefix-list IMPORT_V4 seq 20 deny 10.0.0.0/8 le 32
ip prefix-list IMPORT_V4 seq 30 deny 100.64.0.0/10 le 32
ip prefix-list IMPORT_V4 seq 40 deny 127.0.0.0/8 le 32
ip prefix-list IMPORT_V4 seq 50 deny 169.254.0.0/16 le 32
ip prefix-list IMPORT_V4 seq 60 deny 172.16.0.0/12 le 32
ip prefix-list IMPORT_V4 seq 70 deny 192.0.2.0/24 le 32
ip prefix-list IMPORT_V4 seq 80 deny 192.88.99.0/24 le 32
ip prefix-list IMPORT_V4 seq 90 deny 192.168.0.0/16 le 32
ip prefix-list IMPORT_V4 seq 100 deny 198.18.0.0/15 le 32
ip prefix-list IMPORT_V4 seq 110 deny 198.51.100.0/24 le 32
ip prefix-list IMPORT_V4 seq 120 deny 203.0.113.0/24 le 32
ip prefix-list IMPORT_V4 seq 130 deny 224.0.0.0/4 le 32
ip prefix-list IMPORT_V4 seq 140 deny 240.0.0.0/4 le 32
ip prefix-list IMPORT_V4 seq 150 deny 0.0.0.0/0 ge 25 le 32
ip prefix-list IMPORT_V4 seq 999 permit 0.0.0.0/0 le 32
! --- AS-path filters (bogon ASNs + path length) ---
bgp as-path access-list BOGON_ASNS deny _0_
bgp as-path access-list BOGON_ASNS deny _23456_
bgp as-path access-list BOGON_ASNS deny _6449[6-9]_
bgp as-path access-list BOGON_ASNS deny _6450[0-9]_
bgp as-path access-list BOGON_ASNS deny _6451[01]_
bgp as-path access-list BOGON_ASNS permit .*
bgp as-path access-list LONG_PATHS deny ^([0-9]+_){25,}
bgp as-path access-list LONG_PATHS permit .*
! --- Route-map combining all checks ---
route-map IMPORT_UPSTREAM deny 10
match as-path BOGON_ASNS
route-map IMPORT_UPSTREAM deny 20
match as-path LONG_PATHS
route-map IMPORT_UPSTREAM permit 100
! --- BGP neighbor configuration ---
router bgp 64500
neighbor 198.51.100.1 remote-as 64501
neighbor 198.51.100.1 ttl-security hops 1
address-family ipv4 unicast
neighbor 198.51.100.1 prefix-list IMPORT_V4 in
neighbor 198.51.100.1 route-map IMPORT_UPSTREAM in
neighbor 198.51.100.1 maximum-prefix 1500000 90 restart 5
En FRR, se evalúan tanto la prefix-list como el route-map. La prefix-list se ejecuta primero y descarta prefijos bogon y pequeños. Las rutas que superan la prefix-list pasan al route-map, que comprueba los filtros AS-path. Ambos deben permitir la ruta para que sea aceptada.
¿Cómo verificar que los filtros de rutas BGP funcionan?
Los filtros solo son útiles si realmente rechazan lo que deben. Verifica después de cada cambio.
Verificación en BIRD2
# Check what routes were rejected (requires print statements in filters)
grep "REJECT" /var/log/bird.log | tail -20
# Show the routing table with filter details
birdc show route filtered
# Show routes from a specific protocol
birdc show route protocol upstream_v4
# Count accepted routes per protocol
birdc show protocols all upstream_v4 | grep "Routes:"
# Test a specific prefix against your import filter
birdc show route for 10.0.0.0/8 all
El comando show route filtered muestra las rutas que se recibieron pero fueron rechazadas por el filtro de importación. Si tu filtro de bogons funciona, debería ver cero prefijos bogon en la tabla aceptada y cualquier bogon recibido en la tabla filtrada.
Verificación en FRR
# Show accepted routes from a neighbor
vtysh -c "show ip bgp neighbors 198.51.100.1 received-routes"
# Show routes filtered by inbound policy
vtysh -c "show ip bgp neighbors 198.51.100.1 filtered-routes"
# Check the prefix count per neighbor
vtysh -c "show ip bgp summary"
# Test if a specific prefix is accepted
vtysh -c "show ip bgp 10.0.0.0/8"
# Check max-prefix status
vtysh -c "show ip bgp neighbors 198.51.100.1" | grep -A2 "Maximum prefix"
Para que received-routes y filtered-routes funcionen, debes habilitar soft-reconfiguration inbound en el neighbor:
router bgp 64500
address-family ipv4 unicast
neighbor 198.51.100.1 soft-reconfiguration inbound
Esto consume memoria extra (almacena todas las rutas recibidas antes de filtrar). En una sesión de tabla completa, es aproximadamente 2x la memoria para el RIB. En routers de producción con RAM limitada, úsalo selectivamente.
Verificación externa
Tus filtros protegen tu propio RIB. Para verificar lo que anuncias a otros, usa looking glasses externos:
- bgp.tools - busca tu ASN para ver qué prefijos estás anunciando globalmente
- RIPE RIS - servicio de información de enrutamiento BGP, muestra la visibilidad de rutas entre colectores
- Hurricane Electric BGP Toolkit - búsqueda de prefijos y ASN
Comprueba esto después de realizar cambios en los filtros para confirmar que no estás filtrando accidentalmente rutas legítimas ni filtrando rutas que no deberías estar anunciando.
Para monitoreo automatizado, ver .
Comparación de sintaxis BIRD2 vs FRR
Referencia rápida para traducir entre los dos daemons:
| Tipo de filtro | BIRD2 | FRR |
|---|---|---|
| Prefijo bogon | if (net ~ BOGON_PREFIXES) then reject |
ip prefix-list BOGONS deny 10.0.0.0/8 le 32 |
| Prefijo pequeño | if (net.len > 24) then reject |
ip prefix-list X deny 0.0.0.0/0 ge 25 le 32 |
| ASN bogon | if (bgp_path ~ [64512..65534]) then reject |
bgp as-path access-list X deny _64[5-9][1-9][2-9]_ |
| Longitud de path | if (bgp_path.len > 25) then reject |
bgp as-path access-list X deny ^([0-9]+_){25,} |
| Max-prefix | import limit 50 action disable |
neighbor X maximum-prefix 50 |
| GTSM | ttl security yes |
neighbor X ttl-security hops 1 |
| Autenticación MD5 | password "secret" |
neighbor X password secret |
| Eliminar AS privado | bgp_path.delete([64512..65534]) |
neighbor X remove-private-AS all |
| Aplicar filtro | import filter name |
neighbor X prefix-list/route-map name in |
BIRD2 usa una única función de filtro que combina todas las comprobaciones. FRR divide las comprobaciones entre prefix-lists (coincidencia de prefijos), as-path access-lists (coincidencia de paths) y route-maps (combinando múltiples condiciones de coincidencia). Ambos enfoques funcionan. El enfoque de BIRD2 es más legible para políticas complejas. El enfoque de FRR es más familiar para operadores de Cisco.
¿Algo fue mal?
Sesión cerrada por max-prefix: Comprueba journalctl -u bird o journalctl -u frr para el mensaje de límite alcanzado. Aumenta el límite si el peer creció legítimamente, o investiga si es un leak. En BIRD2, re-habilita con birdc enable upstream_v4. En FRR, limpia con vtysh -c "clear bgp 198.51.100.1".
Rutas legítimas siendo filtradas: Comprueba birdc show route filtered o vtysh -c "show ip bgp neighbors X filtered-routes" para ver qué se descartó. Causa común: tu lista de bogons es demasiado agresiva, o tu umbral de prefijos pequeños está rechazando /25s legítimos de un cliente. Ajusta el filtro y recarga: birdc configure o vtysh -c "write memory" luego systemctl reload frr.
GTSM rechazando un peer válido: Ambos lados deben habilitar GTSM. Si un lado lo tiene activado y el otro no, los paquetes llegan con TTL 1 y son descartados por el lado con GTSM habilitado. Comprueba con tcpdump -i eth0 port 179 -v y observa el valor TTL.
Los filtros no tienen efecto después de un cambio: En BIRD2, ejecuta birdc configure para recargar. En FRR, si cambias una prefix-list o route-map, activa un soft reset: vtysh -c "clear bgp 198.51.100.1 in". Sin esto, las rutas existentes en el RIB no se re-evalúan contra el nuevo filtro.
Logs: Ambos daemons registran por defecto a través del journal de systemd.
# BIRD2
journalctl -u bird -f
# FRR
journalctl -u frr -f
Las instrucciones print en las funciones de filtro de BIRD2 escriben en el log de bird. En FRR, habilita el logging de debug con debug bgp updates en vtysh para depuración temporal. Deshabilítalo cuando termines porque genera grandes cantidades de salida de log.
Este artículo es parte de la serie BGP Bring Your Own IP on a VPS.
Copyright 2026 Virtua.Cloud. Todos los derechos reservados. Este contenido es una obra original del equipo de Virtua.Cloud. La reproducción, republicación o redistribución sin permiso escrito está prohibida.
¿Listo para probarlo?
Despliega tu propio servidor en segundos. Linux, Windows o FreeBSD.
Ver planes VPS