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.
-
Post by Sam CrooksPost by Sam CrooksDoes 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
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.
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).
Post by Sam CrooksI've tried various examples with twisted.conch.ssh and it seems Twisted
is a
Post by Sam Crooksbit 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.
Post by Sam CrooksI'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
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).
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
:-).
--