opened image

Как создать телеграм бота для мониторинга Mikrotik, размещенного за NAT провайдера

В большинстве случаев домашние маршрутизаторы недоступны из интернета, что не позволяет их настраивать и мониторить удаленно. Сокрытие устройств за NAT - обычнвая практика провайдеров, предоставляющих услуги домашнего интернета, обусловленная, в том числе вопросами безопасности. 

 

В данной статье рассмотрим вопрос мониторинга доступности роутера Mikrotik, который размещен за NAT Вашего интернет-провайдера .

 

Существует несколько (на самом деле, больше) способов, позволяющих решить вопрос мониторинга роутеров или даже их удаленного управления.:

 

1. Вы можете приобрести у провайдера услугу "белого IP" (публичный IP адрес, виден из интернета). Вероятно, это самый простой и достаточно недорогой способ решить вопрос мониторинга и управления своим домашним роутером так как он будет доступен по предоставленному белому IP из любой точки интернета. Этот способ подойдет практиески для всех моделей роутеров так как не требует дополнительных настроек на самом роутере. Минус этого решения в том, что на Вас ложаться вопросы организации безопасности как самого роутера так и Вашей домашней сети и всех устройств в ней. Кроме того, далеко не все провайдеры предоставляют услугу белого IP.

 

Если у Вас уже есть белый IP, для создания мониторинга роутера с помощью телеграм бота, можно воспользоваться инструкцией: Как создать телеграм бота для мониторинга удаленных хостов.

 

2. Организация своей VPN сети на VPS сервере. Конфигурация и утановленное ПО на сервере, как правило,  не имеют значения. В этом случае, на сервере достаточно установить VPN сервер (например, WireGuard), а на Mikrotik настроить VPN клиент WireGuard (доступен с 7-й версии RouterOS). После чего, роутер станет доступен во внутренней сети VPS сервера.  Способ требует дополнительных настроек VPN сети и организации мониторинга внутри этой сети (например, bash или python скриптом).

 

3. Обеспечить возможность периодически оставлять роутером "след" в виде записей в файле лога на удаленном сервере. После чего, на сервере проводить анализ этих записей python-скриптом (мы будем использовать именно python) для организации отправки собщения в телеграм в случае, если Mikrotik не отставил "след" в заданный период времени. 

 

Для реализации этого способа, необходимо сделать минимальные  настройки на роутере и разместить готовый python-скрипт на VPS сервере. На VPS сервере должен работать веб-сервер и размещен какой-либо сайт или создан сайт-по умолчанию (сайт-заглушка), который открывается по IP сервера. 

 

В нашем примере используется виртуальный сервер с операционной системой CentOS7 и панелью управления VestaCP. 

Приступим к реализации.

 

1. Настройка Mikrotik

 

Для изменений на роутере будем использовать стандартную программу WinBox.

 

1.1 Включим DDNS на тот случай, если интернет-провайдер практикует смену внешнего IP

IP - Cloud - DDNS Enabled

 

 

DNS Name - не изменяющиеся (в отличие от внешнего IP) имя Вашего роутера. Сохраните значение этого поля, понадобиться для нашего скрипта мониторинга. 

 

Обратите внимание, роутер сам укажет на то, что находится за NAT и соединение с ним извне может быть недоступно.

 

1.2 Создадим скрипт, в котором роутер будет делать попытку отправить на сервер по http (или https) пустое значение методом post. 

 

System - Scripts - Add (+)

Name: задайте произвольное название скрипта (латиницей)

Source: прописываем скрипт

/tool fetch http-method=post url="https://11.22.33.44/"

 

 

Где 11.22.33.44 - IP сервера, где будет работать скрипт мониторинга. Обратите внимание, что значение url также может содержать ссылку на конкретный сайт, который размещен на этом же  сервере. От этого значения будет зависеть, какой журнал лога на сервере необходимо указать для анализа. Расмотрим вариант с указанием IP сервера. В этом случае будет использоваться лог сайта по умолчанию (или сайт-заглушка)

 

1.3 Создадим задание планировщика для запуска только что созданного скрипта с определенной периодичностью.

 

System - Scripts - Add (+)

Name: задайте произвольное название задания планировщика (латиницей)

Interval: задайте периодичность запуска скрипта  (например, раз в 30 секунд)

On Event: прописываем строку запуска ранее созданного скрипта

 

/system script run web_label

 

 

Теперь роутер раз в 30 секунд будет делать попытку отправить на сервер post запрос, оставляя в журнале на сервере "след" о себе. 

 

2. Настройка сервера и размещение скрипта мониторинга

 

2.1 Создайте в панели VestaCP сайт заглушку, используя Инструкцию.

 

2.2 Создайте телеграм бота и канал для размещения уведомлений, выполнив пункт 1 из Инструкции, после чего из этой же инструкции выполните пункт 2 для подготовки сервера и пункт 3 для запуска скрипта: но в файле main.py вставьте такой код скрипта:

 

import os
import socket
import requests
import datetime
import time
from datetime import timedelta
#------------------------
logfile = '/var/log/httpd/domains/site.plug.log';  #log-file сайта-заглушки 
hostname = 'f1*********b.sn.mynetname.net'    #RouterOS DDNS (IP - Cloud)
time_period = 30    #равно периоду запуска скрипта в планировщике на RouterOS
time_pause = 60    #секунд, периодичность проверки 
#-----------------------
def SendMsgToTelegramChanel(msg):
    token="TOKEN"
    chat_id = 'CHAT_ID'
    params = {'chat_id': chat_id,'text': msg}
    response = requests.get('https://api.telegram.org/bot'+token+'/sendMessage', params=params)

def GetIP(hname):                         #resolv hostname to IP 
    ips = ''
    try:
        ips = str(socket.gethostbyname(hname))
        if ips not in lastips:
            lastips.append(ips)
            print(ips,'was added to previous IPs list')
    except socket.gaierror as e:
        print(hname,'hostname Error')
        pass
    return ips

def CheckPeriod(lfile, hip, tperiod):
    res = [False,'']
    if os.path.exists(lfile):
        lstr =  os.popen("grep 'Mikrotik' " + lfile + " | tail -1 | awk -F' ' '{print $1,$4}'").read()
        if lstr != '':
            
            #get ip from log
            logip = lstr.split(' ')[0]
            if (hip != logip):
                print('Old IP: ' + logip + ', new IP: ' + hip) 
            
            # get last time from log
            now = datetime.datetime.now().time()
            nowtime = timedelta(hours = now.hour, minutes = now.minute, seconds = now.second)
            lasttime = nowtime
            indx = lstr.find(':') + 1
            if (indx > 0):
                ctime = lstr[indx:indx+8]
                ctime = ctime.split(':')   # hour = ctime[0], minutes= ctime[1], secund = ctime[2]
                lasttime = timedelta(hours = int(ctime[0]), minutes = int(ctime[1]), seconds = int(ctime[2]))
                res[1] = str(lasttime)
            rtime = nowtime - lasttime

            #check 
            if ((hip == logip) or (hip in lastips)) and (int(rtime.total_seconds()) <= tperiod):
                res[0] = True

        else:
            res[1] =  'notag'
            print('Mikrotik tag not found in log file')                    
    else:
         print('File not found:',lfile)
    return res

#-----------------------------------------------------------------------------------
print(datetime.datetime.now(),'start monitoring:')
chklabel = False 
lastips = []       #last IPs

while True:
    hostip = GetIP(hostname)
    chkperiod =  CheckPeriod(logfile, hostip, time_period)

    if (hostip == '') or (chkperiod[1] == ''):
        break

    if (chkperiod[0] == True and chklabel == True):
        chklabel = False
        SendMsgToTelegramChanel('Mikrotik is UP at ' + chkperiod[1] )
        print(datetime.datetime.now(),' ' + hostname + ' is UP at ' + chkperiod[1] )
    if (chkperiod[0] == False and chklabel == False):
        chklabel = True
        SendMsgToTelegramChanel('Mikrotik is DOWN at ' + chkperiod[1] )
        print(datetime.datetime.now(),' ' + hostname + ' is DOWN at ' + chkperiod[1])    

    time.sleep(time_pause)

 

Обратите внимание на переменные в скрипте:

 

logfile = '/var/log/httpd/domains/site.plug.log' - содержит значение пути до файла журнала сайта-заглушки. Именно в этом файле роутер Mikrotik должен оставлять запись раз в 30 секунд.

 

hostname - тут укажите значение поля DNS Name (WinBox - IP -Cloud). 

 

token и chat_id получаем из созданных ранее соответствующих значений телеграм бота.

 

В результате, Вы можете мониторить 24/7 доступность роутера Mikrotik, который находится за NAT провайдера.