Centralized configuration collection with MikroTiks using Python

    What for



    With the increase in the number of network nodes and the complexity of their configuration, many probably have a question - and if the piece of iron dies, can I quickly restore work to another? If I can do it manually, then how long will I then catch the little things that I forgot?

    The googling process has led to the understanding that there are no ready-made solutions of this kind specifically for this vendor. I did not like what was found in the community - they offered to place backup scripts on the hardware itself and run them on a schedule. In essence, this solved the problem, but if I have several dozen pieces of equipment, clicking on the copy paste for each copy is not Feng Shui.

    Fortunately there is a little skill in writing useful things in Python and fantasy.


    Fantasy



    I’m wondering what I’ll need - a TFTP server, where we will put our economy, * a nix machine (it’s easier to do this than with win), Python on board with the necessary set of libraries. As it turned out later, the TFTP server can be thrown out, you will need FTP.

    Try times


    I try to solve the problem head-on - I use telnetlib for communication - it does not work. It's strange, because it worked with switches. After thinking it over, I realized that telnet at MikroTik is decorated with all the colors of the rainbow, it means it is strewing with special characters, and filtering them is not included in my plans.

    Attempt two


    I’m looking at the paramiko library and its component SSHClient - now everything works out - the connection goes through, I can execute the commands and get the result.

    Now let's see how the configurations are removed from these really unusual pieces of iron. A common scenario on network equipment is the execution of one command that can send its config to a TFTP server. In the case of MikroTik, this option does not work - it turns out that the backup configuration file is the first thing you need to create:

    /system backup save [name=]

    After that, the file can already be downloaded somewhere, but as it turned out, this can only be done via FTP, and with HTTP and TFTP it can only merge files. It doesn’t matter, we quickly raise the FTP server with a minimal configuration, which is not difficult for the esteemed readers to google.

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

    And in the end, you need to remove the garbage behind you so as not to sail to the exhaustion of free space on the internal carrier:

    /file remove

    Result


    For a couple of hours, fantasy gave birth to this script:

    #!/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
    


    The script will store on our FTP server a set of configuration backups per month with names of the form IP_YYYY-MM-DD.backup

    PS: there is a similar creation for the case of 3Com switches and uploading their configurations via telnet to TFTP - if readers are interested, I will definitely publish it.

    Also popular now: