Blog |Follow Nick on Twitter| About
 

atom screenshot

Recently myself (and a maybe colleague or two) has been copy/pasting parts of C.R.A.SSH (crassh) my python script for automating commands on Cisco IOS devices into personal scripts to get something done; knowing there must be a better a way I decided to turn crassh into a module which can/should be easy to install on linux or OSX systems with pip. PIP is a python (cross platform) package manager that now crassh is available in, i.e. pip install crassh

Below is an output from my machine, as you can see pip will install any necessary dependencies:

$ pip install crassh
Collecting crassh
  Downloading CraSSH-2.02.tar.gz
Collecting paramiko>=1.10 (from crassh)
  Using cached paramiko-1.16.0-py2.py3-none-any.whl
Collecting pycrypto!=2.4,>=2.1 (from paramiko>=1.10->crassh)
Collecting ecdsa>=0.11 (from paramiko>=1.10->crassh)
  Using cached ecdsa-0.13-py2.py3-none-any.whl
Building wheels for collected packages: crassh
  Running setup.py bdist_wheel for crassh
Successfully built crassh
Installing collected packages: pycrypto, ecdsa, paramiko, crassh
Successfully installed crassh-2.2 ecdsa-0.13 paramiko-1.16.0 pycrypto-2.6.1
$

I'm about to start work on some proper documentation , but to get you started there are four functions that most people will want/use:

  • crassh.connect()
  • crassh.send_command()
  • crassh.disconnect()
  • crassh.readtxtfile()

The first three are self explanatory, the last one is very useful as it'll read in a plain text file (one line at at time) and use it as an array, typically the plain text file would be a list of IP address to connect to or a list of commands to execute.

To show how crassh can be used, below is a simple example to audit to switches for the SNMP community string public - A security no-no!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/env python
# coding=utf-8

import crassh

# Variables
routers = ["10.159.83.135", "10.159.83.136"]
username = "nick"
password = "nick"

# Loop
for device in routers:

    hostname = crassh.connect(device, username, password)
    output = crassh.send_command("show run | inc snmp-server community", hostname)
    crassh.disconnect()

    # Split the output by spaces so we can search the response
    words = output.split()

    # Look for "public" in the output
    for x in words:
        if x == "public":
            print("DANGER: Public SNMP Community set on %s [%s]" % (hostname, device))

I've saved the file as no_public.py and this is the response...

$ python no_public.py 
Connecting to 10.159.83.135 ... 
Connecting to 10.159.83.136 ... 
DANGER: Public SNMP Community set on r2 [10.159.83.136]
$

Obviously you could do a lot more than just output but hopefully this'll give you an idea.

NOTE: Instead of routers being an array, I could have done routers = crassh.readtxtfile("./routers.txt") where routers.txt was a plain text file with one IP address per line.

 

 
Nick Bettison ©