The best place for network developers

Paramiko – Python Library

How to connect to your device via Python? Here you will find an introduction to Paramiko - Python Library.

Have you ever wondered if there is a possibility to send a few commands to 100 / 200 or 500 devices via one button? We are sure there is a lot of wonderful network management tools which do these things but what if you need an adaptive tool to your network? What if you need to compare some outputs and make some decission before adding next commands on your device?

So.. let we begin. What is the Paramiko library

This is a library for making SSH2 connections (client or server). Emphasis is on using SSH2 as an alternative to SSL for making secure connections between python scripts. All major ciphers and hash methods are supported. SFTP client and server mode are both supported too.

https://pypi.org/project/paramiko/

This is theoretically point of view. We would like to skip theoretical parts as much as it is possible. Let’s get straight to the point – first of all, we have to install our Paramiko library:

  1. pip install paramiko

When this is done, we are ready to use it. Please note that with Paramiko there are some other libraries installed:

Successfully installed asn1crypto-0.24.0 bcrypt-3.1.6 cffi-1.12.3 cryptography-2.6.1 paramiko-2.4.2 pyasn1-0.4.5 pycparser-2.19 pynacl-1.3.0 six-1.12.0

First of all, we have to import libraries. This is always a good practice to import all libraries at the beginning of the script and this is how we have done it.

  1. import paramiko
  2. import time
  3. import getpass

We import 3 libraries:

  • paramiko – the one that we installed one step ago – used to make SSH connection
  • time – we will use this library to make „breaks” between commands that will be sent to device
  • getpass – this is used to collect information from command line where scripts ask you about your username and password. More about this library: https://docs.python.org/3.7/library/getpass.html
  1. if __name__ == "__main__":
  2. main()
  3.  
  4. def main ():
  5. #provide credentials
  6. login = input("Username:")
  7. password = getpass.getpass("Password for " + login + ":")

Next step is opening (lines 1 and 2) and defining (lines 4-7) main() function and creating two variables which will collect username and password from prompt:

Username:LOGIN_NAME
Password for LOGIN_NAME:

Provided credentials will be used to login to our device(s) in our script.

  1. list_of_ips = ["1.1.1.1", "2.2.2.2", "3.3.3.3"]

As a next step, we define list of devices / IPs on which script should be executed. You can define this list manually, like here. You can also collect list of IPs from file or database. It depends on your requirements.

  1. for ip in list_of_ips:
  2. try:
  3. remote_conn_pre = paramiko.SSHClient()
  4. remote_conn_pre.set_missing_host_key_policy(paramiko.AutoAddPolicy())
  5. remote_conn_pre.connect(ip, username=login,
  6. password=password,
  7. look_for_keys=False, allow_agent=False)
  8. remote_conn = remote_conn_pre.invoke_shell()
  9. remote_conn.send('\n')
  10. remote_conn.send('terminal length 0')
  11. remote_conn.send('\n')
  12. time.sleep(2)
  13. remote_conn.send("sh ip int br")
  14. remote_conn.send('\n')
  15. remote_conn.recv(10000).decode("utf-8")
  16. time.sleep(10)
  17. except:
  18. print ("I cannot connect to device:" + ip)
  19. continue

Now we can see the most important part of our script. In line 1 – we will go device by device from our IPs list.

Note that we do every connection to each seperate device in “try / except” format (lines 2 and 17). This is how we strongly recommend to use exceptions in your code. Thanks to that if something goes wrong, e.g. connection to device will break, the script will not crash. The script will print exception error + information “I cannot connect to device+ <IP> on which the issue occurred.

Example error output to device that I was not able to login (the device is offline):

Username:Cisco
Password for Cisco:
I cannot connect to device:1.1.1.1
I cannot connect to device:2.2.2.2
I cannot connect to device:3.3.3.3

Then, we do a connection to paramiko remote_conn_pre = paramiko.SSHClient()When the SSHClient object is created (remote_conn_pre = paramiko.SSHClient()), we can set the SSH host key policy (remote_conn_pre.set_missing_host_key_policy(paramiko.AutoAddPolicy())) to automatically add the SSH host key (add untrusted hosts). Make sure that you can use this command in your environment because this command makes a potential vulnerability to MINTM (man in the middle) attack.

Finally, we are ready to connect to our device:

  1. remote_conn_pre.connect(ip, username=username,
  2. password=password,
  3. look_for_keys=False, allow_agent=False)

We can add two variables: look_for_keys and allow_agent. Both of them make us not use SSH keys. Both these options are optional,  but they are highly recommended to use. Not using these options can cause problems with password authentication.

We are also using remote_conn_pre.invoke_shell() to establish an ‘interactive session’ with CLI on the network device.

  1. remote_conn.send('\n')
  2. remote_conn.send('terminal length 0')
  3. remote_conn.send('\n')
  4. time.sleep(2)
  5. remote_conn.send(„sh ip int br”)
  6. remote_conn.send('\n')

We use built-in Paramiko methods like remote_conn.send, we recommend to use some “enters’” (“\n”) before each command. This is a good practice to simulate „human” entering commands on CLI. What is more, quite important is to use “terminal length 0” command as the first command  that is sent. Thanks to that we are 100% sure that full output will be presented and our script will not drop some output from device. 

Last but not least, here you can find full script used in this article. What is more you can also visit our github: https://github.com/DevNetSpace/Articles/blob/master/paramiko_library.py , where we collect all our scripts.

Access Point – automatic report

Do you remember when last time local IT / your colleague / HelpDesk / anyone asked you for gathering a report about some devices which are connected in your network? Do you remember all the boring stuff that you had to do? Login into 5, 10, 15… 50 devices and gathering information like IP, port number, description, device name, mac address?

Building lab environment

Every time I have to automate specific kind of a job I write down and answer project specific questions, which help me to prepare algorithm and general idea, how a new solution will work.

Of course, this list can be easily extended during algorithm preparation. A good approach is to prepare small working solution and extend it, every time you need it, by adding new functionality. Building small peaces and extracting specific functions will help in troubleshooting, reduce downtime during writing a code and of course, give a better planning and estimation of time when whole project will be finished.

Automatic interface configuration

For all of us entering same commands / text into CLI becomes boring after some time. Do you remember your fascination when you created a VLAN 10, connected two switches together and they pinged each other? Yes, probably for most of us were very enthusiastic that time. But after some time copying same command, creating same VLANs can become a little bit boring. What can we do to make it faster, better and less prone to mistakes?