Linux Networking Systems Administration

A script to connect to a Cisco switch and backup the running-config using Python3 and Paramiko

I have been trying to find a way to create a regular backup of my Cisco switch’s running-config, so I can store it in my normal backups. However, after searching online I was able to find some tools that were almost there, but nothing that was quite as flexible as I needed, so I wrote a new script to connect to the switch using the python3 paramiko library, and then dump the config.

Note – as mentioned by @mmezo on fosstodon, (thanks @mmezo) if you are backing up a bunch of switch configurations in production, you should look into these two tools:
Discussion is here:

My script is based on one that I found here:

However, when trying to use that script I found:

  • It didn’t use Python3, so not as easy to use on newer versions of Ubuntu
  • It didn’t connect properly with newer versions of paramiko

So I made an updated version for use myself. Note, you will need install the python3-paramiko on Ubuntu to use the script, can be done like this:
sudo apt-get install python3-paramiko
Script can be downloaded here:

#!/usr/bin/env python3

import paramiko
import sys
import argparse
import time

__version__ = "1.0.0"

def dump_cisco_config(ip, username, ssh_password, enable_password, quiet=False):
    client = paramiko.SSHClient()  # create an SSH client
    # Set the policy to auto-connect to hosts not in known-hosts file
    if not quiet:
        print(f"Connecting to cisco switch {ip}", file=sys.stderr)
    client.connect(ip, username=username, password=ssh_password, look_for_keys=False, allow_agent=False)

    print(f"Connected. Enabling...", file=sys.stderr)
    channel = client.invoke_shell(); time.sleep(5)
    channel.send('enable\n'); time.sleep(5)
    channel.send(f"{enable_password}\n"); time.sleep(5)
    # Set the terminal length to 0 so it doesn't try to pageinate the output
    channel.send("terminal length 0\n"); time.sleep(1)
    _ = channel.recv(99999)  # get back all the output up to this point
    print(f"Now dumping running-config...", file=sys.stderr)
    channel.send("show running-config\n"); time.sleep(30)

    config = channel.recv(999999).decode('utf-8')  # now get back the running config and decode to string\
    config = "\n".join(config.replace('\r\n', '\n').split('\n')[0:-1])  # remove the last line of the config, which will be the prompt again
    client.close()  # close ssh connection

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description='Connect to a cisco switch over SSH and dump the running-config',
        epilog='''You will need the paramiko SSH library installed to run this. On Ubuntu this can be installed with: sudo apt-get install python3-paramiko''', 
    parser.add_argument("--address", help="IP or Hostname of the switch", required=True)
    parser.add_argument("--username", help="Switch username", required=True)
    parser.add_argument("--ssh-password", help="Switch SSH password", required=True)
    parser.add_argument("--enable-password", help="Switch enable password", required=True)
    parser.add_argument("--quiet", help="Don't show interactive info on stderr", action="store_true")
    args = parser.parse_args()
    print(dump_cisco_config(ip=args.address, username=args.username, ssh_password=args.ssh_password, enable_password=args.enable_password, quiet=args.quiet))

You can use this script pretty easily, like this:

root@bigtuckey #~/l/bin_scripts> ./ --address --username cisco --ssh-password mypass --enable-password enablepass
Connecting to cisco switch
Connected. Enabling...
Now dumping running-config...
show running-config
Building configuration...

Current configuration : 2739 bytes
! Last configuration change at 00:21:32 UTC Mon Jan 2 2006 by cisco
version 15.2
no service pad
... trimmed for length ...
line con 0
line vty 0 4
 password no
 login local
 transport input ssh
line vty 5 15

root@bigtuckey #~/l/bin_scripts>

You can also remove the interactive output by using --quiet

Leave a Reply

Your email address will not be published. Required fields are marked *