Blog

MikroTik kill switch, tested with a leak probe

A RouterOS 7 kill switch in three rules, then a 100 ms probe on a CHR with the tunnel stopped: what leaked, what stayed silent and why rule order matters.

Published October 29, 2026 · 12 minutes read

Key takeaways

  • A blackhole route at distance 10 let 0 of 800 probes out over the WAN link in both stop modes; a health check did not.
  • 706 of 800 probes left over the WAN link in our run when a router with policy routing only lost its tunnel interface.
  • A drop rule above the fasttrack exemption leaked 0 probes; the same rule one line below it leaked 706.
  • The IPv4 rules never touched IPv6: all 800 IPv6 probes arrived over the WAN link, before and after the stop.
  • This was an emulated CHR with native WireGuard: not hardware, and not the ForestVPN container.
On this page (9)

A kill switch is a promise about one moment: the moment the tunnel stops. Most forum recipes, including the IPsec ones, show the rules and stop there. This one shows the moment, with a packet counter on the far side.

What the probe saw after the stop:

  • Policy routing only, or the health check only, with the router's own tunnel interface stopped: probes leaked from the first one after the stop, with no silent gap.
  • Health check only, with the peer stopped: about 30 s of silence, then replies over the WAN link about 33 s after the stop.
  • Blackhole in place: the probe went silent within 0.2 s.

What does a MikroTik kill switch have to stop?

A kill switch on RouterOS 7 (MikroTik's router operating system) has to keep traffic you marked for the tunnel from falling back to the main routing table when the tunnel route goes away. That fallback is how a router leaks: the marked packets lose their route, RouterOS looks again in the main table, and the main table has a default route out of the WAN.

Two terms matter here:

  • Mangle rules are RouterOS's packet- and connection-marking rule set. They create the marks.
  • Fasttrack is RouterOS's fast path that lets established flows skip most firewall rules, which is why rule order matters later.

The router in our run did exactly that. The table further down shows which layer closed the leak and which did not.

RouterOS's health check is check-gateway=ping: RouterOS pings the route's gateway and marks the route inactive when the gateway stops answering. On its own it did not close the leak. The ForestVPN routing script does not use it; it relies on the blackhole route and the rules described below.

We ran the test on a CHR (Cloud Hosted Router), a virtual RouterOS machine, and the whole run sits in the box below.

How this was tested

Product
MikroTik RouterOS Cloud Hosted Router (CHR), arm64, free licence level, native WireGuard
Version
7.24.1 (stable, build 2026-08-21)
System
QEMU 11.1.2 software emulation on a Mac; three CHR guests: router (2 vCPU, 512 MB), LAN client and WireGuard peer with the lab host (256 MB each)
Checked
Runs
1
Not tested

The router held the policy routing from the choose-traffic recipe: mangle marks, a routing table named via-fvpn, and a fasttrack exemption for marked flows. We added the kill switch layers by hand, one at a time: a health check, a blackhole route at distance 10, and drop rules.

ForestVPN's routing script today builds its kill switch differently (a blackhole at distance 250 and a rule that keeps marked packets out of the main table, no health check); that script was not what we ran.

A LAN client sent one ICMP probe every 100 ms, 800 probes per run, to a lab host behind the peer. Ten seconds in, we stopped the tunnel. The lab host counted arrivals by interface: over the WAN link was a leak, over the tunnel was not.

We stopped the tunnel two ways: the peer's interface (the remote end vanishes) and the router's own WireGuard interface (what a vanished local tunnel looks like to the route).

Each configuration ran once per stop mode, so these are single runs, not averages. Limits: a CHR is a virtual router: this is not a hardware result, no speed was measured, and the ForestVPN container was not run, because container mode was off on this CHR. Probe timing is host-side and good to about 0.2 s. ICMP only; no TCP, DNS or runs longer than about 80 s.

How do I make a VPN kill switch on RouterOS 7?

Paste the routing script from the router's status page on the router that routes your LAN. Every mode of it includes the kill switch, and the MikroTik kill switch help page lists what it builds and holds the commands for the check and the undo. This list says what each piece is for.

The container must already be installed: the script stops with an error if there is no veth-fvpn. The routing modes are in choosing what goes through the tunnel.

  1. A via-fvpn routing table with a default route to the container and a blackhole route behind it. When the container route goes away, the blackhole takes over. Our lab layer "blackhole fallback" is this piece, at distance 10 rather than the script's 250.
  2. A routing rule with lookup-only-in-table, so a marked packet is never looked up in the main table. This is the fallback the leak section describes, closed in the rule rather than by a route. We did not run this rule in the lab.
  3. Forward drops: one for new connections that come back out of the container's veth from anything but the container itself, which is what a container with a dead tunnel sends, and one from the selected LAN traffic to your internet interface list (the second is added in the all, devices and services modes). We did not run the first of these.
  4. Fasttrack exemptions for flows to and from the container, placed above the fasttrack-connection rule.
  5. Check IPv6. The tunnel is IPv4 only. Per the help page, the all mode refuses the LAN's IPv6; the other modes only report it.
  6. Verify with a steady probe instead of the page load in the help page's check: keep a 100 ms ping running from a LAN device, stop the tunnel, and treat replies that keep arriving after the stop as a leak. Keep it running for at least a minute after the stop. Each stop run reported here watched about 75 s, because a shorter watch can mistake a silent gap for a working kill switch. The blackhole configurations went silent after 2 or 3 in-flight replies within 0.2 s and stayed silent.

How do I test a MikroTik kill switch for leaks?

Run a steady probe from a LAN device, stop the tunnel, and count what still arrives. A steady probe finds the first escaped packet, and a browser page that fails to load does not. On the CHR run, the LAN client used RouterOS's own ping tool through the router's forward path:

/tool/ping 198.51.100.1 interval=100ms count=800

The address is a documentation address that exists only inside the lab. The far side kept a counter rule per arrival interface, so each run ended with two numbers that add up to the probes that reached the lab host: probes that came over the tunnel and probes that came over the WAN link. Here are the counter totals from a leaking run and a closed run, both with the router's own interface stopped:

c0-local-down                 policy routing only         WAN 706   tunnel 94
c2-checkgw-blackhole-local    check-gateway + blackhole   WAN 0     tunnel 94

With no kill switch and the router's own tunnel interface stopped, 800 probes returned 800 replies, and 706 of them arrived over the WAN link. The router was healthy and the tunnel was gone. The traffic carried on regardless. Nothing told it not to.

Stop the peer instead, and the same router behaved differently: 58 replies in the whole run, 12 of them after the stop, none over the WAN link, then silence. The route stayed active into a dead tunnel, so packets went nowhere. That is a failure of a different kind, and not a leak.

Which MikroTik kill switch rule actually stops the leak?

The blackhole route did the work in our run, and the health check alone did not. Each layer closes one gap and leaves another open, so test a rule copied from a forum thread before you trust it.

In this native-WireGuard run the blackhole held on its own in both stop modes. The case it leaves open is the untested container one, which the script covers with its own drop rule. This table shows what each layer did.

LayerLocal interface stoppedPeer stoppedWhat it leaves open
Policy routing only706 probes over WAN0 over WAN, silenceLocal tunnel loss falls back to the main table
Health check on the tunnel route only744 probes over WAN405 over WAN after about 30 s of silenceIt makes the route go inactive, and an inactive route is the leak
Blackhole fallback, distance 100 over WAN0 over WANA container that still answers ping while its own tunnel is down keeps the tunnel route active, so the blackhole never takes over
Drop rule above the fasttrack exemption0 over WANnot runCovers the device or address it names, nothing else
Probes that arrived over the WAN link, out of 800, with the router's tunnel interface stopped. The same numbers are in the table above and in the text.
Three behaviours after the stop. Policy routing only leaked from the first probes, the health check alone, with the peer stopped, was silent for about 30 s and then leaked, and the blackhole configurations went silent within 0.2 s.

Read the second row twice. A health check on the tunnel route sounds like the kill switch, and on its own it is the opposite. It turns a dead tunnel into an inactive route, and an inactive route is exactly what lets marked traffic fall back to the WAN.

The blackhole route sits in the same routing table at distance 10, so it is inactive while the tunnel route is healthy. When the tunnel route goes inactive, the blackhole becomes the best route in that table. The marked packets are dropped there instead of falling through to the main table.

It held with or without the health check, in both stop modes, with 0 probes over the WAN link.

So is check-gateway enough for a MikroTik kill switch? No. And in this lab we could not show that it adds anything the blackhole does not, so we do not recommend it as a kill switch.

Where must the drop rule sit relative to fasttrack?

The drop rule has to sit above the firewall rule that lets marked flows skip fasttrack, because RouterOS evaluates forward-chain rules from the top and stops at the first rule that matches and accepts the packet. Put the drop below that accept and marked packets never reach it.

We ran the negative control to see this happen. A tunnel-only drop rule (the kind that keeps a named device off the WAN) was placed in two positions on the same router with the local interface stopped. In both runs the health check was on and the blackhole route was disabled, so the result belongs to the drop rule.

  • Above the exemption: 0 of 800 probes leaked.
  • Below the exemption: 706 left over the WAN link.

The rule was present, and it was never reached.

That is why the order matters when you add a rule of your own. Run /ip/firewall/filter/print and read the order: a drop meant to catch marked flows must have a smaller number than the accept that exempts them from fasttrack. The choosing what goes through the tunnel help page has the check that the exemption sits above the fasttrack rule.

How FastTrack skips firewall rules is covered in FastTrack and tunnels on MikroTik. To test any kill switch, see why a kill switch seems not to work.

Does a router kill switch cover IPv6?

Not the rules we ran: in our run IPv6 stayed completely open. Those rules match IPv4 only. All 800 IPv6 probes in the run, before and after the stop, arrived over the WAN link, because IPv6 never used the tunnel at any point. The full IPv4 set was in place and the local tunnel interface was stopped partway through.

If your router has working IPv6, a device you selected for the tunnel can still reach destinations over IPv6, around it. The help page's step 3 shows how to check whether the router advertises IPv6 and has a default route. The script's all mode refuses the LAN's IPv6; in the other modes you either give IPv6 its own rules or stop advertising it on that LAN. Which one is your call.

Does the same rule work for native WireGuard and a container client?

The shape is the same: a routing table whose only ways out are the tunnel or nowhere. We ran it with native RouterOS WireGuard, the interface type described on MikroTik's WireGuard page, because the CHR we used had container mode off. A container client, from the RouterOS container package, sits behind a virtual ethernet pair (veth) and answers from its own address on a small private link.

That difference is why the script adds a drop for new connections that come back out of the container's veth from anything but the container itself, which this lab did not run. A container can answer a ping from the router while its own tunnel is down, then hand the traffic back to the router. The health check sees a live gateway and the blackhole stays inactive.

We tested the two routing layers and the rule-order effect. We did not test this case.

If you run the ForestVPN container, the install guide and choosing what goes through the tunnel come first: the install guide, because the routing script needs the container's veth-fvpn, and the choose-traffic page, which explains the modes. The kill switch feature page describes the product side.

How do you undo a MikroTik kill switch?

Remove the objects the routing script created; they all carry a comment that starts forestvpn. The help page has the commands under "Undo it": they remove the mangle, filter, NAT, IPv6 filter and routing rules, the via-fvpn routes and table, and the direct address list. The container's own objects stay.

Undo it first, before you take the container down for a long stop, or the LAN devices you chose are cut off until you do. In all mode, also set the LAN's DHCP DNS back to the value the script printed.

What can a MikroTik kill switch not protect?

A kill switch on a router covers only the traffic you selected, not the router's own traffic and not the rest of your network, and it is not absolute. This run also did not test the following. That list matters more than the numbers.

  • Hardware. This was a CHR under software emulation, and a real router's timing will differ.
  • The container. Container mode was off, so no veth, no ForestVPN image, and not the veth drop rule.
  • A client that keeps answering ping while its own tunnel is down, the case the script's veth drop is written for.
  • Traffic other than ICMP, DNS behaviour, and longer outages.
  • Repeats. Each configuration ran once per stop mode.

It stops packets the rules can see. It will not tell you why the tunnel is down.

For that, start with the troubleshooting help page. The guide for a VPN that connects but loads nothing covers the app-side messages. If you are still deciding between router platforms, MikroTik vs OpenWrt lays out what each one needs.

Questions and answers

How do I make a VPN kill switch on RouterOS 7?

Paste the routing script from the router's status page on the router that routes your LAN. It builds the kill switch: a via-fvpn routing table with a blackhole route behind the container, a rule that never lets a marked packet fall back to the main table, forward drops, and a fasttrack exemption. The MikroTik kill switch help page lists the pieces and the leak test.

Why does my traffic leave over the WAN when the tunnel is down?

When a route goes inactive, the packets that were marked for it fall back to the main routing table, and the main table has a default route out of the WAN. In our run that sent 706 of 800 probes out over the WAN link. A blackhole route in the same table gives the packets a place to die instead.

Where must the drop rule sit relative to fasttrack?

Above the accept rule that lets marked flows skip fasttrack. Below it, marked flows are accepted before the drop is evaluated. In our run the same rule leaked 0 probes above the exemption and 706 below it.

How do I test a MikroTik kill switch?

Run a steady probe from a device on the LAN to a lab host, stop the tunnel after ten seconds, keep probing for a minute, and count the probes that arrive over the WAN link. A browser page that fails to load is a weaker test, because it cannot tell you when the first packet escaped.

Does a router kill switch cover IPv6?

Not the IPv4 rules we ran. In our run, all 800 IPv6 probes, before and after the stop, reached the lab host over the WAN link, because IPv6 never used the tunnel. The tunnel is IPv4 only: the script's all mode refuses the LAN's IPv6, and its other modes only report it, so check whether your router routes IPv6.

Does the same rule work for native WireGuard and a container client?

The routing and firewall rules are the same shape, because both put a tunnel behind a routing table. We ran the native WireGuard case. The drop rule the script adds for traffic the container hands back was not part of the run.

Sources

  1. MikroTik documentation: WireGuard (read October 16, 2026)
  2. MikroTik documentation: Container (read October 16, 2026)

How this was made

Drafted with AI assistance from a lab run we did on 2026-10-16 on a RouterOS CHR, checked by automated gates and an editor; the run used native WireGuard, not the ForestVPN container.

All posts

Back to top

Ask us anything