Documentação

Escolhendo o que passa pelo túnel

Receitas opcionais de RouterOS para um roteador ForestVPN — enviar um grupo de aplicativos, enviar tudo, e impedir vazamento de tráfego quando o túnel está fora do ar.

Atualizado em 8 de outubro de 2026

Tudo nesta página é opcional. Um roteador ForestVPN tuneliza seu próprio tráfego no momento em que conecta, e nada disso é necessário para isso. Esta é a outra tarefa: decidir qual parte do tráfego da sua LAN sai pelo servidor de saída, e o que acontece quando o servidor de saída não pode ser alcançado.

A divisão de tarefas nunca muda. O RouterOS decide o quê vai para o túnel, o contêiner tuneliza o que lhe é entregue, e sua conta decide onde isso sai. Então tudo isso é configuração comum do RouterOS — marcações mangle, uma tabela de roteamento, uma regra de firewall — e nada disso toca o contêiner.

Leia isto primeiro

Três fatos decidem se qualquer parte disso funciona. Pular esta seção é uma noite que você não recupera.

Cole isto na caixa que roteia sua LAN. A cadeia prerouting do RouterOS só vê o tráfego que a própria caixa roteia. Em um ponto de acesso situado a jusante do seu gateway real, toda regra abaixo é inerte — medido em um cAP ax cuja própria rota padrão é o roteador a montante dele: o contêiner tunelizou perfeitamente e o tráfego de nenhum cliente da LAN chegou perto dele. O contêiner pode viver naquele ponto de acesso; as regras vão no gateway.

O servidor de saída admite um endereço de origem por dispositivo — o lease de overlay que ele emitiu. Um pacote chegando com qualquer outra origem interna é descartado, não roteado, por mais corretas que suas regras sejam. Algo precisa reescrever sua LAN nesse lease, e o que faz isso depende do contêiner:

ContêinerO que você precisa fazer sobre isso
suquant/fvpn — o aplicativo gerenciado pela contaNada. A partir da versão 0.3.9, o contêiner mascara (masquerade) o que você encaminhar para ele sobre seu próprio lease, e segue esse lease quando ele muda. O comando de instalação ativa isso.
suquant/fvpnq — o túnel bruto, a partir de um .conf que você escreveuAdicione um src-nat para o Address no seu .conf, que também é o que você coloca no AllowedIPs do servidor de saída. Você o escolheu, então ele é estável e uma regra pode referenciá-lo.

Está rodando um contêiner mais antigo que 0.3.9? Rode o comando de instalação de novo — as regras abaixo vão marcar e rotear perfeitamente e o servidor de saída vai descartar todo pacote, o que parece como a LAN perdendo o acesso à internet por completo no momento em que você adiciona a regra de roteamento.

O fasttrack pula o mangle. O firewall de fábrica da MikroTik faz fasttrack de conexões estabelecidas, e uma conexão em fasttrack nunca mais alcança a cadeia mangle — então suas marcações se aplicam ao primeiro pacote de um fluxo e a nada depois dele. Cada receita abaixo traz a regra que mantém conexões marcadas fora do fasttrack, e ela precisa ficar acima da regra fasttrack-connection.

E a metade do IPv6, que estas regras não fazem por você

Tudo aqui é IPv4. Se seu roteador tiver IPv6 funcionando, todo destino que você selecionar abaixo também é alcançável por v6, contornando o túnel, e nada avisa você disso. Se, em vez disso, o roteador se anuncia como um roteador IPv6 sem ter uma rota padrão v6, os clientes da LAN mandam tráfego v6 para ele e não recebem nada de volta — nem mesmo um erro, porque o RouterOS 7 não tem rota “inalcançável” para v6, só um blackhole silencioso. Dispositivos sem Happy Eyeballs — TVs, relógios, qualquer coisa que faça uma conexão direta em um registro AAAA — então travam pelo tempo limite de conexão completo em cada destino v6, o que parece “a internet às vezes quebra” e culpa o Wi-Fi. Esta linha única informa em qual dos dois casos você está:

# Does this router tell LAN clients it is their IPv6 router?
/ipv6/nd/print where ra-lifetime!=none
 
# Does it have somewhere to send their v6 traffic?
/ipv6/route/print where dst-address="::/0" and routing-table="main"

Resposta para a primeira e nenhuma para a segunda é o segundo caso. Dê ao IPv6 uma rota padrão de verdade, ou pare de anunciar uma com /ipv6/nd/set [find] ra-lifetime=none.

Etapa 1 — a estrutura de base

O mesmo para as três receitas. Substitua pelo endereço do seu próprio contêiner no lugar de 172.31.254.2 (o padrão da instalação; /interface/veth/print tem esse valor) e pelo seu próprio prefixo de LAN no lugar de 192.168.88.0/24.

Confira /container/print detail primeiro. remote-image precisa dizer 0.3.9 ou posterior, e cmd precisa conter --nat-lan. Ambos vêm do comando de instalação atual; um contêiner instalado antes disso não tem nenhum dos dois, e o sintoma é a LAN perder o acesso à internet por completo no momento em que você adiciona a regra de roteamento na etapa 2.

# A routing table of its own, so nothing here can disturb your normal
# default route.
/routing/table add name=via-fvpn fib
 
# Where marked traffic goes: the container, on the address RouterOS itself
# gave it.
/ip/route add dst-address=0.0.0.0/0 gateway=172.31.254.2 \
    routing-table=via-fvpn comment="fvpn: traffic leaves via the container"
 
# Collapse the LAN to one source address on the way IN to the container. The
# exit never sees this one either -- the container masquerades again onto its
# own lease -- so this is about keeping your LAN's layout out of the
# container's connection table, not about being admitted.
/ip/firewall/nat add chain=srcnat out-interface=veth-fvpn action=masquerade \
    comment="fvpn: hide LAN addressing from the container"
 
# The tunnel costs 80 bytes of MTU. Without this, large TCP flows stall
# rather than fail, which presents as "the internet is broken on Tuesdays".
/ip/firewall/mangle add chain=forward action=change-mss new-mss=clamp-to-pmtu \
    protocol=tcp tcp-flags=syn connection-mark=via-fvpn \
    comment="fvpn: clamp MSS on tunnelled TCP"
 
# Fasttrack bypasses mangle, so marked connections have to be accepted
# before they reach it. This rule is inert if it ends up below the fasttrack
# rule -- check with /ip/firewall/filter/print that it did not.
/ip/firewall/filter add chain=forward action=accept connection-mark=via-fvpn \
    place-before=[find action=fasttrack-connection] \
    comment="fvpn: marked flows skip fasttrack"

Depois escolha uma das duas próximas. Ambas produzem a mesma marcação de conexão via-fvpn, então elas disputariam o mesmo tráfego se você colasse as duas.

Etapa 2a — opcional: apenas chamadas e mensageiros

A configuração que roda no nosso próprio RB3011 há meses. Ela divide o problema da mesma forma que o tráfego realmente se divide: a sinalização é um punhado de hostnames dos fornecedores, a mídia é uma faixa de portas em relés que ninguém publica.

# Signalling, by hostname. A hostname in a RouterOS address list is not a
# static entry -- the router resolves it and keeps the answers fresh, which
# is the only form that survives a CDN moving under you.
/ip/firewall/address-list
add list=fvpn-via address=g.whatsapp.net      comment="fvpn: signalling"
add list=fvpn-via address=media.whatsapp.net  comment="fvpn: signalling"
add list=fvpn-via address=mmg.whatsapp.net    comment="fvpn: signalling"
add list=fvpn-via address=static.whatsapp.net comment="fvpn: signalling"
add list=fvpn-via address=web.whatsapp.com    comment="fvpn: signalling"
add list=fvpn-via address=api.telegram.org    comment="fvpn: signalling"
add list=fvpn-via address=core.telegram.org   comment="fvpn: signalling"
add list=fvpn-via address=web.telegram.org    comment="fvpn: signalling"
add list=fvpn-via address=chat.signal.org     comment="fvpn: signalling"
add list=fvpn-via address=storage.signal.org  comment="fvpn: signalling"
 
/ip/firewall/mangle
add chain=prerouting action=mark-connection new-connection-mark=via-fvpn \
    dst-address-list=fvpn-via \
    comment="fvpn: signalling by resolved vendor hostname"
 
# Media, by port -- the half an address list can never cover, because a call
# lands on whichever TURN relay the vendor picked that minute.
add chain=prerouting action=mark-connection new-connection-mark=via-fvpn \
    protocol=udp dst-port=3478-3481 \
    comment="fvpn: STUN/TURN media - calls in every major app"
add chain=prerouting action=mark-connection new-connection-mark=via-fvpn \
    protocol=tcp dst-port=3478-3481,5349,5350 \
    comment="fvpn: STUN/TURN over TCP and TLS"
add chain=prerouting action=mark-connection new-connection-mark=via-fvpn \
    protocol=udp dst-port=5060,5061 comment="fvpn: SIP"
add chain=prerouting action=mark-connection new-connection-mark=via-fvpn \
    protocol=tcp dst-port=5060,5061 comment="fvpn: SIP over TCP/TLS"
add chain=prerouting action=mark-connection new-connection-mark=via-fvpn \
    protocol=tcp dst-port=5222,5223 comment="fvpn: XMPP signalling"
 
# One routing decision for the whole connection. Marking the connection
# first and the route second -- rather than marking the route directly -- is
# what keeps a call that started on the tunnel on the tunnel.
add chain=prerouting action=mark-routing new-routing-mark=via-fvpn \
    passthrough=no src-address=192.168.88.0/24 connection-mark=via-fvpn \
    comment="fvpn: route marked connections via the exit"

Os hostnames são um ponto de partida, não uma autoridade. Os fornecedores os adicionam e aposentam sem avisar ninguém. Confira /ip/firewall/mangle/print stats em busca de contadores parados em zero — isso é uma regra que não bate com nada, não uma regra fazendo seu trabalho em silêncio.

Etapa 2b — opcional: tudo

/ip/firewall/mangle
# The container's own packets must never be marked, or its tunnel gets
# routed into itself. The install puts the container's interface in the LAN
# list, so the rule below WOULD match it. Substitute the container's
# address.
add chain=prerouting action=accept src-address=172.31.254.2 \
    comment="fvpn: never mark the container's own traffic"
 
# Everything from the LAN that is not addressed to this router.
# `dst-address-type=!local` is what keeps DNS, WebFig and the status page
# off the tunnel; `in-interface-list=LAN` rather than a source prefix keeps
# the rule correct when the LAN is renumbered.
add chain=prerouting action=mark-connection new-connection-mark=via-fvpn \
    in-interface-list=LAN dst-address-type=!local \
    comment="fvpn: everything from the LAN"
# `dst-address-type=!local` on this rule too, and it is not decoration. The
# install puts the container's veth in the LAN list, so replies coming back
# OUT of the container also match `in-interface-list=LAN`, and they still
# carry the connection mark. Mangle prerouting runs before dstnat, so at
# this moment their destination is still the router's own srcnat address --
# local. Without the test they would take the routing mark and be sent back
# into the container instead of on to the client that asked.
add chain=prerouting action=mark-routing new-routing-mark=via-fvpn \
    passthrough=no in-interface-list=LAN dst-address-type=!local \
    connection-mark=via-fvpn \
    comment="fvpn: route marked connections via the exit"

Confira o que você colou antes de testar. /ip/firewall/mangle/print precisa mostrar estas três regras. Uma colagem no terminal que perde uma das continuações de linha te deixa com as regras de marcação e nenhuma regra de roteamento, o que parece exatamente com “o túnel está sendo ignorado” — as conexões carregam connection-mark=via-fvpn, nada nunca consulta a tabela, e todo pacote sai pela sua conexão normal.

Enviar tudo significa enviar o DNS também — que é o objetivo, mas quer dizer que o resolvedor do servidor de saída responde à sua LAN. Confira se o que depende de nomes locais (uma impressora, um NAS, router.lan) ainda resolve antes de decidir que este é o modo que você quer.

Etapa 3 — opcional: um interruptor de emergência

O roteamento seletivo tem um modo de falha que vale a pena fechar: quando o túnel para, o tráfego marcado pode voltar silenciosamente a sair pela sua conexão normal. Estas três regras fazem isso parar. Adicione-as depois de qualquer receita que você escolheu.

Todo comando desta seção foi executado no RouterOS 7.24.1 antes de ser escrito aqui. A sintaxe difere do RouterOS 6 em um ponto, marcado abaixo.

# 1. The route to the container counts only while the container answers.
/ip/route/set [find routing-table=via-fvpn dst-address=0.0.0.0/0] \
    check-gateway=ping
 
# 2. When it stops counting, drop rather than fall back. The higher distance
#    keeps this route inactive for as long as the real one is up. `blackhole`
#    is a bare flag here, not `type=blackhole` -- RouterOS 7 has no `type`
#    property on a route at all, and rejects it with "bad parameter type".
/ip/route/add dst-address=0.0.0.0/0 blackhole distance=10 \
    routing-table=via-fvpn comment="fvpn: kill switch - no exit, no traffic"
 
# 3. The leak the first two cannot see: a container that is alive and
#    answering ping while its own tunnel is down forwards to its default
#    gateway, which is you. Traffic wearing the address the srcnat above gave
#    it must never reach the internet directly. Substitute your router's own
#    address on the container's /30 if you changed it.
/ip/firewall/filter/add chain=forward action=drop src-address=172.31.254.1 \
    out-interface-list=WAN \
    place-before=[find comment="fvpn: marked flows skip fasttrack"] \
    comment="fvpn: kill switch - overlay source must not leave over WAN"

A regra 3 precisa ficar acima da regra de isenção de fasttrack da etapa 1, ou aquela regra aceita o tráfego primeiro e o descarte nunca é alcançado. place-before faz isso aqui; confirme com /ip/firewall/filter/print.

A versão mais rígida: dispositivos que só podem usar o túnel

Se o que você realmente quer é “este laptop não tem internet a menos que esteja tunelizado”, diga isso diretamente em vez de inferir a partir do estado de roteamento:

/ip/firewall/address-list/add list=fvpn-only address=192.168.88.50 \
    comment="fvpn: the work laptop"
/ip/firewall/filter/add chain=forward action=drop src-address-list=fvpn-only \
    out-interface-list=WAN \
    place-before=[find comment="fvpn: marked flows skip fasttrack"] \
    comment="fvpn: kill switch - these devices are tunnel-only"

Esse dispositivo agora alcança a internet pelo contêiner ou não alcança de forma alguma, seja lá o que as tabelas de roteamento disserem em qualquer manhã.

Conferindo se funcionou

# A rule sitting at zero packets is a rule matching nothing.
/ip/firewall/mangle/print stats
/ip/route/print where routing-table=via-fvpn
# The fasttrack-exemption rule has to be above the fasttrack rule.
/ip/firewall/filter/print

A partir de um dispositivo da LAN, carregue qualquer página de “qual é o meu IP”. Ela deve mostrar o país do servidor de saída para o tráfego que você selecionou e o seu próprio para todo o resto. Se ela mostrar o seu próprio para tudo, a causa costumeira é o primeiro fato desta página: as regras estão em uma caixa que não roteia a LAN.

Desfazendo tudo

Toda linha acima carrega um comentário começando com fvpn:, então removê-las é exato — e não vai tocar nos próprios objetos do contêiner, que o instalador comenta como forestvpn.

/ip/firewall/mangle/remove [find comment~"^fvpn:"]
/ip/firewall/filter/remove [find comment~"^fvpn:"]
/ip/firewall/nat/remove [find comment~"^fvpn:"]
/ip/firewall/address-list/remove [find comment~"^fvpn:"]
/ip/route/remove [find comment~"^fvpn:"]
/ip/address/remove [find comment~"^fvpn:"]
/routing/table/remove [find name="via-fvpn"]

O contêiner continua rodando, mantém sua vinculação de conta, e volta a tunelizar apenas o próprio tráfego. Se algo mais estiver errado, veja solução de problemas.

Voltar para Suporte

Português
Pergunte qualquer coisa