Community discussions

MikroTik App
 
droux
just joined
Topic Author
Posts: 1
Joined: Tue Feb 08, 2022 12:09 pm

Detecting Internet connection

Tue Feb 08, 2022 12:31 pm

I am on routerOS 7.1.

Question: How do I check for an active Internet connection, if I cannot do UDP, and /ping has no useful return code?

This is proving way harder than I would have expected. The /ping command does not have an exit code that I can check (!)

First, following https://help.mikrotik.com/docs/display/ ... t+Internet cannot work. Because UDP is blocked by my provider, so it never switches from wan to internet:

[admin@MikroTik] /interface/detect-internet/state> print
Columns: NAME, STATE, STATE-CHANGE-TIME
#  NAME              STATE    STATE-CHANGE-TIME
0  wlan1             no-link  feb/07/2022 13:23:20
1  lte1              wan      feb/07/2022 13:23:26

Next I tried /ping.
And /ping gives me different results from what these forums tell me I should expect. Maybe a v7+ issue? This is what I see:

For a valid IP:

[admin@MikroTik] > :set $pingResult [:ping count=1 1.1.1.1]
Columns: SEQ, HOST, SIZE, TTL, TIME
SEQ  HOST     SIZE  TTL  TIME
  0  1.1.1.1    56   51  118ms503us

[admin@MikroTik] > :put [:typeof $pingResult ]
nothing

For an invalid IP:

[admin@MikroTik] > :set $pingResult [/ping count=1 172.1.1.1]
Columns: SEQ, HOST, STATUS
SEQ  HOST       STATUS
  0  172.1.1.1  timeout

[admin@MikroTik] > :put [:typeof $pingResult ]
nothing

... which means there is no way for me to check the exit code of the /ping command?

This is what I am seeing because of that, and it blows my mind:

[admin@MikroTik] > :if ([/ping 1.1.1.1 count=1] = 1) do={:put "Down"} else={:put "Up"}
Columns: SEQ, HOST, SIZE, TTL, TIME
SEQ  HOST     SIZE  TTL  TIME
  0  1.1.1.1    56   51  134ms149us

Up
[admin@MikroTik] > :if ([/ping 172.1.1.1 count=1] = 1) do={:put "Down"} else={:put "Up"}
Columns: SEQ, HOST, STATUS
SEQ  HOST       STATUS
  0  172.1.1.1  timeout

Up
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3357
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Detecting Internet connection

Tue Feb 08, 2022 3:55 pm

Have you looked at the netwatch function?

https://www.youtube.com/watch?v=UgKfkhyynKk
 
majestic
Member Candidate
Member Candidate
Posts: 109
Joined: Mon Dec 05, 2016 11:19 am

Re: Detecting Internet connection

Sun Oct 27, 2024 9:46 pm

I wanted to share my experience with using Netwatch on MikroTik routers for failover scenarios and offer an alternative approach that I've found more effective.

Problem with Netwatch:
Netwatch has limitations when it comes to testing specific interfaces, unlike the ping tool. While it's possible to use Netwatch in conjunction with IP route rules to achieve similar functionality, I found that method quite messy. Forcing traffic to a specific IP to route through a designated gateway can complicate the setup unnecessarily.

Although this topic has been discussed before, I wanted to revisit it because I encountered situations where Netwatch simply doesn't meet the needs for clean and effective failover management. Thanks to a command mentioned in a previous post, I was able to devise a straightforward script that utilizes /interface detect-internet state to monitor interface statuses and respond accordingly.

Use Case:
In my setup, I only want the secondary router to activate when the primary WAN/Internet link is down. When the primary link is restored, the secondary router should shut down. This approach helps me conserve bandwidth and power since the secondary router has limited capacity. It's more of an active-cold/standby setup, which fits my needs perfectly. While it takes a few minutes for the secondary connection to come online, it's a worthwhile trade-off for the efficiency it offers.

Here’s the script I’m using:
:local primaryState [/interface detect-internet state get [find name="pppoe0"] state]
:local backupState [/interface detect-internet state get [find name="ether2"] state]
:local powerState [/interface ethernet poe get ether2 poe-out]

# When primary WAN is down
:if ($primaryState != "internet") do={
    # Check if ether2 is not powered on
    :if ($powerState != "auto-on") do={
        /interface ethernet poe set ether2 poe-out=auto-on
        /log info "IntelliFailover: PPPoE interface (pppoe0) is DOWN"
        /log info "IntelliFailover: Switching to backup (ether2) connection"
    }
} else={
    # When primary WAN is restored, check if both interfaces have internet
    :if ($primaryState = "internet" && $backupState = "internet") do={
        # Check if ether2 is powered on
        :if ($powerState != "off") do={
            /interface ethernet poe set ether2 poe-out=off
            /log info "IntelliFailover: PPPoE interface (pppoe0) is RESTORED"
            /log info "IntelliFailover: Restoring primary (pppoe0) connection"
        }
    }
}
I hope this script and approach can help others facing similar challenges. I’d love to hear your thoughts or any improvements you might suggest!
 
User avatar
HoracioDos
just joined
Posts: 20
Joined: Mon Jan 06, 2025 1:05 pm

Re: Detecting Internet connection

Sat Jan 25, 2025 4:09 pm

Hello.
This is my first script to detect internet connection. Please be kind. Any comments about how to improve it are very welcome.
First I've setup internet detection like this:
/interface detect-internet
set detect-interface-list=WAN internet-interface-list=WAN lan-interface-list=LAN wan-interface-list=WAN
Then it executes every 3 minutes via scheduler.

Script check-internet
:global previousState;

:global id [/interface/detect-internet/state find];
:global ifaceName [/interface/detect-internet/state get $id value-name=name];
:global ifaceState [/interface/detect-internet/state get $id value-name=state];
:global ifaceTime [/interface/detect-internet/state get $id value-name=state-change-time];
:global ifaceRTT [/interface/detect-internet/state get $id value-name=cloud-rtt];

:if ($ifaceState != $previousState) do={:set previousState $ifaceState;

:global ms [:pick $ifaceRTT 9 12];
:set ifaceRTT ($ms . "ms");

:global emailBody ("Interfaz: $ifaceName\rEstado: $ifaceState\rUltimo cambio: $ifaceTime\rRTT: $ifaceRTT\rDetect Internet usa cloud.mikrotik.com con el protocolo UDP en el puerto 30000. La conectividad se verifica cada minuto y, si no se alcanza por 3 minutos, el estado cambia de internet a WAN");

:if ($ifaceState = "internet") do={/tool e-mail send to="mail@gmail.com" subject=("Internet Disponible en " . $ifaceName) body=$emailBody;} else={/tool e-mail send to="mail@gmail.com" subject=("Sin Conexion en " . $ifaceName) body=$emailBody;}}
This is the output

No Internet connection
Interfaz: ether1-isp
Estado: wan
Ultimo cambio: 2025-01-23 07:12:12
RTT: ms
Detect Internet usa cloud.mikrotik.com con el protocolo UDP en el puerto 30000. La conectividad se verifica cada minuto y, si no se alcanza por 3 minutos, el estado cambia de internet a WAN
Internet restored

Interfaz: ether1-isp
Estado: internet
Ultimo cambio: 2025-01-23 07:14:09
RTT: 253ms
Detect Internet usa cloud.mikrotik.com con el protocolo UDP en el puerto 30000. La conectividad se verifica cada minuto y, si no se alcanza por 3 minutos, el estado cambia de internet a WAN
Last edited by HoracioDos on Sat Jan 25, 2025 4:14 pm, edited 2 times in total.
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 4502
Joined: Sun May 01, 2016 7:12 pm
Location: California
Contact:

Re: Detecting Internet connection

Sat Jan 25, 2025 6:34 pm

/interface detect-internet
set detect-interface-list=WAN internet-interface-list=WAN lan-interface-list=LAN wan-interface-list=WAN
I'm not sure I'd the use automatically adding interface to WAN or LAN interface list. You already have to interfaces defined as WAN to even use detect-internet. And since detect-interface-list=WAN, it never find LANs anyway. And it adding things to the default LAN or WAN list can have all sorts of side-effects that have to be considered since the firewall uses LAN and WAN interface list as matchers.

So unless you're using the detect-internet state in the firewall rules, you actually don't need to set anything (leave none/blank) expect detect-interface-list=WAN for your script. If you want to the "interface list adding" feature for NEW firewall rules, it be better to use different /interface/list same like internet-interface-list=DETECTED_WAN lan-interface-list=DETECTED_LAN wan-interface-list=DETECTED_WAN - instead of us


:global
ALL the variables can and should be ":local", not ":global", if this is running from /system/scheduler since you're not using them in other scripts (which would need :global).



:global ifaceName [/interface/detect-internet/state get $id value-name=name];
:global ifaceState [/interface/detect-internet/state get $id value-name=state];
:global ifaceTime [/interface/detect-internet/state get $id value-name=state-change-time];
:global ifaceRTT [/interface/detect-internet/state get $id value-name=cloud-rtt];
You actually don't need "value name=" — you just use [/interface/detect-internet/state get $id name] – works same, just short.


:global:local ms [:pick $ifaceRTT 9 12];
:set ifaceRTT ($ms . "ms");
Guessing this works fine. But it's possible RTT might be 0 or something else. So using [:pick] without "protection" may not be best approach...but for an email... it showing ONLY "ms" indicate a problem already


Any comments about how to improve it are very welcome.
I'm not sure many other have braved using, let alone scripting, /interface/detect-internet. But for something like email notification it's likely pretty simple method for checking internet.

Disclaimer: Not recommending using /internet/detect-internet in routing decision or failover...there are better approaches for that. And detect-internet can/does have side-effects – which MT doc's highlight... but many are pretty subtle (and often surprising).

The net is using just "detect-interface-list=WAN" is relatively safe – but when detect-interface MODIFIES your /interface/list like WAN or LAN (or adds DHCP clients), that where the trouble starts. And if interface is "declared" as WAN in /interface/list ... it really should have IP address or DHCP client if you explicitly set an interface to be a WAN, so the "automatic DHCP client" is less problematic there...
 
User avatar
HoracioDos
just joined
Posts: 20
Joined: Mon Jan 06, 2025 1:05 pm

Re: Detecting Internet connection

Sat Jan 25, 2025 11:24 pm

Thank you Amm0 for such a detailed answer.

I started using "detect internet" instead of Netwatch with a ping to Google or Cloudflare because this feature is already built-in and I wanted to take advantage of it. I've read in the manual that "detect internet" could take some automated actions that might alter the current configuration. These potential modifications were never very clear to me, but I still took the risk.

I have some firewall rules based on Interface Lists such as LAN and WAN, so I created a new one named INTERNET and assigned the ether1-ips port. Then I set detect-interface-list=INTERNET and set the other parameters to NONE. If I'm not mistaken, I followed your advice.

I changed all variables to local except previousState, which needs to be global to avoid receiving emails every 3 minutes saying the state is OK. I also made some changes to [:pick $ifaceRTT 9 12] as I didn't like having blanks + ms when there's no internet.

I don't have any other rule to set a failover mechanism. Since I have only one ISP, I will follow your advice not to rely on these decisions in "detect internet".

I have a Raspberry Pi running Zabbix 7.0.X with numerous checks and triggered alerts, but I wanted to start learning MikroTik scripting with a simple use case.

I can't believe how many networking concepts have been clarified to me since I started configuring MikroTik devices. So many features and config decisions are hidden from non-technical users when purchasing simple networking devices.

This is the modified version:
:global previousState;

:local id [/interface/detect-internet/state find];
:local ifaceName [/interface/detect-internet/state get $id name];
:local ifaceState [/interface/detect-internet/state get $id state];
:local ifaceTime [/interface/detect-internet/state get $id state-change-time];
:local ifaceRTT [/interface/detect-internet/state get $id cloud-rtt];

:if ($ifaceState != $previousState) do={:set previousState $ifaceState;

:local ms [:pick $ifaceRTT 9 12];
:if ([:len $ms] = 0) do={
    :set ms "No RTT";
}
:set ifaceRTT ($ms . "ms");

:local emailBody ("Interface: $ifaceName\rState: $ifaceState\rLast change: $ifaceTime\rRTT: $ifaceRTT\rWAN's internet connectivity via cloud.mikrotik.com (UDP:30000) is checked every minute. If unreachable for 3 consecutive minutes, state changes to WAN");

:if ($ifaceState = "internet") do={/tool e-mail send to="mail@gmail.com" subject=("Internet Available on " . $ifaceName) body=$emailBody;} else={/tool e-mail send to="mail@gmail.com" subject=("No Internet connection on " . $ifaceName . "Family will start complaining - run away!") body=$emailBody;}}
Thank you very much for your time answering this post
Regards
H
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 4502
Joined: Sun May 01, 2016 7:12 pm
Location: California
Contact:

Re: Detecting Internet connection

Sun Jan 26, 2025 12:50 am

No I think it's a totally reasonable approach. I use /interface/detect-internet in default config on detect-interface-list=WAN since Mikrotik's mobile app show the internet status on the app main screen...

And correct, it's "safe" as long as as you do NOT set the "three bottom attributes" in detect-internet as those WIRITE the detected interface into an address list - which I believe you've corrected already... See detect-interface-list= just READS the interface list that one attribute controls what is "checked for internet", but it does NOT change any interface lists. So the common mistake is someone set all 4 things, when ONLY detect-interface-list=WAN (or your own custom list of interfaces to check) is needed. The 2nd common one is there is likely no need and bad to ideal to include known LAN (or other internal) network in the detect-interface-list, and again you're good on that one.

On the script, if you want the actual milliseconds... the RTT is a "time" type, so you can convert it nanoseconds (then to ms), which might be more accurate that parsing the string (or at least more resilient to future changes to scripting outputs). But I'm pretty sure your existing code is fine. So more just FYI:

:local ms [:pick $ifaceRTT 9 12];
:if ([:len $ms] = 0) do={
:set ms "No RTT";
}
:set ifaceRTT ($ms . "ms");


could be just:
:set ifaceRTT "$[([:tonsec $ifaceRTT]/(1000*1000))]ms"
 
User avatar
HoracioDos
just joined
Posts: 20
Joined: Mon Jan 06, 2025 1:05 pm

Re: Detecting Internet connection

Sun Jan 26, 2025 1:00 am

:local ms [:pick $ifaceRTT 9 12];
:if ([:len $ms] = 0) do={
:set ms "No RTT";
}
:set ifaceRTT ($ms . "ms");


could be just:
:set ifaceRTT "$[([:tonsec $ifaceRTT]/(1000*1000))]ms"
DONE!!

Thank you again for your time
Regards
H
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 4502
Joined: Sun May 01, 2016 7:12 pm
Location: California
Contact:

Re: Detecting Internet connection

Sun Jan 26, 2025 1:19 am

DONE!!
I guess you could also add one more email when detect-internet goes to "WAN state". This would happen if you can ping google DNS 8.8.8.8, but not reach Mikrotik's servers (via UDP).

The app says something like "Internet (Limited)" if in WAN state, while if "Internet state" reports just "Internet: Good" (or something like that).

So you could cover that the "WAN state" too (just for example on text):

:if ($ifaceState = "wan") do={/tool e-mail send to="mail@gmail.com" subject=("Limited Internet Available on " . $ifaceName) body=$emailBody;} else={/tool e-mail send to="mail@gmail.com" subject=("Limited Internet connection on " . $ifaceName . "Family will start complaining - run away!") body=$emailBody;}}
 
User avatar
HoracioDos
just joined
Posts: 20
Joined: Mon Jan 06, 2025 1:05 pm

Re: Detecting Internet connection

Sun Jan 26, 2025 1:28 pm

Hello Amm0

I agree that not reaching cloud.mikrotik.com might not represent a full internet access problem and the service could just be limited or degraded. According to documentation, there are currently only two possible states (internet and wan), but MikroTik could change this behavior at any time. I will modify the script to avoid the else statement and check the state for the two possible values (Internet and wan), sending emails for Degraded/Limited internet service and Restored/Full Service, and then forget about it. It's a redundant notification method in addition to others already in place.

In the event of a real internet failure, email notification is always received once the internet service is up and running again, and there is no other way to receive a notification via Wi-Fi if a mobile phone is connected to the LAN. I didn't attempt to keep the MikroTik mobile app connected and running in background to verify if a notification is sent to the phone when the internet is down, and I wouldn't like to do it in that way either.

It's the same problem with any observability platform. They need internet access to notify an internet failure (my dog used to chase its own tail better, lol!) unless you have redundant ISP or some LTE service.

It's always a pleasure talking to you gentleman.

Regards
H
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 4502
Joined: Sun May 01, 2016 7:12 pm
Location: California
Contact:

Re: Detecting Internet connection

Sun Jan 26, 2025 4:08 pm

I agree that not reaching cloud.mikrotik.com might not represent a full internet access problem and the service could just be limited or degraded.
Yeah that was my only point that "wan" generally means there is internet. For example, in past /ip/cloud things have gone down for short period of times... which would cause something normally in "internet" state to go to "wan" state.

How you want notify is totally up to you, I just wanted to have some concrete example, adjust as needed. More something to be aware of: i.e., "WAN state" does have working ping to 8.8.8.8, while "Internet state" can echo data via UDP to Mikrotik.

What detect-internet lacks is some kind of NAT type detection, as it be useful to know if it's CGNAT or other NATing scheme since "WAN state" can also happen with otherwise working internet depending on what ISP is doing. Video game consoles often report some kinda "NAT type" - which be useful in RouterOS but lacking.

It's the same problem with any observability platform. They need internet access to notify an internet failure (my dog used to chase its own tail better, lol!) unless you have redundant ISP or some LTE service.
All true. Now there is also narrowband LTE, which KNOT supports, and those SIM are pretty cheap monthly since it limited data. Also, there also LoRaWAN for these types of notification, which KNOT/LtAP/etc support. Certainly more setup, hardware, config, scripting... Anyway, always some solution if something is important.
 
User avatar
HoracioDos
just joined
Posts: 20
Joined: Mon Jan 06, 2025 1:05 pm

Re: Detecting Internet connection

Mon Jan 27, 2025 3:48 pm

All true. Now there is also narrowband LTE, which KNOT supports, and those SIM are pretty cheap monthly since it limited data. Also, there also LoRaWAN for these types of notification, which KNOT/LtAP/etc support. Certainly more setup, hardware, config, scripting... Anyway, always some solution if something is important.
Hello.
You've sparked my curiosity!
Thanks!