Python SSHv2 to Cisco routers for multiple commands

Sam Crooks sam.a.crooks at gmail.com
Tue Mar 10 17:58:00 UTC 2009


I'm not necessary trying to bootstrap a router... that was just a string of
config commands off the top of my head... the point is that they must be
sequential, and must be done ins a single session to make sense...

I thought about the output a file and SCP / TFTP transfer it, but that is a
bit of a kludge/workaround... would like to avoid if possible.  it requires
TFTP, yet another dependency, so I'd prefer to do it directly with SSH if
possible.


The ultimate goal is to build a provisioning system for a DMVPN solution we
have


We use DMVPN in combination with GETVPN (aka GDOI) over Internet links to
provide branch and customer (extranet) connectivity.  The DMVPN solution for
branch connectivity uses dynamic spoke-to-spoke tunneling, and GETVPN is
used so that there is no lag in the dynamic tunnel setup, as there is then
no IKE and IPSec negotiation between spoke routers when they build direct
spok-to-spoke tunnels. We're also using Front-Door VRF on the routers, so
the Internet interface is in an FVRF and the tunnel(s) are configured to use
the FVRF for NHRP resolution (tunnel vrf <vrf-name>).  We have an ACL
applied inbound and another ACL applied outbound.

In order for each spoke router to build dynamic tunnel to another spoke, ESP
must be permitted inbound in the inbound ACL applied to the Internet
interface.  Due to the dictates of our internal infosec people, the ACL,
must explicitly permit EACH spoke router's public IP, rather than a nice,
easy "permit esp any any "


the effect of this is that each time we add a new branch office router, we
must update the ACL and deploy it to all the branch routers.  In addition,
we must add IKE key entries (using PSK IKE keys on the GETVPN keyservers),
and add routing neighbors to the headends routing (using eBGP for routing
exchange through the tunnel).

The net effect is that the addition of 1 router to the group triggers a few
different small config changes to the keyservers, a few routing neighbor
additions, and an ACL deployment to all existing branch routers.


My goal is to script this whole process:

 - create a DB-like structure that is persistent on disk of all the routers
and their attributes (name, location, loopbak0 ip, tun1 ip , tun 2 ip,
internet interface IPs, IKE keys, etc) - so far, using shelve for this, and
using a class to represent the routers, serializing to disk using shelve...
working OK at the moment

 - to add a new router
     - add a new object to the DB

 - to deploy the new router
     - from the DB structure, pull out the public IPs and generate the ACL.
     - ssh to GETVPN keyserver
          - add the IKE keys for the new router's public IPs,
          - issue commands to SCP or TFTP a new ACL which controls access to
the key server to the keyserver's flash
          - checksum the ACL file on flash:
          - copy the ACL to running-config
          - wr mem
     - ssh to the DMVPN headends
           - add BGP neighbors for the new router's tunnel IPs (the tunnel
IPs are the eBGP peering addresses)
           - wr mem
     - ssh to each router's Lo0 ip in the DB
           - issue commands to SCP or TFTP the new ACL to the router's
flash:
           - checksum the ACL file on flash:
           - copy the ACL to running config
           - wr mem
     - (optional) archive a copy of each router's config before and after to
a Subversion repository for disaster recovery and troubleshooting purposes
     - write a copy of the ACLs into a Subversion repository
     - write a copy of the shelve structure/DB structure elsewhere (ie:
Subversion repository)
     - send a status report about what happened


The SSH aspect for multiple commands is currently tripping me up.

:-|


I've look at various sources, but all are somewhat convoluted.. .I'm new to
using Twisted, so I am sure that is a part of my issue... also the examples
I've seen are a bit trivial.  Planning on looking closely at the tkconch.py
example script that comes with Twisted, as well as the code in ModiPy, which
also uses Twisted... ModiPy itself doesn't seem to work.


-


On Tue, Mar 10, 2009 at 11:34 AM, Andreux Fort <afort at choqolat.org> wrote:

> On Tue, Mar 10, 2009 at 9:24 AM, Sam Crooks <sam.a.crooks at gmail.com>
> wrote:
> > Does anyone have any suggestions for SSHv2 to multiple Cisco devices and
> > (this is the catch) running multiple commands?
> >
> > I've tried with Paramiko using the SSHClient(), then connect()'ing and
> > issuing exec_command(), and it seems that the router closes the channel
> > after the .exec_command('command here').  Subsequent write()'s on the
> stdin
> > file object returned do not work, as shown on the examples I have seen:
> >
> http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/#more-465
>
> Yes.  The SSH session you're opening has a lifetime of one command.
> If you want to do more than that, you have a couple of options:
>
> 1. Don't use exec_command().  Create the connection yourself, like
> SSHClient does, and then run in SSH1.5 mode (details escape me now in
> this airport, but I've done this).
>
> 2. On Juniper, I can do "show foo; show this; show that", which works
> just fine with exec_command().  Does that work on a Crisco?  (I'm
> guessing no, since that's a single command that the juniper splits).
>
> >
> > I've tried various examples with twisted.conch.ssh and it seems Twisted
> is a
> > bit more low-level than paramiko's SSHClient class.
> >
>
> Yes; however, the SSHClient class wraps up a few other things that you
> could just do yourself, too.  The code isn't that ugly, although it
> will raise EOFError on most operations (or socket.timeout in paramiko
> 1.7), and the docstrings in SSHClient's methods don't say that, so be
> aware.
>
> >
> > I'm trying to  be able to issue a string of commands to routers which
> > require a particular sequence;
> >
> > configure terminal
> > hostname blahrouter1
> > ip domain-name x.i.z
> >
> > ip tftp source-interface lo0
> > end
> >
> >
> > copy tftp:/x.y.z.w/my/path/file.txt   flash:
> >
>
> So you're trying to bootstrap a new router?
> You could use the Cisco TFTP/BOOTP/DHCP method of bootstrapping.  I
> don't think many people really use this, but you may be in luck (i.e.,
> it may work on your routers).
>
> For ongoing mainteance:
> Put the actual commands in a file, and then just send "copy source
> dest" on the router?  This is how I do config pushes (it allows you to
> copy to a local file on the router first and perform an MD5 checksum,
> too.  Which I'd recommend so your operators don't want to kill you
> :-).
>
> --
> Andreux Fort (afort at choqolat.org)
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.isc.org/pipermail/toolmakers/attachments/20090310/ea60fb55/attachment.html>


More information about the Toolmakers mailing list