Mikrotik

CGNAT no Mikrotik: netmap determinístico com blocos de portas

Grade de blocos de portas em laranja sobre fundo grafite, representando CGNAT determinístico

Montar CGNAT no Mikrotik é fácil: uma regra de src-nat com o bloco 100.64.0.0/10 e um IP público já funciona. O problema do CGNAT no Mikrotik aparece semanas depois, quando chega um ofício pedindo o cliente que usava o IP 203.0.113.5, porta 4100, numa data e hora. Com NAT dinâmico, a resposta depende de log de cada conexão, que cresce rápido e é difícil de guardar. Se o conceito ainda é novo, veja antes o que é CGNAT e como funciona no provedor.

Este guia monta o CGNAT no Mikrotik de forma determinística, no RouterOS v7: cada cliente sai sempre pelo mesmo IP público e pela mesma faixa de portas, calculados por fórmula. Uso a ação netmap com blocos de portas, um script que gera todas as regras, uma tabela de correspondência em CSV e uma função que responde ao ofício sem precisar de log de NAT. O cenário é de laboratório, com endereços de documentação: clientes em 100.64.0.0/22 e pool público 203.0.113.0/27.

Resposta rápida: CGNAT no Mikrotik em 6 passos

  1. Defina a proporção: quantos clientes por IP público e quantas portas cada um recebe.
  2. Crie uma rota blackhole para o pool público, para o tráfego de retorno sem conexão não voltar para a borda.
  3. Crie uma regra de jump que manda só o bloco 100.64 para uma chain própria.
  4. Para cada bloco de clientes do tamanho do pool, crie duas regras netmap (TCP e UDP) com to-ports na faixa daquele bloco.
  5. Feche a chain com uma regra de src-nat para ICMP e os demais protocolos.
  6. Gere e guarde a tabela de correspondência cliente x IP:portas, com a data em que a configuração entrou no ar.

Por que fazer o CGNAT no Mikrotik determinístico

No NAT dinâmico, o roteador escolhe IP e porta na hora de cada conexão. Para saber quem usou a porta 4100 às 21h13, você precisa ter registrado aquela tradução. Num provedor com alguns milhares de clientes, isso dá milhões de linhas por dia, e o syslog vira um projeto à parte.

No modelo determinístico, a tradução é uma conta. O cliente 100.64.0.37 sempre sai como 203.0.113.5, sempre entre as portas 3024 e 5023. Com o IP público e a porta do ofício, você chega ao 100.64 sem consultar log de NAT. Falta só saber qual cliente tinha aquele 100.64 no horário, e isso já está no registro de conexão do PPPoE ou do RADIUS, que o provedor guarda de qualquer forma.

Guarde a tabela com data. O Marco Civil da Internet (Lei 12.965/2014, art. 13) obriga o provedor de conexão a guardar os registros de conexão por um ano. Se você mudar a proporção ou o pool, a fórmula muda. Guarde cada versão da tabela com a data em que entrou em produção.

Existe um custo: cada cliente fica preso à sua faixa de portas. Um cliente que abre muitas conexões esgota a faixa dele sem poder pegar portas livres dos vizinhos. Por isso o dimensionamento é a primeira decisão do CGNAT no Mikrotik, antes de qualquer regra.

Dimensionamento: clientes por IP e portas por cliente

O RouterOS trabalha com portas de 0 a 65535. As abaixo de 1024 ficam de fora, o que deixa cerca de 64 mil portas por IP público. Divida pelo número de clientes que vão compartilhar cada IP e você tem as portas por cliente. A tabela assume um bloco de 1024 clientes:

Clientes por IPIPs públicos para 1024 clientesPortas por clienteComentário
81288.000Folgado, gasta IP público
16644.000Folgado para uso residencial
32322.000Equilíbrio usado neste guia
64161.000Apertado com jogos, câmeras e muitas abas

