Pexpect ist ein Python-Modul, mit dem man ähnlich wie bei Expect scriptgesteuert eine interaktive Umgebung steuern kann.
Hier zwei Beispiele, bei denen die laufende Konfiguration "running config" eines Cisco-Geräts heruntergeladen und angezeigt wird.
Etwas älter, deswegen Python 2.
Siehe auch etwas moderner: CISCO + Pexpect (Python3).
#!/usr/bin/python
# python script to fetch the config of a switch
# www.unixwitch.de, 2008-12-04
password1="mypassword1" # that's why you should be really carefull where to store this script!
password2="mypassword2"
geraet="myswitch"
user="myuser"
import pexpect
child = pexpect.spawn ('telnet ' + geraet)
child.expect ('.*sername:.*')
child.sendline (user)
child.expect ('.*assword:.*')
child.sendline (password1)
child.expect ('.*>.*')
child.sendline ('ena')
child.expect ('.*assword:.*')
child.sendline (password2)
child.sendline ('terminal length 0')
child.sendline ('sh run')
child.expect ('end\r\n\r\n.*#')
# this last line won't be shown
runningconfig=child.before
print runningconfig
child.sendline('exit')
child.close()
Übrigens, liebe Ciscos: warum muss man für Switche, die auch SSH können, noch extra Geld zahlen?
der wichtige Dreh: die Config mit more system:running-config anzeigen! Bei "show running-config" werden z.B. Pre-Shared-Keys von VPNs aus-gesternt, dann wundert man sich, warum irgendwelche VPNs nach ein paar Stunden nicht mehr hochkommen.
#!/usr/bin/python
# python script to fetch the running config of a cisco asa
# www.unixwitch.de, 2008-12-04
password1="mypassword1" # that's why you should be really carefull where to store this script!
password2="mypassword2"
router="myasa.example.com"
user="myuser"
import pexpect
child = pexpect.spawn ('ssh ' + user + '@' + router)
child.expect ('.*assword:.*')
child.sendline (password1)
child.expect ('.*> ')
child.sendline ('ena')
child.expect ('.*assword:.*')
child.sendline (password2)
child.sendline ('terminal pager 0')
child.sendline ('more system:running-config')
child.expect (': end.*')
runningconfig=child.before
print runningconfig
child.sendline('exit')
child.close()
Übrigens, liebe Ciscos: wäre toll, wenn man endlich ssh-keys hinterlegen könnte.
hochkopieren geht mit scp, runterkopieren leider nicht …. runterkopieren kann man dafür mit https (vorausgesetzt https und scp sind eingeschaltet und von der jeweiligen Location auch erlaubt. Und die Crypto-Keys müssen natürlich auch auf dem Gerät vorhanden sein …)
#!/usr/bin/python
# script for writing or fetching files from or to cisco asa flash disk
# 2010-06-10, www.unixwitch.de
"""
asa-copy-file:
hole oder schiebe datei auf flash-speicher der asa
Aufruf:
asa-copy-file asa-name put dateinamelokal {dateinameremote}
asa-copy-file asa-name get dateinameremote
"""
import pexpect
import os
import sys
import re
password="meingeheimespasswort"
username="meinmaechtigeruser"
scriptname=sys.argv[0]
scriptname=os.path.basename(scriptname)
try:
boxname=sys.argv[1]
except:
fehler="Fehler: kein Firewallname angegeben\n%s" % __doc__
print >> sys.stderr, fehler
sys.exit(1)
if ((boxname == "-h") or (boxname == "--help")):
print __doc__
sys.exit(0)
try:
action=sys.argv[2]
except:
fehler="Fehler, Aktion ('put' oder 'get') fehlt\n%s" % __doc__
print >> sys.stderr, fehler
sys.exit(1)
try:
filenamefrom=sys.argv[3]
except:
fehler="Fehler, Dateiname fehlt\n%s" % __doc__
print >> sys.stderr, fehler
sys.exit(1)
try:
filenameto=sys.argv[4]
except:
filenameto=filenamefrom
if action == "put":
print "transferiere datei %s auf %s:%s" % (
filenamefrom, boxname, filenameto )
child = pexpect.spawn ('scp %s %s@%s:%s' % (filenamefrom,username,boxname,filenameto))
child.expect ('.*assword:.*')
child.sendline (password)
child.expect ('100%')
child.close()
elif action == "get":
print "transferiere von %s die datei %s und lege sie als %s ab" % (
boxname, filenamefrom, filenameto)
cmd="/usr/bin/wget -nv https://%s:%s@%s/admin/disk0/%s --no-check-certificate" % (
username,password,boxname, filenamefrom)
cmd="/usr/bin/curl -s https://%s:%s@%s/admin/disk0/%s -k > %s" % (
username,password,boxname, filenamefrom, filenameto)
print cmd
os.popen(cmd);
else:
fehler="Fehler, Aktion muss 'put' oder 'get'sein \n%s" % __doc__
sys.exit(1)
man könnte die Konfiguration natürlich auch auf einen TFTP-Server schieben, wenn man einen in sicherer Reichweite hat.
wenn man einfach nur den Login-Vorgang automatisieren will und dann wieder selber tun möchte, einfach nach dem 2ten Passwort
child.sendline (password2)
den Rest löschen und die Zeile
child.interact()
anfügen.
Bei beiden Scripts wird die letzte Endmarkierungs-Zeile weggeschnitten.
gilt für alle Tipps, Tricks & Spickzettel:
dies sind einfache, teils banale Notizen für meinen persönlichen Gebrauch,
die hier eher zufällig auch öffentlich lesbar sind
(vielleicht hilft es ja jemandem weiter). Verwendung auf eigene Gefahr
Fehler-Hinweise, Dankesschreiben , etc. bitte an: web.25@unixwitch.de
weitere Tools / Spickzettel