BGP

BGP no Juniper Junos: policy-statement, prefix-list e communities

Fluxo de terms de uma policy-statement do Junos com rotas aceitas e rejeitadas

Configurar BGP no Juniper é fácil até a hora de filtrar. A sessão sobe com meia dúzia de linhas, mas sem policy o Junos aceita tudo que o vizinho manda e anuncia todas as rotas BGP ativas para todo mundo. Numa borda com dois trânsitos, isso significa virar trânsito de graça entre as duas operadoras na primeira sessão que subir.

Este post é o espelho, em Junos, do que eu mostrei em BGP communities no Huawei: prefix-list, filtros de import e export, communities para marcar a origem das rotas, local-preference e prepend. Ele é para quem tem borda mista, opera Huawei no dia a dia e de repente precisa mexer num MX. O cenário é de laboratório e a sintaxe segue o BGP User Guide e o Routing Policy User Guide da Juniper.

Resposta rápida: BGP no Juniper com policies

  1. Crie um group por tipo de vizinho (trânsito, cliente, IX) com type external e peer-as.
  2. Declare os objetos em policy-options: prefix-list para os seus blocos, community para marcar a origem das rotas.
  3. Escreva uma policy-statement de import e outra de export, com terms em ordem do mais específico para o mais genérico.
  4. Termine toda export com um term que faz reject. Sem ele, a policy default do BGP anuncia todas as rotas BGP ativas.
  5. Aplique com import e export no group ou no neighbor e confira com show route advertising-protocol bgp antes de dar o commit final.

Como o Junos avalia uma policy de BGP

Uma policy-statement é uma lista de terms. Cada term tem condições (from) e ações (then). O Junos testa os terms na ordem em que aparecem e para no primeiro que termina com accept ou reject. Ações que só modificam a rota, como local-preference ou community add, são aplicadas e a avaliação continua.

Dentro de um term, condições de tipos diferentes são E: from protocol static e from prefix-list NOSSOS no mesmo term exigem as duas. Várias linhas do mesmo tipo, como vários route-filter, funcionam como OU.

Se a rota passa por todos os terms e por todas as policies da cadeia sem decisão, vale a policy default do protocolo. Para o BGP no Juniper, a default aceita as rotas recebidas e anuncia as rotas BGP ativas. Por isso a export precisa terminar com um reject explícito.

Onde aplicar: global, group ou neighbor

Import e export podem ficar em protocols bgp, no group ou no neighbor. Vale só o nível mais específico: uma import no neighbor substitui a do group, que substitui a global. Elas não somam. Quem coloca uma policy no neighbor e esquece disso perde o filtro de bogons que estava no group.

Para quem vem do VRP, a tradução dos termos ajuda:

JunosHuawei VRPObservação
policy-statementroute-policyA policy inteira
termnodeAvaliados em ordem; o Junos usa nomes, o VRP números
fromif-matchCondições do term
thenapply + permit/denyAções e decisão final
prefix-list / route-filterip ip-prefixLista de prefixos; o route-filter traz o tipo de casamento na própria linha
community NOME membersip community-filterCommunities com nome
import / exportpeer X route-policy NOME import|exportOnde a policy entra

Cenário do laboratório de BGP no Juniper

Uma borda com dois trânsitos e um cliente BGP. O trânsito B é backup: queremos que o tráfego de entrada prefira o A. O cliente anuncia o próprio /24 e pode pedir para ser backup marcando uma community. IPs e ASNs são de documentação.

EquipamentoASPrefixosIP do vizinho
Borda (Junos)64500203.0.113.0/24–
Trânsito A64501Tabela completa192.0.2.2
Trânsito B (backup)64502Tabela completa192.0.2.6
Cliente BGP64510198.51.100.0/24192.0.2.10

Todos os blocos estão no formato set, para colar no modo de configuração. Se você ainda está se acostumando com a CLI, veja antes os comandos Junos básicos.

Grupos e vizinhos eBGP no Juniper

Primeiro o AS, o router-id e a rota estática do bloco próprio. A rota para discard garante que o /24 exista na tabela mesmo que nenhuma sub-rede interna esteja ativa, e é ela que a export vai anunciar:

set routing-options autonomous-system 64500
set routing-options router-id 192.0.2.1
set routing-options static route 203.0.113.0/24 discard

Depois os groups. No BGP no Juniper, o group junta vizinhos com a mesma política, e o peer-as pode ficar no group (os trânsitos, um por group) ou no neighbor (os clientes, vários no mesmo group):

set protocols bgp group TRANSITO-A type external
set protocols bgp group TRANSITO-A peer-as 64501
set protocols bgp group TRANSITO-A neighbor 192.0.2.2 description "transito A"
set protocols bgp group TRANSITO-B type external
set protocols bgp group TRANSITO-B peer-as 64502
set protocols bgp group TRANSITO-B neighbor 192.0.2.6 description "transito B"
set protocols bgp group CLIENTES type external
set protocols bgp group CLIENTES neighbor 192.0.2.10 peer-as 64510

Repare que ainda não há import nem export. Se você der commit agora, as sessões sobem e a borda passa a anunciar para cada trânsito tudo que aprendeu do outro. Monte as policies antes de configurar o neighbor, ou deixe as sessões desativadas até o fim.

prefix-list, route-filter e communities

Os objetos usados pelo BGP no Juniper ficam em policy-options. Uma prefix-list casa os prefixos exatos da lista. Para aceitar também os mais específicos, use prefix-list-filter com orlonger. As communities ganham nome, e é pelo nome que as policies se referem a elas:

set policy-options prefix-list NOSSOS 203.0.113.0/24
set policy-options prefix-list CLIENTE-64510 198.51.100.0/24
set policy-options community DE-TRANSITO members 64500:100
set policy-options community DE-CLIENTE members 64500:200
set policy-options community PEDE-BACKUP members 64500:80
set policy-options community TODAS members "*:*"

As três communities de valor seguem a ideia do post do Huawei: 64500:100 marca rota aprendida de trânsito, 64500:200 marca rota de cliente e 64500:80 é a que o cliente manda para pedir local-preference de backup. TODAS, com "*:*", casa qualquer community e serve para limpar o atributo antes de anunciar.

route-filter: o tipo de casamento faz a diferença

TipoCasa quando o prefixo da rota
exactTem o mesmo tamanho de máscara
orlongerTem máscara igual ou maior
longerTem máscara estritamente maior
upto /NTem máscara entre a configurada e /N
prefix-length-range /A-/BTem máscara entre /A e /B

Um detalhe que pega quem vem do VRP: num term com vários route-filter, o Junos primeiro escolhe o prefixo configurado mais longo que contém a rota e só depois testa o tipo. Se esse teste falhar, ele não volta para os prefixos mais curtos. Por isso o filtro de prefixos pequenos (/25 a /32) ficou num term separado do filtro de bogons: se alguém acrescentar depois um prefixo mais longo à lista de bogons, um /25 dentro dele deixaria de passar pelo teste de tamanho.

Policy de import do trânsito

A import do trânsito é a primeira defesa do BGP no Juniper: descarta lixo, protege os seus próprios prefixos e marca o resto:

set policy-options policy-statement TRANSITO-IN term BOGONS from route-filter 0.0.0.0/0 exact
set policy-options policy-statement TRANSITO-IN term BOGONS from route-filter 10.0.0.0/8 orlonger
set policy-options policy-statement TRANSITO-IN term BOGONS from route-filter 100.64.0.0/10 orlonger
set policy-options policy-statement TRANSITO-IN term BOGONS from route-filter 127.0.0.0/8 orlonger
set policy-options policy-statement TRANSITO-IN term BOGONS from route-filter 169.254.0.0/16 orlonger
set policy-options policy-statement TRANSITO-IN term BOGONS from route-filter 172.16.0.0/12 orlonger
set policy-options policy-statement TRANSITO-IN term BOGONS from route-filter 192.168.0.0/16 orlonger
set policy-options policy-statement TRANSITO-IN term BOGONS from route-filter 224.0.0.0/3 orlonger
set policy-options policy-statement TRANSITO-IN term BOGONS then reject
set policy-options policy-statement TRANSITO-IN term PEQUENOS from route-filter 0.0.0.0/0 prefix-length-range /25-/32
set policy-options policy-statement TRANSITO-IN term PEQUENOS then reject
set policy-options policy-statement TRANSITO-IN term NOSSOS from prefix-list-filter NOSSOS orlonger
set policy-options policy-statement TRANSITO-IN term NOSSOS then reject
set policy-options policy-statement TRANSITO-IN term ACEITA then local-preference 100
set policy-options policy-statement TRANSITO-IN term ACEITA then community add DE-TRANSITO
set policy-options policy-statement TRANSITO-IN term ACEITA then accept
  • BOGONS: rota default, faixas privadas, CGNAT, loopback, link-local e multicast. Nada disso deve vir de um trânsito.
  • PEQUENOS: qualquer prefixo de /25 a /32. Não entra na tabela global.
  • NOSSOS: o seu /24 ou um pedaço dele chegando de fora é sequestro ou vazamento. Rejeite.
  • ACEITA: o resto recebe local-preference 100, a community de trânsito e é aceito.

Esta é uma lista curta de bogons, boa para o laboratório. Em produção, gere a lista e os filtros de clientes a partir do IRR; o post sobre bgpq4 e IRR para gerar filtros automáticos mostra a saída do bgpq4 já no formato do Junos.

Policy de export: anuncie só o que é seu

A export para os trânsitos anuncia dois grupos de rotas: o bloco próprio, que vem da estática, e as rotas de clientes, reconhecidas pela community de cliente e pela prefix-list do cliente. Antes de sair, as communities internas são apagadas. Tudo o mais é rejeitado:

set policy-options policy-statement TRANSITO-OUT term NOSSOS from protocol static
set policy-options policy-statement TRANSITO-OUT term NOSSOS from prefix-list NOSSOS
set policy-options policy-statement TRANSITO-OUT term NOSSOS then accept
set policy-options policy-statement TRANSITO-OUT term CLIENTES from community DE-CLIENTE
set policy-options policy-statement TRANSITO-OUT term CLIENTES from prefix-list-filter CLIENTE-64510 exact
set policy-options policy-statement TRANSITO-OUT term CLIENTES then community delete TODAS
set policy-options policy-statement TRANSITO-OUT term CLIENTES then accept
set policy-options policy-statement TRANSITO-OUT term REJEITA then reject

O term REJEITA é o mais importante do post. Sem ele, a rota de trânsito que não casou com nenhum term cai na policy default do BGP no Juniper, que anuncia rotas BGP ativas. Resultado: a tabela do trânsito A sai pelo trânsito B.

Aplicando nos dois groups:

set protocols bgp group TRANSITO-A import TRANSITO-IN
set protocols bgp group TRANSITO-A export TRANSITO-OUT
set protocols bgp group TRANSITO-B import TRANSITO-IN
set protocols bgp group TRANSITO-B export [ PREPEND-2X TRANSITO-OUT ]

Proteção extra a partir do Junos 20.3

A partir do Junos 20.3R1 existe um filtro implícito para vizinho eBGP sem policy, na linha da RFC 8212. Ele vem desligado por padrão, para não mudar redes que já funcionam. Ligado com reject, o eBGP sem import não recebe e o eBGP sem export não anuncia rotas unicast:

set protocols bgp defaults ebgp no-policy receive reject
set protocols bgp defaults ebgp no-policy advertise reject
A documentação lista o defaults para algumas plataformas (ACX, JRR200, MX204, PTX5000 e vRR). Confira o suporte na sua versão antes de contar com ele. De qualquer forma, ele é rede de segurança: a policy explícita continua sendo a regra.

local-preference e as-path-prepend no BGP no Juniper

