Как стать автором
Обновить

Централизованный сбор конфигураций с MikroTik'ов средствами Python

Время на прочтение 4 мин
Количество просмотров 25K

Зачем



С ростом количества сетевых узлов и сложности их конфигурации наверняка у многих возникает вопрос — а если железка умрет, смогу ли я быстро восстановить работу на другой? Если смогу сделать это вручную, то как долго я буду потом отлавливать мелочи, которые забыл?

Процесс гугления привел к пониманию того, что конкретно для этого вендора готовых решений подобного рода нет. То, что было найдено в комьюнити мне не понравилось — предлагали размещать скрипты резервного копирования на самой железке и запускать их по расписанию. По сути задачу это решало, но если у меня несколько десятков единиц оборудования, нащелкивать копипасту по каждому экземпляру — это не по Фен-Шую.

Благо есть небольшой навык написания полезняшек на Python и фантазия.


Фантазия



В уме прикидываю что понадобится — TFTP сервер, куда будем складывать наше хозяйство, *nix машинка (с ней проще, чем под win всё это делать), Python на борту с необходимым набором библиотек. Как выяснилось впоследствии, TFTP сервер можно выкинуть, понадобится FTP.

Попытка раз


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

Попытка два


Присматриваюсь к библиотеке paramiko и её составляющей SSHClient — теперь всё получается — соединение проходит, могу выполнять команды и получать результат.

Теперь разберемся как снимаются конфигурации с этих действительно необычных железок. Привычный сценарий на сетевом оборудовании — выполнение одной команды, которая умеет отправлять свой конфиг на TFTP сервер. В случае с MikroTik это вариант не работает — оказывается первым делом бэкап конфига нужно создать:

/system backup save [name=]

После этого файл уже можно куда-то загрузить, но как оказалось сделать это можно только по протоколу FTP, а по HTTP и TFTP он умеет только сливать файлы. Это не беда, быстро поднимаем FTP сервер с минимальной конфигурацией, нагуглить которую уважаемым читателям не составит труда.

/tool fetch address= mode=ftp dst-path= src-path= user= password= upload=yes

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

/file remove

Результат


За пару часов фантазия родила сей скрипт:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# for SSH
from paramiko import SSHClient
from paramiko import AutoAddPolicy
# for versioning
import datetime
# for file operations
import os
# for sleep
import time

# versioning
Version = datetime.date.today()
#print "\n" + str(Version)

# hosts array IP1, IP2, IP3
hosts = ( "1.2.3.4", "5.6.7.8" , "9.10.11.12")
# username
users = ( "user1", "user2", "user3")
iterUser = iter(users)
# userpassword
passwords = ( "pass1", "pass2", "pass3" )
iterPassword = iter(passwords)
# FTPD IP
FtpdIP = "13.14.15.16"
# ftp user account
ftpUser = "ftpuser"
ftpPass = "ftppass"
# keep backups for 4 weeks
backtime = datetime.timedelta(weeks=-4)
sshCli = SSHClient()
sshCli.set_missing_host_key_policy(AutoAddPolicy())

print "header done"

# loop host adresses
for host in hosts:
    print "\n" + str(host)
    # iterate through user-password pairs
    user = iterUser.next()
    Password = iterPassword.next()
    # define operations
    CreateLocalBckp = "system backup save name=" + str(host) + "_" + str(Version) + ".backup"
    UploadToFtp = "tool fetch address=" + str(FtpdIP) + " mode=ftp dst-path=" + str(host) + "_" + str(Version) + ".backup src-path=" + str(host) + "_" + str(Version)+ ".backup" + " user=" + str(ftpUser) + " password=" + str(ftpPass) + " upload=yes"
    RemoveLocalBckp = 'file remove "' + str(host) + "_" + str(Version) + ".backup" + '"'
    # try for not to fail the whole script on one error
    try:
        print "connecting.." + str(host) + "@"  + str(user) + ":" + str(Password)
        sshCli.connect(str(host), port=2022, username=str(user), password=str(Password))
        print "connected.."
        # creating local backup
        print "creating local backup.. /" + CreateLocalBckp
        sshCli.exec_command(CreateLocalBckp)
        # sleep after each command because mikrotik can not do it so fast as script executes
        time.sleep(2)
        print "local backup created.."
        # uloading local backup to ftp
        print "uploading local backup to ftp.. /" + UploadToFtp
        sshCli.exec_command(UploadToFtp)
        time.sleep(2)
        print "backup uploaded to remote location.."
        # removing local backup
        time.sleep(2)
        print "removing local backup.. /" + RemoveLocalBckp
        sshCli.exec_command(RemoveLocalBckp)
        time.sleep(2)
        print "local backup removed.."
        sshCli.close()
        # try delete old file (if exists)
        try:
            os.remove("/tftp/" + str(host) + "_" + str(Version + backtime)  +".cfg")
        except:
            print "Error while trying to delete old backup " + "/tftp/" + str(host) + "_" + str(Version + backtime)  +".cfg"
    except:
        print "Error connecting to host", host


Скрипт будет хранить на нашем FTP сервере набор резервных копий конфигураций за месяц с именами вида IP_YYYY-MM-DD.backup

PS: есть подобное создание для случая коммутаторов 3Com и загрузки их конфигураций через telnet на TFTP — если читателям интересно, обязательно опубликую.
Теги:
Хабы:
+22
Комментарии 17
Комментарии Комментарии 17

Публикации

Истории

Работа

Python разработчик
134 вакансии
Data Scientist
62 вакансии

Ближайшие события

PG Bootcamp 2024
Дата 16 апреля
Время 09:30 – 21:00
Место
Минск Онлайн
EvaConf 2024
Дата 16 апреля
Время 11:00 – 16:00
Место
Москва Онлайн
Weekend Offer в AliExpress
Дата 20 – 21 апреля
Время 10:00 – 20:00
Место
Онлайн