Monitoring your internet connections with OpenWRT and a Telegram Bot
For the past 5 years or so, I have been using a single ISP at home and mobile data for backup when it went down. But since last few months, the ISP service became a bit unreliable – this is more related to the rainy season. Mobile data doesn’t give fiber like constant speeds I get on the wire. It’s very annoying to browse at < 10 Mbps on mobile data when you are used to 100 Mbps on the wire.
I decided to get another fiber pipe from a local ISP. One needs to be very unlucky to have both going down at the same time – I hope that never happens. Now the question is how to monitor the two connections: Why do I need monitoring? – so that I can inform the ISP when it goes down, with the fail-over happening automatically thanks to OpenWRT’s mwan3 package, I won’t ever know when I am using which ISP (unless I am checking the public IP address, of course).
The solution: A custom API and a Telegram bot. For those not aware about Telegram, it is an amazing messaging app just like Whatsapp with way more features (bots, channels), and does away with some idiosyncrasies of Whatsapp such as restricting you to always have the phone connected.
A Telegram bot is fairly simple to write, you just have to use their API. Now this bot is just going to send me messages, I am never going to send any to it, so implementing my WAN monitor bot was very easy.
My router is a TP Link WR740N which has 4 MB flash – so it is not possible to have curl with SSL support which is required by the API. I wrote a custom script which can be called over HTTP and plays well with the default wget. The script is present on a cloud server which can, obviously, do the SSL stuff.
A custom wrapper to Telegram API to send message in PHP:
<?php
$key = '<a random key>';
if ($_REQUEST['key'] != $key) {
die("Access Denied");
}
$interface = $_REQUEST['interface'];
$status = $_REQUEST['status'];
$interface_map = array(
'wan1' => 'ISP1',
'wan2' => 'ISP2'
);
$status_map = array(
'ifdown' => 'Down',
'ifup' => 'Up'
);
$message = "TRIGGER: ${interface_map[$interface]} is ${status_map[$status]}";
$ch = curl_init("https://api.telegram.org/bot<bot ID>/sendMessage");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, array(
'chat_id' => '<your chat id>',
'text' => $message
));
curl_exec($ch);
The <your chat id> part needs to be discovered once you send a /start command to your bot and use Telegram’s getUpdates method. You will get it in API’s response JSON. $key is just a security check to prevent external attacks on the script.
And this script is called on interface events by mwan3 (/etc/mwan3.user ):
wget -O /dev/null "http://<server ip address>/wanupdate.php?interface=$INTERFACE&status=$ACTION&key=<your random key>" >/dev/null 2>/dev/null &
Shell script to monitor connections by cron directly from the server:
#!/bin/bash
nc -w 2 -z <ip address> <port number>
isp1_status=$?
nc -w 2 -z <ip address> <port number>
isp2_status=$?
sendmsg() {
curl https://api.telegram.org/bot<bot id>/sendMessage -d chat_id=<chat id> -d text="$1" &> /dev/null
}
if [[ $isp1_status -ne 0 ]]; then
sendmsg "MONITOR: ISP1 is Down"
fi
if [[ $isp2_status -ne 0 ]]; then
sendmsg "MONITOR: ISP2 is Down"
fi
The above script uses netcat to do the link test using a TCP connection to a port number which is port forwarded to a server because I found ping was doing some false positives. I couldn’t reproduce it when I was trying it manually but I used to get DOWN messages even though the connection was working.
One must wonder though, how will the message reach me via Telegram when both ISPs go down at the same time – well I leave that job to Android and mobile data. Android switches to mobile data as soon as it finds WiFi doesn’t have internet access.
Hi there Nilesh. This seems to be exactly what I need. But I’m a bit of a beginner in these things. I do have some knowledge of OpenWRT and SSH commands (I’ve managed to install and run p910nd & sane printer/scanner server on my router and my AIO printer). I’m sure I can find way to utilize the Telegram bot. But I’m a bit stumped on the mwan3 and your cron script. Could you provide a step by step how the set up this up in OpenWRT for this purpose?
LikeLike
Which part of my article is confusing? I’ll try to fix the same.
LikeLike