ВОЙТИ
    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 провайдера.