Neste guia: 1024 clientes (100.64.0.0/22), 32 IPs públicos (203.0.113.0/27), 32 clientes por IP e 2000 portas por cliente. As faixas vão de 1024 a 65023, em 32 blocos de 2000 portas. As portas de 65024 a 65535 sobram.

Quantas portas um cliente usa

Uma casa com celulares, TV e computador costuma ficar em algumas centenas de conexões simultâneas. Picos acontecem com jogos online, torrent, câmeras em nuvem e navegadores com muitas abas. 2000 portas por cliente é um valor comum no mercado brasileiro e dá margem para a maioria das casas. Clientes empresariais ou que precisam receber conexões devem ficar fora do CGNAT, com IP público próprio.

Como o netmap faz o mapeamento determinístico

A documentação do RouterOS define o netmap como um mapeamento estático 1:1 de um conjunto de endereços para outro. Na prática, ele troca a parte de rede do endereço e preserva a posição do host. Se a regra mapeia 100.64.0.32/27 para 203.0.113.0/27, o 100.64.0.37 (sexto endereço do bloco) sai como 203.0.113.5 (sexto endereço do pool).

O truque do CGNAT no Mikrotik com netmap é repetir o mesmo pool para vários blocos de clientes, cada um com uma faixa de portas diferente no to-ports. O bloco 0 (100.64.0.0/27) usa as portas 1024 a 3023, o bloco 1 (100.64.0.32/27) usa 3024 a 5023, e assim até o bloco 31 (100.64.3.224/27), com 63024 a 65023. Cada IP público é dividido entre 32 clientes, um de cada bloco, sem sobreposição de portas.

Diagrama: blocos /27 de 100.64.0.0/22 mapeados no pool 203.0.113.0/27, cada bloco com sua faixa de portas
Cada bloco /27 de clientes usa o mesmo pool público com uma faixa de portas própria. O netmap mantém a posição do host: 100.64.0.37 sai como 203.0.113.5 nas portas 3024 a 5023.

A conta inversa é a que responde ao ofício. Com IP público e porta, a posição do IP no pool dá a posição do host, e a porta dá o bloco: (porta – 1024) dividido por 2000, sem o resto. Para 203.0.113.5 e porta 4100, a posição é 5 e o bloco é 1, então o cliente é o 100.64.0.37.

Preparando o roteador

Lista de interfaces WAN

As regras de NAT usam uma lista de interfaces em vez de nome de porta. Assim, trocar ou somar um uplink não exige mexer no NAT. Ajuste ether1 para a sua interface de saída:

/interface list add name=WAN
/interface list member add list=WAN interface=ether1

Rota blackhole para o pool público

/ip route add dst-address=203.0.113.0/27 blackhole

O pool público não está configurado em nenhuma interface, e o NAT cuida das conexões que existem. Mas pacotes que chegam da internet para um IP do pool sem conexão correspondente precisam de destino. Sem essa rota, eles seguem a rota padrão e voltam para o upstream, criando um loop até o TTL zerar. A rota blackhole descarta esse tráfego no próprio roteador. Se o pool é anunciado por BGP a partir deste equipamento, essa rota também serve de origem para o anúncio.

As regras de CGNAT no Mikrotik, uma a uma

Antes de gerar as 64 regras com script, vale ver como ficam as primeiras. Este é o começo da configuração, com os dois primeiros blocos:

/ip firewall nat
add chain=srcnat action=jump jump-target=cgnat src-address=100.64.0.0/22 \
    out-interface-list=WAN
add chain=cgnat action=netmap protocol=tcp src-address=100.64.0.0/27 \
    to-addresses=203.0.113.0/27 to-ports=1024-3023
add chain=cgnat action=netmap protocol=udp src-address=100.64.0.0/27 \
    to-addresses=203.0.113.0/27 to-ports=1024-3023
add chain=cgnat action=netmap protocol=tcp src-address=100.64.0.32/27 \
    to-addresses=203.0.113.0/27 to-ports=3024-5023