Para o tráfego de entrada preferir o trânsito A, o B anuncia o bloco com o AS repetido. Em vez de duplicar a export, criei uma policy pequena que só faz o prepend e passa adiante com next policy. No group do B, ela vem antes da export comum, na mesma cadeia (export [ PREPEND-2X TRANSITO-OUT ], do bloco anterior):

set policy-options policy-statement PREPEND-2X term SOMA then as-path-prepend "64500 64500"
set policy-options policy-statement PREPEND-2X term SOMA then next policy

A rota recebe o prepend em PREPEND-2X e segue para TRANSITO-OUT, que decide se ela sai. O que foi rejeitado ali não é anunciado, com ou sem prepend. O caminho visto de fora pelo B fica 64500 64500 64500, contra 64500 pelo A.

Cadeia de policies de import e export do BGP no Juniper
Import e export no Junos: os terms são avaliados em ordem; accept e reject encerram, next policy passa para a próxima policy da cadeia e, no fim, vale a policy default.

Cliente que pede backup por community

Do lado do cliente, a import aceita só o /24 dele. Se a rota vier com 64500:80, ganha local-preference 80 e vira caminho de backup dentro da sua rede. Sem a community, ganha 200, acima dos 100 do trânsito. As duas marcam a rota com 64500:200, que é o que a export do trânsito procura:

set policy-options policy-statement CLIENTE-64510-IN term BACKUP from prefix-list CLIENTE-64510
set policy-options policy-statement CLIENTE-64510-IN term BACKUP from community PEDE-BACKUP
set policy-options policy-statement CLIENTE-64510-IN term BACKUP then local-preference 80
set policy-options policy-statement CLIENTE-64510-IN term BACKUP then community add DE-CLIENTE
set policy-options policy-statement CLIENTE-64510-IN term BACKUP then accept
set policy-options policy-statement CLIENTE-64510-IN term ACEITA from prefix-list CLIENTE-64510
set policy-options policy-statement CLIENTE-64510-IN term ACEITA then local-preference 200
set policy-options policy-statement CLIENTE-64510-IN term ACEITA then community add DE-CLIENTE
set policy-options policy-statement CLIENTE-64510-IN term ACEITA then accept
set policy-options policy-statement CLIENTE-64510-IN term REJEITA then reject

O term BACKUP vem antes do ACEITA de propósito: os dois casam o mesmo prefixo, e o primeiro que aceita encerra. Na export para o cliente, mandamos o bloco próprio e as rotas de trânsito, e a import fica no neighbor, porque cada cliente tem a sua prefix-list:

set policy-options policy-statement CLIENTES-OUT term NOSSOS from protocol static
set policy-options policy-statement CLIENTES-OUT term NOSSOS from prefix-list NOSSOS
set policy-options policy-statement CLIENTES-OUT term NOSSOS then accept
set policy-options policy-statement CLIENTES-OUT term TRANSITO from community DE-TRANSITO
set policy-options policy-statement CLIENTES-OUT term TRANSITO then accept
set policy-options policy-statement CLIENTES-OUT term REJEITA then reject
set protocols bgp group CLIENTES neighbor 192.0.2.10 import CLIENTE-64510-IN
set protocols bgp group CLIENTES export CLIENTES-OUT

O mesmo esquema serve para blackhole: uma community de cliente que dispara descarte. O desenho com a community BLACKHOLE está no post de RTBH com blackhole via BGP.

Aplicando as policies do BGP no Juniper com segurança

Policy errada em borda derruba tráfego. No Junos você tem duas redes de proteção: o show | compare, que mostra a diferença antes de aplicar, e o commit confirmed, que desfaz sozinho se você não confirmar em 5 minutos:

show | compare
commit check
commit confirmed 5
commit

Entre o commit confirmed 5 e o commit final, confira as rotas anunciadas e recebidas. Se perder o acesso, espere os 5 minutos e a configuração anterior volta.

Verificação do BGP no Juniper

