BGP

RPKI: como criar ROA no Registro.br para proteger seu ASN

Cadeado dourado sobre um prefixo IP com a cadeia de certificados do RPKI ao fundo

Quem recebe o primeiro ASN e o primeiro bloco do Registro.br costuma deixar o RPKI para depois. A sessão BGP sobe, o prefixo aparece na internet e tudo parece resolvido. O problema é que, sem uma ROA publicada, nada impede que outro AS anuncie o seu bloco e leve parte do tráfego dos seus clientes. E muitos trânsitos e IXs descartam rotas inválidas, então a ROA errada também derruba o seu próprio anúncio. Se a sessão BGP ainda é novidade, veja antes o que é BGP e como ele funciona no provedor.

Este guia mostra o caminho completo no Brasil: o que a ROA declara, como o Registro.br entrega o RPKI (modelo delegado, com uma CA própria rodando no Krill), como criar a ROA no Krill sem abrir o max-length à toa e como conferir o resultado no Routinator e em consultas públicas. Os exemplos usam o AS 64500 e blocos de documentação (203.0.113.0/24, 198.51.100.0/24 e 2001:db8::/32). Troque pelos seus.

Resposta rápida: como criar ROA no Registro.br

  1. Suba um Krill (a CA do RPKI da NLnet Labs) num servidor seu e crie a CA com krillc add.
  2. Gere o child request no Krill, cole no painel do Registro.br (TITULARIDADE, nome da organização, opção RPKI – Configurar RPKI) e traga de volta o Parent Response.
  3. No mesmo lugar, clique em Configurar Publicação Remota e faça a troca do repositório (Publisher Request e Repository Response).
  4. Crie uma ROA por prefixo que você anuncia, sem max-length maior que o prefixo, com krillc roas update --add.
  5. Confira no Routinator ou no RIPEstat: o seu anúncio tem de aparecer como valid.

O que é RPKI e o que uma ROA diz

RPKI (Resource Public Key Infrastructure) é uma cadeia de certificados que liga cada bloco de IP e cada ASN a quem recebeu esses recursos. No topo estão os RIRs, como o LACNIC. No Brasil, o NIC.br distribui os recursos e emite os certificados para os provedores. Com o certificado na mão, o dono do bloco assina objetos que dizem o que é legítimo no BGP.

A ROA (Route Origin Authorization) é o objeto mais usado. Ela tem três campos: o prefixo, o tamanho máximo de máscara aceito (max-length) e o ASN autorizado a originar aquele prefixo. Em português claro: “o bloco 203.0.113.0/24 pode ser anunciado pelo AS 64500, só como /24”.

A ROA não diz nada sobre o caminho. Ela valida só a origem, o último AS do AS-path. Um vazamento de rota com a origem correta continua passando. Mesmo assim, ela fecha a porta para o sequestro mais comum, em que alguém anuncia o seu bloco como se fosse dele.

Quem assina o quê na cadeia do RPKI

O validador (Routinator, por exemplo) baixa os certificados e as ROAs de todos os repositórios, confere as assinaturas desde a raiz do RIR e monta uma lista de pares prefixo, max-length e ASN. Essa lista se chama VRP (Validated ROA Payload). O roteador não fala com o RPKI direto: ele recebe os VRPs do validador pelo protocolo RTR e compara com cada rota recebida.

Cadeia do RPKI: LACNIC, NIC.br, CA do provedor no Krill, ROA publicada, validador e roteador
Do certificado do NIC.br até o roteador: a CA do provedor assina a ROA, o validador baixa e confere, e o roteador recebe os VRPs via RTR.

Hospedado ou delegado: o modelo do Registro.br

Existem duas formas de um registro entregar o RPKI. No modelo hospedado, o próprio registro gera e guarda a chave da sua CA, e você só preenche a ROA num formulário. No modelo delegado, você roda a CA. O registro assina o certificado dela, e é a sua CA que assina as ROAs e as publica.

ModeloComo funcionaPrós e contrasOnde aparece
HospedadoO registro guarda a chave e você cria a ROA num formulário do portalMais simples; você depende do portal para tudoComum em RIRs como RIPE NCC e ARIN
DelegadoVocê roda a própria CA (Krill), que recebe o certificado do registro e assina as ROAsMais trabalho; a chave e as ROAs ficam sob seu controleModelo do Registro.br para ASNs brasileiros

O Registro.br adotou o modelo delegado e apoia o Krill como software de CA. Por isso o passo a passo tem uma etapa a mais do que nos tutoriais de RIPE ou ARIN: os dois lados trocam arquivos XML no padrão RFC 8183 antes de a primeira ROA existir. No painel do Registro.br não existe formulário de ROA: o painel só habilita o RPKI da titularidade e, se você quiser, a publicação remota. A ROA em si é criada e assinada no seu Krill.

Quem pode fazer: o usuário responsável pelo ID administrativo da titularidade (a organização) no Registro.br. O RPKI é habilitado para a titularidade, e não ASN por ASN. Se a conta foi criada por um consultor, confirme quem é o ID administrativo antes de começar.

Max-length: por que não abrir até /24 à toa

O max-length parece um atalho cômodo. Você tem um /22 e escreve uma ROA só, com max-length 24, para poder anunciar qualquer /23 ou /24 de dentro dele sem mexer no RPKI de novo. O custo aparece num ataque chamado forged-origin: o atacante anuncia um /24 seu que você não anuncia, colocando o seu ASN como origem no AS-path. A ROA aceita, o validador marca como valid e o /24 mais específico ganha do seu /22.

A RFC 9319 (BCP 185) trata exatamente disso. A recomendação é usar ROAs mínimas, que autorizam só os prefixos que você de fato anuncia, e evitar o max-length maior que o prefixo, salvo em casos bem específicos. Se você anuncia o /22 inteiro e dois /24 de engenharia de tráfego, crie três ROAs, uma para cada prefixo, todas com max-length igual à própria máscara.

E quando eu precisar anunciar um /24 numa emergência?

É o argumento mais comum a favor do max-length aberto: ataque DDoS, mitigação que exige anunciar um /24 ou divisão de tráfego às pressas. Criar a ROA do /24 leva um comando no Krill e alguns minutos até os validadores pegarem. Vale mais deixar esse comando documentado no runbook do NOC do que deixar todos os /24 do bloco autorizados o tempo todo.

Com IPv6 vale o mesmo raciocínio. Se você anuncia só o /32, a ROA é do /32. Se o plano de endereçamento prevê anunciar /48 de algum ponto da rede, crie a ROA desse /48 quando ele for para o BGP. Se a base do IPv6 ainda está confusa, comece por o que é IPv6.

Passo a passo: ativar o RPKI e criar a ROA

O roteiro abaixo segue a documentação da CLI do Krill (krillc). A interface web do Krill faz as mesmas coisas com botões; a CLI é mais fácil de documentar e de repetir. Instale o Krill pelo pacote da NLnet Labs ou por Docker, num servidor com HTTPS e com backup do diretório de dados. Perder esse diretório é perder a chave da sua CA.

1. Apontar a CLI e criar a CA

As duas variáveis evitam repetir servidor e token em todo comando. O token é o mesmo configurado no arquivo do Krill; trate-o como senha.

export KRILL_CLI_SERVER="https://localhost:3000/"
export KRILL_CLI_TOKEN="troque-por-um-token-longo"
krillc add --ca meu_ca
krillc show --ca meu_ca

krillc add cria a CA com o nome que você escolher (só letras, números, traço e sublinhado). krillc show mostra o estado. Logo depois de criada, ela ainda não tem nenhum recurso: quem entrega o bloco e o ASN é o Registro.br, no passo seguinte.

2. Trocar os XML com o painel do Registro.br

krillc parents request --ca meu_ca > child_request.xml

