BGP

BGP no Mikrotik RouterOS v7: connection, templates e filtros

Blocos de filtro em azul e amarelo empilhados entre o roteador Mikrotik e dois trânsitos BGP

Quem configurou BGP no Mikrotik na versão 6 e abre um roteador com RouterOS v7 não encontra mais o menu de peers nem o de networks. O protocolo é o mesmo, mas a configuração foi reescrita: sessões viraram connections, configurações comuns foram para templates, os prefixos anunciados saem de uma address-list e os filtros ganharam uma sintaxe parecida com script. A partir da 7.20, o AS voltou a ter um menu próprio, o instance.

Este guia monta uma borda com dois trânsitos do zero, na sintaxe atual. O AS 64500 anuncia 203.0.113.0/24, o trânsito A (AS 64501) é o preferido e o trânsito B (AS 64502) fica de reserva. Todos os endereços e ASNs são de documentação, e os comandos foram conferidos na documentação oficial da MikroTik. Se o conceito de AS, eBGP e atributos ainda é novo para você, comece por o que é BGP e como ele funciona.

Resposta rápida: BGP no Mikrotik v7 em cinco passos

  1. Crie o prefixo como rota (blackhole) e coloque-o numa address-list. O BGP só anuncia o que existe na tabela de rotas.
  2. Crie a /routing/bgp/instance com o seu AS e o router-id.
  3. Coloque o que é comum aos trânsitos num /routing/bgp/template.
  4. Crie uma /routing/bgp/connection por vizinho, com local.role=ebgp, o template e as chains de entrada e saída.
  5. Escreva os filtros em /routing/filter/rule. Chain sem regra que aceite rejeita tudo, então anuncie só o seu prefixo e recuse bogons na entrada.

O que mudou do v6 para o v7

A tabela resume a troca de menus do BGP no Mikrotik. A maior mudança prática está nos filtros: não dá para copiar as regras da v6, nem as expressões regulares de AS-path, porque a v7 compara ASN por ASN e não caractere por caractere. A própria documentação avisa que colar expressões antigas pode gerar resultado perigoso.

ItemRouterOS v6RouterOS v7
AS e router-id/routing bgp instance/routing/bgp/instance (7.20 ou mais novo); antes, as= no template ou na connection
Vizinho/routing bgp peer/routing/bgp/connection
Parâmetros comunsRepetidos em cada peer/routing/bgp/template
Prefixos anunciados/routing bgp networkAddress-list em output.network
FiltrosRegras com campos (prefix, action)Regras em sintaxe de script: if (...) { ... }
Regex de AS-pathSobre o texto do caminhoSobre cada ASN; expressões da v6 não servem
Estado da sessão/routing bgp peer print status/routing/bgp/session print

Comece conferindo a versão. Todo o guia usa a sintaxe da 7.20 ou mais nova; em versões anteriores não existe o menu instance, e o AS vai como as= no template ou na própria connection. Na atualização para a 7.20, o RouterOS converte a configuração antiga para o modelo com instance, mas a própria MikroTik avisa que voltar para uma versão sem esse menu pode deixar a configuração do BGP inconsistente. Faça um /export antes de atualizar.

/system/resource print

Cenário: uma borda com dois trânsitos

Neste exemplo de BGP no Mikrotik, o roteador fala eBGP com dois provedores de trânsito. Do A (198.51.100.1) e do B (192.0.2.1) ele recebe a tabela completa e, para os dois, anuncia o mesmo /24. A política é simples e cobre a maioria dos provedores pequenos: tráfego de saída pelo A enquanto ele estiver de pé, e tráfego de entrada também chegando pelo A.

Diagrama: roteador Mikrotik AS 64500 com trânsito A preferido e trânsito B de reserva
Local-pref na entrada decide por onde o tráfego sai; prepend no anúncio decide por onde ele entra.