user@borda> show bgp summary
user@borda> show bgp neighbor 192.0.2.2
user@borda> show route receive-protocol bgp 192.0.2.2
user@borda> show route receive-protocol bgp 192.0.2.2 hidden
user@borda> show route advertising-protocol bgp 192.0.2.2
user@borda> show route advertising-protocol bgp 192.0.2.6 detail
user@borda> show route 198.51.100.0/24 detail
user@borda> show route community 64500:200
user@borda> test policy TRANSITO-OUT 203.0.113.0/24
  • show bgp summary: estado das sessões e quantas rotas cada vizinho mandou e quantas estão ativas.
  • show bgp neighbor: detalhes da sessão, incluindo as policies de import e export em uso.
  • receive-protocol bgp: o que o vizinho anunciou e foi aceito. Com hidden, aparecem as rotas recebidas que a import rejeitou: é o jeito de confirmar que o filtro de bogons está pegando.
  • advertising-protocol bgp: o que sai depois da export. Para o trânsito, deve aparecer só o seu /24 e o do cliente. Com detail, no B, dá para ver o AS path com o prepend.
  • show route 198.51.100.0/24 detail: local-preference e communities da rota do cliente.
  • show route community 64500:200: todas as rotas marcadas como de cliente.
  • test policy: passa as rotas da inet.0 que casam com o prefixo pela policy e mostra as aceitas. Bom para testar uma export antes de aplicar.

Erros comuns no BGP no Juniper

  • Export sem reject no fim. A policy default anuncia as rotas BGP ativas e a borda vira trânsito entre as operadoras.
  • Policy no neighbor achando que soma com a do group. Só o nível mais específico vale.
  • prefix-list esperando casar mais específicos. Ela casa exato. Use prefix-list-filter ... orlonger ou route-filter.
  • Misturar route-filters de tamanhos diferentes no mesmo term. O casamento pelo mais longo pode deixar passar o que você queria pegar.
  • Term genérico antes do específico. O primeiro accept encerra e o term seguinte nunca é testado.
  • Commit direto em borda. Use commit confirmed até ver o advertising-protocol certo.

Perguntas frequentes

O BGP no Juniper anuncia rotas sem export policy?

Anuncia. Sem export, a policy default do BGP manda para o vizinho as rotas BGP ativas. Rotas de outros protocolos, como estática e diretamente conectada, só saem com uma policy que as aceite.

Qual a diferença entre prefix-list e route-filter no Junos?

A prefix-list é um objeto reutilizável que casa só os prefixos exatos. O route-filter fica dentro do term e traz o tipo de casamento na linha, como exact, orlonger ou prefix-length-range. Para usar uma prefix-list com mais específicos, existe o prefix-list-filter.

Como ver as rotas rejeitadas pela import policy?

Use show route receive-protocol bgp com o IP do vizinho e a opção hidden. Ali aparecem as rotas que o vizinho mandou e a import rejeitou.

O que faz o next policy?

Encerra a policy atual sem aceitar nem rejeitar e passa a rota para a próxima policy da cadeia, com as modificações já feitas. É o que permite separar o prepend numa policy própria.

Como aplicar communities no Junos?

Para marcar rotas do BGP no Juniper, defina a community com nome em policy-options community NOME members e use then community add NOME no term. Para apagar todas, crie uma com members "*:*" e use community delete.

Conclusão

O BGP no Juniper fica previsível quando você pensa em terms: condições de tipos diferentes somam, o primeiro accept ou reject encerra e, se ninguém decidir, vale a default, que é permissiva. Com import que limpa e marca, export que só anuncia o que é seu e termina em reject, e communities para carregar a origem da rota, a borda Junos fala a mesma língua da borda Huawei.

Antes de cada commit em produção, rode o show | compare, aplique com commit confirmed e olhe o advertising-protocol de cada trânsito. São três comandos que evitam o vazamento de rotas.

Compartilhar:

Sobre o autor

Ivan Alves

Especialista em redes de provedores (ISP)

Ivan Alves trabalha há mais de 15 anos com redes de provedores de internet, do NOC ao backbone e à borda BGP. Coordena infraestrutura e tecnologia em um provedor regional e escreve aqui os tutoriais que gostaria de ter encontrado quando começou: comandos testados, cenário explicado e o porquê de cada linha.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *