Меню
Контакты
109147, Москва, ул.Воронцовская, 35Б, корп.2 офис.11, 4 этаж
Пн-Пт: с 9-00 до 17-00   Сб-вс: выходной
Интернет-магазин
сетевого оборудования
Москва +7 (495) 103-41-03 +7 (915) 420-28-94
109147, Москва, ул.Воронцовская, 35Б, корп.2 офис.11, 4 этаж
Пн-Пт: с 9-00 до 17-00   Сб-вс: выходной
Заказать звонок

Скрипт, который пишет другой скрипт и настраивает роутеры

 06 Фев 2017    MikroTik, О настройках и установке оборудования производителя Mikrotik, Scripts

Производители сетевого оборудования потихоньку двигаются в сторону универсального API для настройки и сбора показателей: есть NETCONF, OpenConfig, существует ПО для импорта MIB, та же настройка с помощью SNMP существует давно. Но я не буду касаться этих высоких материй, а просто поделюсь способом автоматизировать настройку сетевого оборудования – на случай массового открытия филиалов.

Для иллюстрации использую D-Link DFL-800 в воображаемом центральном офисе и MikroTik RB951UI-2HnD на периферии. В частности, настроим между ними туннель IPsec, раз уж речь про сценарий с новым филиалом.

Настройка MikroTik

Проще всего настраивать MikroTik с помощью конфигурационного файла, который представляет собой скрипт с набором консольных команд. Описываемый принцип настройки подойдет и для других маршрутизаторов с аналогичным механизмом задания параметров.

Прежде всего получим конфигурационный файл уже настроенного и работающего MikroTik, с помощью команды /export. Файл будет практически идентичен бэкапу, но в нем не будет имен пользователей и MAC-адресов.

Чтобы применить конфигурационный файл на другом роутере, часть параметров нужно изменить на уникальные. Для этого подойдут возможности встроенного в прошивку скриптового языка – в частности, вынос индивидуальных настроек в переменные. Вот пример скрипта с назначением шлюза по умолчанию:

local Gate "10.1.3.1"

/ip route

:if ([:len [/ip route find distance=1]] = 0) do={add distance=1 gateway=$Gate;

} else={set [find distance=1] gateway=$Gate}

Изначально была идея создать универсальный скрипт, который можно применять без сброса конфигурации. Поэтому в коде проводится проверка на наличие маршрута по умолчанию, после чего он создается с нуля или меняется. Но от этой идеи пришлось отказаться, поскольку в свежих прошивках в конфигурацию по умолчанию постоянно добавляются изменения. Предусмотреть все нереально, а при постоянном обновлении скрипта теряется смысл автоматизации.

Индивидуальные параметры роутера удобнее задавать не в текстовом файле, а в GUI – тогда с настройкой маршрутизатора справятся даже незнакомые со спецификой устройства люди. То что нужно для удаленного офиса, который могут обслуживать сотрудники разной квалификации.

GUI я отрисовываю в скрипте, разработанном на AutoIT. В этот скрипт я также добавил функцию пересчета масок сети (255.255.255.0 = /24) и построчное заполнение конфигурационного файла. Сам инструмент разработки для решения задачи не принципиален – можно использовать и что-то более привычное лично вам.

Скрипт для настройки MikroTik RB951UI-2HnD

Получившийся интерфейс настройки

Разберем подробнее функцию, которая формирует окно.

Для работы всех функций будущего конфигуратора потребуются следующие библиотеки, в основном из комплекта AutoIT:

  • RandomString для генерации ключа IPsec;

  • GuiIPAddress для формы ввода IP-адресов;

  • GUIConstantsEx для работы GUI;

  • File для работы с файлом.

С принципами работы с графическим интерфейсом в AutoIT можно ознакомиться в официальной документации, я же сразу перейду к результату:

$hgui = GUICreate("МикроТик" , 300, 600)

GUICtrlCreateLabel("введите локальный адрес роутера",2,2)

$iploc1 = _GUICtrlIpAddress_Create($hgui, 10, 20)

GUICtrlCreateLabel("введите локальную маску",2,55)

$iplocnet1 =  _GUICtrlIpAddress_Create($hgui, 10, 75)

GUICtrlCreateLabel("введите внешний адрес",2,115)

$ipext1 =  _GUICtrlIpAddress_Create($hgui, 10, 135)

GUICtrlCreateLabel("введите  внешнюю маску",2,170)

$ipextnet1 =  _GUICtrlIpAddress_Create($hgui, 10, 190)

GUICtrlCreateLabel("введите  шлюз",2,225)

$ipgate1 =  _GUICtrlIpAddress_Create($hgui, 10, 245)

GUICtrlCreateLabel("введите ДНС1",2,280)

$DNS11 =  _GUICtrlIpAddress_Create($hgui, 10, 300)

GUICtrlCreateLabel("введите ДНС2",2,335)

$DNS21 =  _GUICtrlIpAddress_Create($hgui, 10, 355)

GUICtrlCreateLabel("введите ключ на ипсек",2,390)

$secret1 =  GUICtrlCreateInput("",10, 410)

GUICtrlCreateLabel("введите порты для банка через запятую",2,445)

$ports1 =  GUICtrlCreateInput("5000,8000",10, 480)

GUICtrlCreateLabel("введите мак кассы через:",2,515)

$mac1 = GUICtrlCreateInput("00:00:00:00:00:00",10, 535)

$OK_Btn = GUICtrlCreateButton("Поехали", 75, 570, 70, 25)

_GUICtrlIpAddress_Set($iploc1, $iploc8)

_GUICtrlIpAddress_Set($ipext1, $ipext8)

_GUICtrlIpAddress_Set($iplocnet1, "255.255.255.0")

_GUICtrlIpAddress_Set($ipextnet1, "255.255.255.252")

if $secret8 = "" Then

   GUICtrlSetData($secret1,_Crypto_GetRandomString(12,7))

Else

   GUICtrlSetData($secret1,$secret8)

EndIf

GUISetState(@SW_SHOW)

While 1

   $msg = GUIGetMsg()

   Select

      Case $msg = $GUI_EVENT_CLOSE

         Exit

      Case $msg = $OK_Btn

;при нажатии кнопки "Поехали" считываем значения в переменные

         $iploc=_GUICtrlIpAddress_Get($iploc1)

         $iplocnet=_GUICtrlIpAddress_Get($iplocnet1)

         $DNS1=_GUICtrlIpAddress_Get($DNS11)

         $DNS2=_GUICtrlIpAddress_Get($DNS21)

         $ipext=_GUICtrlIpAddress_Get($ipext1)

         $ipextnet=_GUICtrlIpAddress_Get($ipextnet1)

         $ipgate=_GUICtrlIpAddress_Get($ipgate1)

         $secret=GUICtrlRead($secret1)

         $ports=GUICtrlRead($ports1)

         $mac=GUICtrlRead($mac1)

         $iploc2=_GUICtrlIpAddress_GetArray($iploc1)

         ;в организации адреса банковских терминалов статические

         $ipterm1 = $iploc2[0] & "." &$iploc2[1] & "." &$iploc2[2] & ".210"

         $ipterm2 = $iploc2[0] & "." &$iploc2[1] & "." &$iploc2[2] & ".220"

         if $iploc = 0 or $iplocnet=0 or $DNS1=0 or $DNS2=0 or $ipext=0 or $ipextnet=0 or $ipgate=0 or StringLen($secret)=0 then

            MsgBox(4160, "Information", "поля не заполнены")

         else

            GUIDelete()

            ExitLoop

         EndIf

   EndSelect

 WEnd

Дальше логика работы программы следующая: новый текстовый файл построчно заполняется полученными значениями с помощью FileWriteLine. Полученный скрипт-конфиг можно переносить на MikroTik.

Полный листинг функции

Осталось выполнить на MikroTik получившийся скрипт после сброса конфигурации, любым удобным способом: через /system script, использовать сохраненный файл и сбросить конфигурацию так, как показано на картинке:

Скрипт для настройки MikroTik RB951UI-2HnD

Теперь для настройки нового MikroTik достаточно запустить программу, указать индивидуальные настройки в GUI, получить скрипт настройки и передать его маршрутизатору. Осталось довести до ума настройку маршрутизатора в предполагаемом центральном офисе.

Настройка D-Link DFL

Настройку DFL удобнее производить через консоль. Такой тип настройки тоже поддается автоматизации, например с использованием инструмента Plink от создателя Putty.