Na saída, quem decide é o local-pref, aplicado nas rotas recebidas: 120 para o A e 80 para o B. Na entrada, a decisão é dos outros ASes, e a ferramenta mais simples é o prepend, que deixa o caminho via B mais longo. Os dois ajustes são independentes, e é comum o tráfego de entrada não obedecer por completo ao prepend.

Anunciar o prefixo: rota blackhole e address-list

No BGP no Mikrotik v7, o anúncio sai de uma address-list apontada em output.network. Só que a lista sozinha não basta: o prefixo só é anunciado se existir uma rota igual na tabela de rotas. Essa sincronização evita anunciar um bloco que o roteador não sabe entregar.

/ip/address
add address=203.0.113.1/32 interface=lo
/ip/route
add dst-address=203.0.113.0/24 blackhole
/ip/firewall/address-list
add list=bgp-anuncio address=203.0.113.0/24
  • O endereço 203.0.113.1/32 na interface de loopback lo serve de router-id e de origem para testes. Em versões que não têm a lo, uma bridge vazia faz o mesmo papel.
  • A rota blackhole do /24 inteiro garante que o prefixo existe na tabela mesmo que nenhum cliente esteja ligado. Os /32 e /30 dos clientes são mais específicos e continuam funcionando, enquanto o tráfego para endereços sem uso é descartado na borda.
  • A address-list bgp-anuncio é a lista de prefixos que o roteador pode anunciar. Para um bloco novo, rota e linha na lista entram juntos.

Existe também o parâmetro output.network-blackhole=yes na connection, que cria a rota blackhole sozinho para cada prefixo da lista. A rota manual deixa mais claro o que está acontecendo, e é a escolha deste guia.

Instance e template

/routing/bgp/instance
add name=borda as=64500 router-id=203.0.113.1

A instance guarda o AS e o router-id do BGP no Mikrotik v7. Toda connection precisa apontar para uma, e a seleção do melhor caminho só compara rotas recebidas na mesma instance. Por isso as duas sessões de trânsito ficam na mesma: se cada uma estivesse numa instance, o roteador não compararia local-pref nem AS-path entre elas.

/routing/bgp/template
add name=transito afi=ip output.network=bgp-anuncio

O template junta o que vale para todos os trânsitos: a família de endereços (afi=ip, só IPv4 neste exemplo) e a address-list do anúncio. Um terceiro trânsito herda essas opções só com templates=transito. Não é o mesmo que peer-group do Cisco: o template é só uma forma de herdar parâmetros. A documentação não define qual valor vale quando o mesmo parâmetro aparece no template e na connection. Para não depender disso, deixe cada parâmetro num lugar só, como neste guia: o anúncio no template e as chains na connection.

Connection: uma por trânsito

/routing/bgp/connection
add name=transito-a instance=borda templates=transito \
    remote.address=198.51.100.1 remote.as=64501 \
    local.address=198.51.100.2 local.role=ebgp \
    input.filter=transito-in output.filter-chain=transito-a-out
add name=transito-b instance=borda templates=transito \
    remote.address=192.0.2.1 remote.as=64502 \
    local.address=192.0.2.2 local.role=ebgp \
    input.filter=transito-in output.filter-chain=transito-b-out

Cada parâmetro da connection, com o motivo:

  • instance=borda templates=transito: liga a sessão ao AS e herda o anúncio do template.
  • remote.address e remote.as: o vizinho. O AS remoto é opcional, porque o RouterOS descobre pela mensagem OPEN, mas fixá-lo impede que a sessão suba com um AS inesperado.
  • local.address: o equivalente ao update-source. Num enlace direto ele seria escolhido sozinho, mas deixar explícito evita surpresa quando o roteador tem vários endereços.
  • local.role=ebgp: parâmetro obrigatório. Os papéis ebgp-customer, ebgp-provider e ebgp-peer seguem a RFC 9234 e exigem que o vizinho também anuncie o papel; se o trânsito não suportar, a sessão cai com erro de papel. Na dúvida, use ebgp.
  • input.filter e output.filter-chain: as chains de entrada e saída. A entrada é a mesma para os dois; a saída é separada, porque só o B leva prepend.