add chain=cgnat action=netmap protocol=udp src-address=100.64.0.32/27 \
    to-addresses=203.0.113.0/27 to-ports=3024-5023

Linha por linha, o papel de cada regra no CGNAT no Mikrotik:

  • jump para a chain cgnat: só o tráfego de 100.64.0.0/22 saindo pela lista WAN entra na chain própria. O resto do srcnat não passa pelas 64 regras, o que poupa CPU, porque o NAT avalia as regras em ordem até a primeira que casa.
  • action=netmap protocol=tcp: traduz o bloco /27 para o pool /27 mantendo a posição do host. O to-ports limita as portas de origem ao bloco daquele grupo.
  • a mesma regra com protocol=udp: TCP e UDP têm portas independentes, então os dois usam a mesma faixa sem conflito.
  • o bloco seguinte: 100.64.0.32/27 vai para o mesmo pool com a faixa 3024 a 5023. A regra só muda nesses dois campos.

A regra de jump precisa ficar acima de qualquer masquerade ou src-nat genérico que já exista no roteador. Se uma regra mais ampla aparecer antes, ela traduz os clientes do CGNAT no Mikrotik antes da chain própria, de forma dinâmica e a tabela deixa de valer.

ICMP e os demais protocolos

ICMP, GRE e ESP não têm porta. Eles precisam de uma regra no fim da chain, sem to-ports:

/ip firewall nat
add chain=cgnat action=src-nat to-addresses=203.0.113.0-203.0.113.31

Essa tradução não é determinística, mas ofícios tratam de conexões com porta. A regra existe para que ping, traceroute e VPNs que usam esses protocolos funcionem atrás do CGNAT. Para quem fecha VPN a partir do cliente, o guia de como criar VPN no Mikrotik mostra os tipos de túnel do RouterOS.

Script que gera as regras do CGNAT no Mikrotik

Com 32 blocos, são 64 regras netmap mais o jump e a regra final. Escrever na mão é pedir erro de digitação na faixa de portas, e esse erro quebra a tabela sem ninguém perceber. O script abaixo, colado no terminal do RouterOS v7, gera tudo a partir de cinco valores:

{
:local base 100.64.0.0
:local pool "203.0.113.0/27"
:local blocos 32
:local porta 1024
:local passo 2000
/ip firewall nat add chain=srcnat action=jump jump-target=cgnat \
    src-address=100.64.0.0/22 out-interface-list=WAN
:for k from=0 to=($blocos - 1) do={
  :local rede ($base + ($k * 32))
  :local p1 ($porta + ($k * $passo))
  :local p2 ($p1 + $passo - 1)
  :foreach pr in={"tcp";"udp"} do={
    /ip firewall nat add chain=cgnat action=netmap protocol=$pr \
      src-address="$rede/27" to-addresses=$pool to-ports=($p1 . "-" . $p2)
  }
}
/ip firewall nat add chain=cgnat action=src-nat \
    to-addresses=203.0.113.0-203.0.113.31
}

O que cada parte faz:

  • base, pool, blocos, porta e passo são os parâmetros do dimensionamento. Mudou a proporção, mude aqui e gere de novo.
  • $base + ($k * 32) soma um número a um endereço IP, recurso do script do RouterOS. Para k igual a 1, dá 100.64.0.32.
  • p1 e p2 calculam a faixa de portas do bloco k.
  • O :foreach cria a regra TCP e a UDP com os mesmos valores.
  • A última regra cobre ICMP e os demais protocolos.

A documentação da MikroTik traz um script com a mesma ideia, mas com src-nat e uma regra por cliente. Com netmap, cada regra cobre um bloco inteiro, e o total de regras cai de milhares para dezenas. Rode o script num roteador de laboratório primeiro e confira o resultado com /ip firewall nat print antes de levar para produção.

Tabela de correspondência do CGNAT no Mikrotik para ofício