O child request é a identidade da sua CA. No painel do Registro.br, clique em TITULARIDADE e no nome da organização, desça até o fim da página e abra a opção RPKI – Configurar RPKI. Cole o conteúdo de child_request.xml no campo Child Request e clique em Habilitar RPKI. O painel devolve o Parent Response; salve como parent_response.xml.

krillc parents add --ca meu_ca --parent nicbr_ca \
  --response ./parent_response.xml
krillc parents statuses --ca meu_ca

O nome do pai (nicbr_ca) é só um rótulo local; use o mesmo em todos os comandos. O parents statuses confirma se a sua CA conseguiu falar com o Registro.br e se recebeu os recursos. Versões antigas do Krill usavam outra sintaxe para esse comando; se a sua recusar, rode krillc parents add --help e siga o que ela mostrar.

3. Configurar o repositório de publicação

As ROAs precisam ficar num repositório público, que os validadores do mundo inteiro consultam. O Registro.br oferece publicação remota, o que poupa você de manter um servidor rsync e RRDP. A troca é igual à anterior, com outro par de arquivos:

krillc repo request --ca meu_ca > publisher_request.xml
krillc repo configure --ca meu_ca --response ./repository_response.xml
krillc repo status --ca meu_ca

Gere o publisher_request.xml. Na mesma página do painel, clique em Configurar Publicação Remota, cole o conteúdo no campo Publisher Request e clique em Habilitar Publicação Remota. Salve o Repository Response como repository_response.xml.

O Krill aceita configurar pai e repositório em qualquer ordem; a página do Registro.br sugere importar primeiro o Repository Response e depois o Parent Response. O repo status deve mostrar a última publicação sem erro, e o parents statuses fica vazio enquanto o repositório não estiver configurado.

4. Criar uma ROA por prefixo anunciado

krillc roas update --ca meu_ca --add "203.0.113.0/24 => 64500"
krillc roas update --ca meu_ca --add "198.51.100.0/24 => 64500"
krillc roas update --ca meu_ca --add "2001:db8::/32 => 64500"
krillc roas list --ca meu_ca

O formato é prefixo[-max-length] => ASN. Sem o trecho -max-length, o Krill usa a própria máscara, que é a ROA mínima recomendada. Crie uma linha para cada prefixo que sai no BGP, em IPv4 e em IPv6. O roas list no fim mostra o que está publicado.

Remover a ROA de um bloco que saiu do BGP

krillc roas update --ca meu_ca --remove "198.51.100.0/24 => 64500"
krillc roas list --ca meu_ca

Bloco devolvido, cliente com ASN próprio que levou o /24 dele, prefixo que deixou de ser anunciado: tire a ROA. Uma ROA esquecida apontando para o seu ASN deixa espaço para alguém anunciar aquele prefixo com a sua origem forjada. Se o bloco passou para outro AS, a ROA certa é a do novo AS, criada por quem tem a titularidade do bloco.

Conferir a ROA no Routinator e em consultas públicas

Publicar não basta: confira como o mundo enxerga o seu prefixo. O Routinator é o validador da mesma NLnet Labs. Instalado pelo pacote oficial (antes, adicione o repositório de pacotes da NLnet Labs, como manda a página de instalação), ele já roda como serviço, com RTR na porta 3323 e HTTP na 8323, ouvindo só no localhost.

sudo apt install routinator
sudo systemctl status routinator
sudo journalctl --unit=routinator

O arquivo /etc/routinator/routinator.conf traz estas linhas. Para o roteador conseguir falar RTR com o validador, troque o 127.0.0.1 do rtr-listen pelo IP do servidor na rede de gerência e libere a porta só para os roteadores.

repository-dir = "/var/lib/routinator/rpki-cache"
rtr-listen = ["127.0.0.1:3323"]
http-listen = ["127.0.0.1:8323"]

Com o serviço rodando, a documentação pede para não usar os comandos interativos de validação na mesma máquina. Use a API HTTP. A primeira consulta pergunta se o AS 64500 pode originar o 203.0.113.0/24; a segunda testa outro ASN como origem, que deve sair invalid se a ROA estiver certa:

curl -s "http://127.0.0.1:8323/validity?asn=64500&prefix=203.0.113.0/24"
curl -s "http://127.0.0.1:8323/validity?asn=64511&prefix=203.0.113.0/24"

Para uma segunda opinião de fora da sua rede, o RIPEstat tem uma consulta pública de validação RPKI. Ela usa um validador próprio e devolve o estado e as ROAs que casaram com o anúncio:

curl -s "https://stat.ripe.net/data/rpki-validation/data.json?resource=AS64500&prefix=203.0.113.0/24"

Uma saída resumida, com os valores do nosso exemplo:

"data": {
  "resource": "64500",
  "prefix": "203.0.113.0/24",
  "validating_roas": [{"origin": "64500", "prefix": "203.0.113.0/24",
                        "validity": "valid", "max_length": 24}],
  "status": "valid",
  "validator": "routinator"
}

Depois de criar a ROA, espere alguns minutos. Os validadores revisitam os repositórios em ciclos; no Routinator o padrão é a cada 10 minutos. Se em uma hora o prefixo ainda aparece como not-found, volte ao krillc repo status e ao krillc parents statuses.

Estados valid, invalid e not-found

Todo validador classifica cada par prefixo e origem em um de três estados, definidos na RFC 6811. Entender a diferença evita o erro mais caro do RPKI: criar a ROA pela metade e transformar o próprio anúncio em invalid.

EstadoQuando aconteceO que significa na prática
validExiste ROA cobrindo o prefixo, com o mesmo ASN de origem e máscara dentro do max-lengthÉ o que você quer ver no seu anúncio
invalidExiste ROA cobrindo o prefixo, mas a origem é outro ASN ou a máscara passa do max-lengthRedes com ROV descartam a rota. Se é o seu anúncio, corrija a ROA na hora
not-foundNenhuma ROA cobre o prefixoA rota passa, mas sem proteção nenhuma

O caso clássico de invalid autoinfligido: o provedor cria a ROA do /22 com max-length 22 e, semanas depois, a equipe começa a anunciar um /24 para equilibrar dois trânsitos. O /24 agora é coberto por uma ROA que não o aceita. Antes de qualquer mudança de anúncio, a pergunta do runbook é: existe ROA para este prefixo, com esta máscara e esta origem?

Próximo passo: validar rotas no roteador (ROV)

Criar a ROA protege o seu bloco nas redes que validam. Validar as rotas que chegam até você é a outra metade, chamada ROV (Route Origin Validation). O roteador abre uma sessão RTR com o Routinator, recebe os VRPs e marca cada rota recebida dos peers como valid, invalid ou not-found. A política mais comum é descartar as invalid e preferir as valid.

A configuração muda de fabricante para fabricante e merece um post próprio. Antes de ligar o descarte, rode alguns dias só marcando as rotas e veja quantas invalid aparecem. Se você já trabalha com route-policy no Huawei, o sistema de BGP communities no Huawei mostra a estrutura em que a validação vai se encaixar. Para os comandos de consulta do dia a dia no VRP, veja a lista de comandos para roteadores e switches Huawei.

Erros comuns ao criar ROA

  • ROA com o ASN errado. Bloco anunciado pelo AS do trânsito (cliente sem ASN próprio) precisa de ROA com o ASN de quem origina, não com o seu.
  • Max-length aberto até /24 “por garantia”. Abre espaço para o forged-origin. Use ROA mínima.
  • Esquecer o IPv6. O /32 fica not-found e não ganha a proteção que o IPv4 ganhou.
  • Anunciar um /24 novo sem ROA. Se existe ROA do /22 com max-length 22, o /24 vira invalid e some das redes que fazem ROV.
  • Perder ou deixar parado o servidor do Krill. O Registro.br monitora as publicações e avisa por e-mail quando estão em atraso, mas sem backup dos dados você perde a chave da CA e precisa refazer a delegação no painel.
  • Deixar o Krill e o Routinator abertos para a internet. A interface do Krill e a porta RTR não precisam ficar públicas; limite por firewall.
  • Não conferir depois. A ROA só está certa quando o seu anúncio aparece como valid num validador de fora.

Perguntas frequentes

Meu bloco veio do trânsito. Posso criar a ROA?

Não pela sua conta. Quem assina a ROA é o titular do bloco, ou seja, o provedor que repassou os endereços. Peça a ele uma ROA com o prefixo que você anuncia e o seu ASN como origem, e confira o resultado no RIPEstat depois.

Preciso de um Krill próprio para criar ROA no Registro.br?

Sim. O Registro.br usa o modelo delegado: o painel só habilita o RPKI, e quem assina a ROA é a sua CA. A CA indicada pelo Registro.br é o Krill. Conte com um servidor para ele, sempre no ar, e com backup dos dados.

Quanto tempo a ROA leva para aparecer nos validadores?

Normalmente minutos. Depende do ciclo de cada validador: o Routinator, por padrão, revisita os repositórios a cada 10 minutos. Se passar de uma hora, confira o status do repositório e do pai no Krill.

Qual max-length devo usar na ROA?

O mesmo tamanho do prefixo anunciado, que é o padrão quando você não informa nada no Krill. A RFC 9319 recomenda ROAs mínimas e evitar max-length maior que o prefixo, porque isso facilita o sequestro com origem forjada. Se precisar anunciar um /24 depois, crie a ROA dele na hora.

RPKI protege contra vazamento de rota?

Não por completo. A ROA valida só o AS de origem do anúncio. Um vazamento que mantém a origem correta passa pela validação. Filtros de prefixo por cliente, IRR e políticas de exportação continuam necessários.

O que acontece se eu não criar ROA nenhuma?

O seu prefixo fica not-found e continua sendo aceito, mas sem proteção contra quem anunciar o mesmo bloco com outro ASN. Você também perde a chance de ter as suas rotas preferidas em redes que dão prioridade às rotas valid.

Conclusão

Ativar o RPKI no Registro.br dá mais trabalho do que em outros registros, porque o modelo é delegado e a CA é sua. O roteiro, porém, é curto: Krill no ar, troca de XML com o painel para o pai e para o repositório, uma ROA mínima por prefixo anunciado e conferência no Routinator e no RIPEstat. Depois, toda mudança de anúncio passa a ter uma pergunta a mais no checklist: a ROA cobre este prefixo, com esta máscara e esta origem?

Com as ROAs no lugar, o passo natural é validar o que chega até a sua rede com ROV. Até lá, o seu bloco já está protegido em todas as redes que descartam rotas invalid.

Leitura recomendada: Protegendo seu ASN com RPKI, artigo da wiki do Brasil Peering Forum (CC BY-NC 4.0), que mostra a instalação do Krill e a troca de XML com o Registro.br.

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.

2 Comentários

  1. bgpq4 e IRR: gerar filtros de prefixo BGP automaticamente – IA Tecnologia Responder

    […] Quando você pede ao seu trânsito para liberar seus anúncios, ele normalmente roda algo como o bgpq4 contra o seu as-set. Quando o seu cliente pede a você, o caminho é o inverso: você gera o filtro a partir do as-set ou do ASN dele. O IRR não prova que o prefixo é seu, ele só registra o que cada um declarou. Por isso ele anda junto com o RPKI, que assina a origem com certificado; o passo a passo está no post sobre como criar ROA no Registro.br. […]

  2. RPKI no Huawei: validação de origem (ROV) e descarte de inválidos – IA Tecnologia Responder

    […] tem recursos via NIC.br cria os ROAs no painel do Registro.br; o passo a passo está no guia para criar ROA para o seu bloco. Esses objetos ficam em repositórios públicos ligados à cadeia de certificados de cada […]

Deixe um comentário

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