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.21@unixwitch.de
weitere Tools / Spickzettel