Documentación

Elegir qué pasa por el túnel

Recetas opcionales de RouterOS para un router ForestVPN — enviar un grupo de apps, enviarlo todo, y evitar que el tráfico se filtre cuando el túnel está caído.

Actualizado el 8 de octubre de 2026

Todo lo que hay en esta página es opcional. Un router ForestVPN tuneliza su propio tráfico en el momento en que se conecta, y nada de esto es necesario para eso. Esta es la otra tarea: decidir qué parte del tráfico de tu LAN sale por la salida, y qué ocurre cuando no se puede alcanzar la salida.

La división del trabajo nunca cambia. RouterOS decide qué va al túnel, el contenedor tuneliza lo que se le entrega, y tu cuenta decide por dónde sale. Así que todo esto es configuración normal de RouterOS — marcas mangle, una tabla de enrutamiento, una regla de firewall — y nada de ello toca el contenedor.

Lee esto primero

Tres hechos determinan si algo de esto funciona. Saltárselos es una noche que no recuperas.

Pega esto en el equipo que enruta tu LAN. La cadena prerouting de RouterOS solo ve el tráfico que el propio equipo enruta. En un punto de acceso situado aguas abajo de tu puerta de enlace real, cada regla de más abajo es inerte — medido en un cAP ax cuya propia ruta predeterminada es el router aguas arriba de él: el contenedor tunelizaba perfectamente y el tráfico de ningún cliente de la LAN pasaba siquiera cerca de él. El contenedor puede vivir en ese punto de acceso; las reglas van en la puerta de enlace.

La salida admite una dirección de origen por dispositivo — la concesión de superposición que emitió. Un paquete que llegue con cualquier otro origen interno se descarta, no se enruta, por muy correctas que sean tus reglas. Algo tiene que reescribir tu LAN sobre esa concesión, y qué lo hace depende del contenedor:

ContenedorQué tienes que hacer al respecto
suquant/fvpn — la app gestionada por la cuentaNada. A partir de la versión 0.3.9 el contenedor enmascara (masquerade) todo lo que le reenvías hacia su propia concesión, y sigue esa concesión cuando cambia. El comando de instalación activa esto.
suquant/fvpnq — el túnel puro, a partir de un .conf que escribiste túAñade un src-nat a la Address de tu .conf, que es también lo que pones en el AllowedIPs de la salida. Tú lo elegiste, así que es estable y una regla puede nombrarlo.

¿Tienes un contenedor anterior a la 0.3.9? Vuelve a ejecutar el comando de instalación — las reglas de más abajo marcarán y enrutarán perfectamente y la salida descartará cada paquete, lo que se percibe como que la LAN pierde el internet por completo en el momento en que añades la regla de enrutamiento.

Fasttrack se salta mangle. El firewall de fábrica de MikroTik acelera (fasttrack) las conexiones ya establecidas, y una conexión acelerada nunca vuelve a llegar a la cadena mangle, así que tus marcas se aplican al primer paquete de un flujo y a nada después de él. Cada receta de más abajo incluye la única regla que mantiene las conexiones marcadas fuera de fasttrack, y tiene que situarse por encima de la regla fasttrack-connection.

Y la parte de IPv6, que estas reglas no pueden resolver por ti

Todo esto es IPv4. Si tu router tiene IPv6 funcionando, cada destino que selecciones más abajo también es alcanzable por v6, sin pasar por el túnel, y nada te avisa de ello. Si en cambio el router se anuncia como router IPv6 sin tener una ruta predeterminada v6, los clientes de la LAN le envían tráfico v6 y no reciben nada de vuelta — ni siquiera un error, porque RouterOS 7 no tiene ninguna ruta «inalcanzable» para v6, solo un blackhole silencioso. Los dispositivos sin Happy Eyeballs — televisores, relojes, cualquier cosa que haga una conexión directa sobre un registro AAAA — se quedan entonces esperando el tiempo de espera completo en cada destino v6, lo que se percibe como que «el internet a veces falla» y se le echa la culpa al Wi-Fi. Esta línea indica en cuál de los dos casos estás:

# 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"

Respuestas a la primera y ninguna a la segunda es el segundo caso. Dale a IPv6 una ruta predeterminada real, o deja de anunciar una con /ipv6/nd/set [find] ra-lifetime=none.

Paso 1 — el andamiaje

Igual para las tres recetas. Sustituye tu propia dirección de contenedor por 172.31.254.2 (la predeterminada de la instalación; la tiene /interface/veth/print) y tu propio prefijo de LAN por 192.168.88.0/24.

Comprueba primero /container/print detail. remote-image tiene que indicar 0.3.9 o posterior, y cmd tiene que contener --nat-lan. Ambos vienen del comando de instalación actual; un contenedor instalado antes de eso no tiene ninguno de los dos, y el síntoma es que la LAN pierde el internet por completo en el momento en que añades la regla de enrutamiento del paso 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"

Luego elige una de las dos siguientes. Ambas producen la misma marca de conexión via-fvpn, así que competirían por el mismo tráfico si pegaras las dos.

Paso 2a — opcional: solo llamadas y mensajería

La configuración que llevamos meses usando en nuestro propio RB3011. Divide el problema tal como se divide el tráfico en realidad: la señalización es un puñado de nombres de host de los proveedores, y los medios son un rango de puertos en relés que nadie 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"

Los nombres de host son un punto de partida, no una autoridad. Los proveedores los añaden y los retiran sin avisar a nadie. Comprueba /ip/firewall/mangle/print stats en busca de contadores que se quedan en cero — eso es una regla que no coincide con nada, no una regla que hace su trabajo en silencio.

Paso 2b — opcional: todo

/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"

Cuenta lo que has pegado antes de probarlo. /ip/firewall/mangle/print debe mostrar las tres reglas. Un pegado en la terminal que pierde una de las continuaciones de línea te deja con las reglas de marcado y sin la regla de enrutamiento, lo que se parece exactamente a «el túnel se ignora» — las conexiones llevan connection-mark=via-fvpn, nada consulta nunca la tabla, y cada paquete sale por tu conexión normal.

Enviarlo todo significa enviar también el DNS — que es precisamente la idea, pero implica que el resolutor de la salida responde a tu LAN. Comprueba que lo que depende de nombres locales (una impresora, un NAS, router.lan) siga resolviendo antes de decidir que este es el modo que quieres.

Paso 3 — opcional: bloquear el tráfico si falla la salida

El enrutamiento selectivo tiene un modo de fallo que vale la pena cerrar: cuando el túnel se detiene, el tráfico marcado puede volver silenciosamente a salir por tu conexión normal. Estas tres reglas hacen que se detenga en su lugar. Añádelas después de la receta que hayas elegido.

Cada comando de esta sección se ejecutó en RouterOS 7.24.1 antes de escribirlo aquí. La sintaxis difiere de RouterOS 6 en un punto, señalado más abajo.

# 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"

La regla 3 tiene que situarse por encima de la regla de exención de fasttrack del paso 1, o esa regla acepta el tráfico antes y nunca se llega al descarte. place-before lo hace aquí; confírmalo con /ip/firewall/filter/print.

La versión más estricta: dispositivos que solo pueden usar el túnel

Si lo que realmente quieres es «este portátil no tiene internet a menos que esté tunelizado», dilo directamente en lugar de inferirlo del estado de enrutamiento:

/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"

Ese dispositivo ahora llega a internet a través del contenedor o no llega en absoluto, diga lo que diga la tabla de enrutamiento una mañana cualquiera.

Comprobar que ha funcionado

# 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

Desde un dispositivo de la LAN, carga cualquier página de «cuál es mi IP». Debería mostrar el país de la salida para el tráfico que seleccionaste y el tuyo propio para todo lo demás. Si muestra el tuyo propio para todo, la causa habitual es el primer hecho de esta página: las reglas están en un equipo que no enruta la LAN.

Deshacerlo

Cada línea de más arriba lleva un comentario que empieza por fvpn:, así que eliminarlas es exacto — y no tocará los propios objetos del contenedor, que el 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"]

El contenedor sigue ejecutándose, conserva su vínculo de cuenta, y vuelve a tunelizar solo su propio tráfico. Si hay algo más que no funciona, consulta solución de problemas.

Volver a Ayuda

Español
Pregúntanos lo que sea