Filtre antes de ligar. Crie as regras da próxima seção antes de as sessões subirem. Sem input.filter, o BGP aceita tudo o que chega; sem output.filter-chain, o roteador pode repassar a um trânsito as rotas que aprendeu do outro, como faz qualquer BGP sem política. É assim que nasce um vazamento de rotas, e o seu AS vira caminho entre dois provedores.

Routing filters na sintaxe v7

Os filtros do BGP no Mikrotik v7 ficam em /routing/filter/rule. Cada regra pertence a uma chain e traz um texto no formato if (condições) { ações }. As regras rodam em ordem; accept e reject encerram a chain. Se nenhuma regra decidir, o padrão é rejeitar, e é isso que faz o filtro de entrada recusar o que não foi previsto.

Entrada: recusar o que não presta e marcar a origem

/routing/filter/rule add chain=transito-in rule="if (dst in 203.0.113.0/24) { reject }"
/routing/filter/rule add chain=transito-in rule="if (dst in 0.0.0.0/8 || dst in 10.0.0.0/8 || dst in 100.64.0.0/10 || dst in 127.0.0.0/8) { reject }"
/routing/filter/rule add chain=transito-in rule="if (dst in 169.254.0.0/16 || dst in 172.16.0.0/12 || dst in 192.168.0.0/16 || dst in 198.18.0.0/15) { reject }"
/routing/filter/rule add chain=transito-in rule="if (dst in 192.0.2.0/24 || dst in 198.51.100.0/24 || dst in 224.0.0.0/4 || dst in 240.0.0.0/4) { reject }"
/routing/filter/rule add chain=transito-in rule="if (dst-len > 24 || dst-len < 8) { reject }"
/routing/filter/rule add chain=transito-in rule="if (bgp-input-remote-as == 64501) { set bgp-local-pref 120; append bgp-communities 64500:101; accept }"
/routing/filter/rule add chain=transito-in rule="if (bgp-input-remote-as == 64502) { set bgp-local-pref 80; append bgp-communities 64500:102; accept }"
  • A primeira regra recusa o próprio prefixo (e qualquer pedaço dele) vindo de fora. Rota para o seu bloco aprendida de um trânsito só serve para desviar o seu tráfego.
  • As três seguintes recusam bogons: faixas privadas, CGNAT, loopback, multicast, reservadas e as de documentação. O 203.0.113.0/24 não aparece porque é o prefixo do exemplo, já recusado pela primeira regra; na sua rede, inclua as três faixas de documentação. O operador in pega o bloco e todos os mais específicos dele.
  • A regra de dst-len recusa prefixos maiores que /24, que a internet não propaga, e menores que /8, o que inclui a rota padrão.
  • As duas últimas aceitam o resto, com local-pref 120 para o A e 80 para o B, e acrescentam uma community de origem (64500:101 e 64500:102). Com ela, dá para saber de onde veio cada rota na tabela e usar essa marca em filtros internos.

Saída: anunciar só o que é seu

/routing/filter/rule add chain=transito-a-out rule="if (dst in bgp-anuncio && dst-len < 32) { accept }"
/routing/filter/rule add chain=transito-b-out rule="if (dst in bgp-anuncio && dst-len < 32) { set bgp-path-prepend 3; accept }"

O operador in com o nome de uma address-list compara com os prefixos exatos da lista. A documentação avisa que, por a lista trabalhar com endereços de host, um /32 dentro da faixa também casaria; o dst-len < 32 fecha essa porta. Qualquer outra rota cai no rejeitar padrão e não sai.

Na chain do B, o bgp-path-prepend 3 faz o seu AS aparecer repetido no caminho anunciado (com o valor 3, 64500 64500 64500), contra uma vez pelo A. Confirme a contagem no looking glass do trânsito, como na seção de verificação. Para o resto da internet, o caminho pelo A fica mais curto e passa a ser o preferido.

Testar a expressão de AS-path antes de usar