A tabela é a parte que justifica o trabalho. Em vez de extrair do roteador, gere a partir da mesma fórmula, com um script Python que também responde à pergunta inversa. Salve como cgnat_tabela.py:

import csv
import ipaddress
import sys

PRIV = ipaddress.ip_network('100.64.0.0/22')
PUB = ipaddress.ip_network('203.0.113.0/27')
PORTA, PASSO = 1024, 2000
N = PUB.num_addresses


def mapa():
    for i, ip in enumerate(PRIV):
        bloco, pos = divmod(i, N)
        p1 = PORTA + bloco * PASSO
        yield str(ip), str(PUB[pos]), p1, p1 + PASSO - 1


def quem(ip_pub, porta):
    pos = int(ipaddress.ip_address(ip_pub)) - int(PUB.network_address)
    fim = PORTA + PASSO * (PRIV.num_addresses // N)
    if not 0 <= pos < N or not PORTA <= porta < fim:
        raise ValueError('IP ou porta fora do CGNAT determinístico')
    bloco = (porta - PORTA) // PASSO
    return str(PRIV[bloco * N + pos])


if __name__ == '__main__':
    w = csv.writer(sys.stdout)
    w.writerow(['ip_cgnat', 'ip_publico', 'porta_ini', 'porta_fim'])
    w.writerows(mapa())

mapa() percorre os 1024 endereços e devolve, para cada um, o IP público e a faixa de portas. quem() faz a conta inversa: recebe IP público e porta e devolve o 100.64 do cliente. Se o IP ou a porta estiverem fora das faixas, a função recusa a consulta em vez de chutar um cliente. Os parâmetros precisam ser os mesmos do script do RouterOS.

python cgnat_tabela.py > cgnat-tabela-2026-10-09.csv
python -c "import cgnat_tabela as t; print(t.quem('203.0.113.5', 4100))"

O primeiro comando grava o CSV com a data no nome. O segundo responde ao exemplo da introdução e imprime 100.64.0.37. Um trecho do CSV:

ip_cgnat,ip_publico,porta_ini,porta_fim
100.64.0.0,203.0.113.0,1024,3023
100.64.0.1,203.0.113.1,1024,3023
...
100.64.0.32,203.0.113.0,3024,5023
100.64.0.37,203.0.113.5,3024,5023
...
100.64.3.255,203.0.113.31,63024,65023

Repare em 100.64.0.0 e 100.64.0.32: os dois saem por 203.0.113.0, em faixas diferentes. Para fechar o ofício, cruze o 100.64 encontrado com o registro de conexão do PPPoE no horário pedido. Lembre que o horário do ofício pode vir em outro fuso; confira antes de cruzar.

Ajuste de timeouts do CGNAT no Mikrotik

Cada conexão ocupa uma porta da faixa do cliente até sair da tabela de conexões. Timeout longo segura portas que ninguém usa mais. O primeiro comando mostra os valores atuais, e o segundo reduz o timeout de TCP estabelecido:

/ip firewall connection tracking print
/ip firewall connection tracking set tcp-established-timeout=2h4m

O padrão do RouterOS v7 para tcp-established-timeout é de 1 dia. A RFC 5382 pede que um NAT não derrube uma conexão TCP estabelecida ociosa antes de 2 horas e 4 minutos, e é daí que vem o valor do exemplo. Os timeouts de UDP (30 segundos, ou 3 minutos para fluxos) e de ICMP (10 segundos) já são curtos no padrão da v7. Confira com o print antes de mexer.

Conferindo o CGNAT no Mikrotik em laboratório

/ip firewall nat print stats where chain=cgnat
/ip firewall connection print detail where src-address~"100.64.0.37:"

O primeiro comando mostra os contadores de cada regra da chain cgnat. Com tráfego de teste, os contadores do bloco certo sobem. O segundo lista as conexões do cliente 100.64.0.37: no campo reply-dst-address, o endereço tem de ser 203.0.113.5 e a porta tem de estar entre 3024 e 5023. Se aparecer outro IP ou outra faixa, alguma regra acima do jump está traduzindo antes.

Teste também o limite: abra muitas conexões a partir de um cliente de laboratório e veja o que acontece quando a faixa acaba. As novas conexões daquele cliente deixam de ser traduzidas, enquanto os vizinhos seguem normais. É o comportamento esperado do modelo e o motivo de dimensionar com folga.

Erros comuns no CGNAT no Mikrotik

  • Blocos e pool de tamanhos diferentes. Netmap de um /22 para um /27 faz 32 clientes caírem no mesmo IP com a mesma faixa de portas. Cada regra deve ter origem do mesmo tamanho do pool.
  • Regras com a mesma origem. Se todas as regras usam 100.64.0.0/22, só a primeira casa e as faixas seguintes nunca são usadas.
  • Masquerade antes do jump. O tráfego é traduzido de forma dinâmica e a tabela não vale mais.
  • Esquecer o UDP. DNS, jogos e QUIC usam UDP. Sem a regra, ele cai na tradução genérica do fim da chain.
  • Mudar a proporção sem versionar a tabela. Um ofício de três meses atrás precisa da tabela que valia naquela data.
  • Esquecer a rota blackhole. Tráfego da internet para IPs do pool sem conexão fica em loop com o upstream.

O CGNAT resolve a falta de IPv4, mas tem efeitos para o cliente: jogos com NAT restrito, câmeras que não aceitam acesso de fora e NAT duplo com o roteador da casa. A saída de longo prazo é entregar IPv6 junto. Se você ainda está montando o plano, comece por o que é IPv6. Quem também tem borda Huawei acha os comandos equivalentes na lista de comandos para roteadores e switches Huawei.

Perguntas frequentes

Qual a diferença entre netmap e src-nat no CGNAT?

O src-nat traduz para um IP ou faixa escolhida na hora, então precisa de uma regra por cliente para ser determinístico. O netmap traduz um bloco inteiro mantendo a posição do host. Com to-ports, uma regra cobre 32 clientes de uma vez.

Quantos clientes posso colocar por IP público?

Depende das portas por cliente. Com 2000 portas, cabem 32 clientes por IP. Com 1000 portas, 64, mas jogos e câmeras começam a sofrer. Para uso residencial, entre 16 e 32 clientes por IP é uma faixa comum.

Preciso guardar log de NAT com CGNAT determinístico?

Não de cada conexão, porque a fórmula responde qual 100.64 usava o IP e a porta. Você ainda precisa do registro de conexão do PPPoE ou do RADIUS, que diz qual cliente tinha aquele 100.64 no horário, e de cada versão da tabela com data.

O que acontece quando o cliente usa todas as portas da faixa?

As conexões novas daquele cliente não encontram porta livre e falham até que conexões antigas expirem. Os outros clientes não são afetados. Timeouts mais curtos e uma faixa maior reduzem o problema.

Posso usar esse modelo no RouterOS v6?

A ação netmap e o to-ports existem na v6, mas este guia foi escrito e conferido com a documentação da v7. Os timeouts padrão mudaram entre as versões, então confira os valores do seu roteador antes de copiar.

Conclusão

CGNAT no Mikrotik determinístico troca log de NAT por uma conta. Com blocos de clientes do tamanho do pool, netmap com to-ports por bloco e uma tabela gerada pela mesma fórmula, qualquer pedido de IP público e porta vira um endereço 100.64 em segundos. O trabalho está no dimensionamento e na disciplina de versionar a tabela.

Gere as regras com script, guarde o CSV com data, deixe o jump acima de qualquer masquerade e teste em laboratório antes de mover clientes. Assim o CGNAT no Mikrotik segura a falta de IPv4 enquanto o IPv6 chega aos clientes.

Leitura recomendada: CGNAT na prática, wiki do Brasil Peering Forum (CC BY-NC 4.0).

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 *