Концепцию передачи команд в открытое консольное нельзя назвать идеальной, но в случае с D-Link DFL можно использовать его собственные "скрипты". В качестве примера разберем функцию, которую использую в паре с ранее описанной. Если MikroTik нужно настраивать с нуля, то на DFL достаточно создать туннель IPsec и включить его в группу интерфейсов для применения правил встроенного брандмауэра.

Скрипт для настройки MikroTik RB951UI-2HnD

Окно настроек заметно проще, ведь DFL в нашем случае не нужно настраивать с нуля

Для доступа к маршрутизатору по SSH понадобится Plink, а также Pscp для передачи файлов – достаточно просто прописать в скрипте пути к исполняемым файлам.

local $_plink_loc = "\\server\share\plink.exe"

local $scploc="\\server\share\pscp.exe"

При работе Plink и Pscp есть особенность: если используется парольная авторизация, то при первом подключении или замене оборудования появится запрос о внесении отпечатка в реестр. Обойти запрос можно передачей "Y" в консольное окно.

$_plinkhandle = Run(@comspec & " /c " & $_plink_loc & " -ssh admin@" & $_plinkserver &" -pw MegaPass","",@SW_HIDE,7)

sleep (500)

StdinWrite($_plinkhandle, "y"& @CR)

DFL работает с объектами на уровне групп. Так как нельзя добавить объект в группу без перечисления всех ее членов, я генерирую на DFL создающий группу скрипт, забираю его в виде файла и изменяю. Создать скрипт можно следующей командой:

script -create InterfaceGroup VPNs -name=vpns.sgs

Результат можно забрать по SCP. Файл я переименовываю в script.sgs и добавляю в него другие команды для создания новых объектов, после чего импортирую результат на D-Link по SCP и применяю конфигурацию.

script -execute -name=script.sgs

После применения конфигурации уже ненужный скрипт можно удалить командой

script -remove -name=script.sgs

Полный листинг функции

Кстати, в процессе обнаружилось решение и для резервного копирования конфигурации.

Пасхалка: резервное копирование D-Link DFL

В процессе отладки в корне структуры DFL обнаружились два файла: full.bak и config.bak. Несложно догадаться, что это полный бэкап системы и копия конфигурации. Для создания полноценной резервной копии устройства достаточно подключиться по SCP и скопировать оба файла. В этом же скрипте резервного копирования можно написать нечто вроде политики хранения – удалять файлы старше двух недель.

#include <Date.au3>

#Include <File.au3>

Local $_plinkserver = "адрес dfl"

local $scploc="\\server\share\pscp.exe"

local $path=@ScriptDir&"\"

$date1=@YEAR&@MON&@MDAY

local $file = $path &"config-"&$date1&".bak"

$handle=Run(@comspec & " /c " & $scploc & " -pw MegaPass admin@"&$_plinkserver&":config.bak " & $file,"",@SW_HIDE,7)

sleep (500)

StdinWrite($_plinkhandle, "y"& @CR)

sleep (500)

$file =  $path &"full-"&$date1&".bak"

RunWait(@comspec & " /c " & $scploc & " -pw MegaPass admin@"&$_plinkserver&":full.bak " & $file,"",@SW_HIDE,7)

;чистим старые бэкапы

;если бэкапов нет, то лучше ничего не чистить

if FileExists($path &"full-"&$date1&".bak") and FileExists($file = $path &"config-"&$date1&".bak") Then

$files = _FileListToArray($path, "*.bak", 1,True)

$date=@YEAR&"/"&@MON&"/"&@MDAY

$newdate=_DateAdd("D",-14,$date)

$formatdate=StringSplit($newdate,"/")

$newdate=$formatdate[1]&$formatdate[2]&$formatdate[3]&@HOUR&@MIN&@SEC

If IsArray($files) Then

   For $i = 1 To UBound($files) - 1

      $aTime = FileGetTime( $files[$i], 0, 1)

       If $aTime < $newdate Then 

            FileDelete($files[$i])

       EndIf

   Next

EndIf

EndIf

Скрипт для настройки MikroTik RB951UI-2HnD

Скрипт успешно бэкапит любые модели DFL.

Итого

Конечно, эти два способа настройки не претендуют на лучшие практики, а кто-то даже назовет их костылями. Для небольших и разовых изменений конфигурации проще использовать SNMP или специальный API от производителя. Но даже изобретение своего велосипеда сэкономило массу времени на просьбах помочь с настройкой от ранее не работавших с Mikrotik коллег. Опять же, меньше шанс ошибиться.

Используемый материал