A v7 tem um testador embutido. Ele recebe a expressão e um caminho de exemplo, com os ASNs separados por vírgula, e diz se casou. Use antes de colocar qualquer bgp-as-path em produção.

/routing/filter/test-as-path-regexp regexp="^64501" as-path="64501,64510"

Communities para conversar com o trânsito

Muitos trânsitos publicam communities que o cliente pode mandar para mudar o tratamento da rota dentro da rede deles: baixar o local-pref, não anunciar para certos peers ou fazer prepend no lugar do cliente. Quando o B oferece uma community de local-pref baixo, ela costuma funcionar melhor que o prepend, porque age dentro da rede dele. A regra abaixo substitui a do prepend na chain do B (o valor 80 é de exemplo; use o da documentação do seu trânsito):

/routing/filter/rule add chain=transito-b-out rule="if (dst in bgp-anuncio && dst-len < 32) { append bgp-communities 64502:80; accept }"

Na regra, o append acrescenta a community sem apagar as que já existem; set trocaria a lista inteira. Essa lógica do BGP no Mikrotik é a mesma das communities em outros fabricantes, que o guia de BGP communities no Huawei detalha. O mesmo mecanismo serve para o blackhole de ataques, assunto do post sobre RTBH com BGP.

Verificação da sessão e das rotas

Com as sessões no ar, estes são os comandos para conferir o BGP no Mikrotik:

/routing/bgp/session print
/routing/route print count-only where bgp
/routing/route print detail where dst-address=203.0.113.0/24
/routing/filter/rule print where chain=transito-in
/log print where topics~"bgp"
  • /routing/bgp/session print: lista as sessões. A flag E indica estabelecida; o detalhe mostra capacidades negociadas, as chains em uso, uptime e quantos prefixos chegaram.
  • print count-only where bgp: conta as rotas aprendidas por BGP sem despejar um milhão de linhas no terminal.
  • O print detail do seu prefixo mostra a rota blackhole ativa, condição para o anúncio sair.
  • Listar a chain confere a ordem das regras, que importa.
  • O log com tópico bgp mostra quedas de sessão e mensagens NOTIFICATION, como erro de papel ou de AS.

Uma sessão estabelecida com o trânsito A, em formato resumido:

Flags: E - established
 0 E name="transito-a" instance=borda
     remote.address=198.51.100.1 .as=64501 .id=198.51.100.1
     .capabilities=mp,rr,gr,as4 .afi=ip .messages=40211 .eor=ip
     local.role=ebgp .address=198.51.100.2 .as=64500 .id=203.0.113.1
     .capabilities=mp,rr,gr,as4 .afi=ip .messages=1207
     output.procid=20 .filter-chain=transito-a-out .network=bgp-anuncio
     input.procid=20 .filter=transito-in ebgp
     hold-time=3m keepalive-time=1m uptime=2d4h11m prefix-count=1012440

Para confirmar que o anúncio chegou do outro lado, use o looking glass do trânsito ou um looking glass público e procure o seu prefixo: pelo B, o caminho deve aparecer com o seu AS repetido.

Limites de hardware com tabela completa

A tabela IPv4 completa já está na casa de um milhão de prefixos, e cada sessão com tabela cheia guarda a sua cópia. Com dois trânsitos, são duas cópias em memória, além do trabalho de CPU para recalcular tudo quando uma sessão cai. Em roteador de entrada, isso significa minutos de convergência ou falta de memória.

OpçãoVantagemCusto
Tabela completa dos dois trânsitosEscolha do melhor caminho para cada destinoMais RAM e CPU; convergência mais lenta em roteador fraco
Tabela completa de um, rota padrão do outroBom equilíbrio para a maioriaO destino só vai pelo B se o A cair
Rota padrão dos doisCabe em qualquer hardwareSem escolha por destino; só redundância

Antes de pedir tabela completa para o BGP no Mikrotik, confira a memória livre com /system/resource print com as sessões fora e depois com elas no ar. Se o hardware não comporta, peça só a rota padrão ao trânsito ou filtre na entrada:

/routing/filter/rule add chain=so-default rule="if (dst == 0.0.0.0/0) { accept }"
/routing/bgp/connection set transito-b input.filter=so-default

O filtro resolve a tabela de rotas, mas a rota recusada continua em memória como filtrada. Para economizar memória de verdade, a connection tem opções como input.filter-nlri e input.accept-nlri, que descartam antes de guardar; elas exigem reiniciar a sessão. Em roteadores com muitos núcleos, input.affinity e output.affinity distribuem o trabalho das sessões entre processos.

O input.limit-process-routes-ipv4 aceita só potências de 10. Com a tabela perto de um milhão, o valor 1000000 fica justo demais para um trânsito; ele serve melhor em sessões de peering, onde o vizinho manda poucas rotas. Quando o limite estoura, a sessão fica marcada e só volta depois de limpar a flag no menu de sessões.

Erros comuns no BGP no Mikrotik v7

  • Prefixo na address-list sem rota. Sem a rota blackhole (ou outra rota igual), o prefixo não é anunciado, e nada no log avisa.
  • Chain de saída sem accept. O padrão é rejeitar. Uma chain criada com nome errado ou com a condição errada derruba todo o anúncio.
  • Sem filtro de saída. Sem output.filter-chain, o BGP aceita enviar tudo, e as rotas do trânsito A podem sair para o B. Isso é vazamento de rotas.
  • Sessões em instances diferentes. A seleção do melhor caminho só compara rotas da mesma instance; o local-pref parece ser ignorado.
  • Regex copiada da v6. A expressão é interpretada por ASN, não por texto. Teste com test-as-path-regexp.
  • Papel RFC 9234 sem suporte do outro lado. ebgp-customer com um trânsito que não negocia papel fecha a sessão. Use ebgp.
  • Porta 179 aberta para a internet. Libere o BGP só a partir dos vizinhos no firewall de input, como mostra o guia de segurança no Mikrotik RouterOS v7.

Perguntas frequentes

Preciso informar o remote.as na connection?

Não é obrigatório: o RouterOS descobre o AS do vizinho pela mensagem OPEN. Mesmo assim vale informar, porque a sessão passa a recusar um AS diferente do combinado, o que pega erro de configuração do outro lado.

Por que o meu prefixo não é anunciado?

Confira três coisas, nesta ordem, antes de culpar o BGP no Mikrotik: a rota igual ao prefixo existe e está ativa, o prefixo está na address-list de output.network e a chain de saída tem uma regra que aceita esse prefixo. Faltando qualquer uma, o anúncio não sai.

Dá para usar o BGP no Mikrotik com tabela completa?

Dá, desde que o hardware tenha memória e CPU para isso. Em modelos de entrada, prefira rota padrão de um ou dos dois trânsitos. Meça a memória livre com e sem as sessões antes de decidir.

Qual a diferença entre template e connection?

A connection é a sessão com um vizinho e precisa de nome, instance, endereço e papel. O template guarda parâmetros que várias connections herdam pelo campo templates, evitando repetir a mesma configuração.

Como fica o IPv6?

Do mesmo jeito, com uma connection para o endereço IPv6 do vizinho, a rota blackhole em /ipv6/route e a address-list em /ipv6/firewall/address-list. Os filtros podem separar as famílias com a condição afi ipv6.

Conclusão

O BGP no Mikrotik v7 pede outra forma de pensar: instance para o AS, template para o que se repete, uma connection por vizinho, address-list para o anúncio e filtros escritos como pequenos scripts. Com a rota blackhole do prefixo, a entrada recusando bogons e o próprio bloco, e a saída aceitando só o que é seu, a borda com dois trânsitos fica previsível.

O próximo passo é gerar filtros por cliente a partir do IRR, como descrito em filtros BGP com bgpq4 e IRR, e validar as rotas com RPKI. Monte o BGP no Mikrotik em laboratório antes, com as sessões subindo já filtradas.

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 *