In this short howto I’ll explain how to use expect scripts with Cisco devices. In this example I’m going to use it to backup the current running configuration.
Requirements
Lucky for us both requirements are available in all major distro’s.
The Debian/Ubuntu way:
sudo apt-get install tftp tftpd expect
Next on our todo list is configuring the tftp server. This should also be fairly easy:
# cat /etc/xinetd.d/tftp service tftp { protocol = udp port = 69 socket_type = dgram wait = yes user = nobody server = /usr/sbin/in.tftpd server_args = /tftpboot disable = no }
Restart your xinetd server when done.
# /etc/init.d/xinetd restart
Make sure the /tftpboot folder exists and is owned by user and group nobody:
# chown -R nobody:nobody /tftpboot
You should also create an empty file where you’d like to save your configuration and rerun the above command to adjust permissions.
# touch /tftpboot/config # chown -R nobody:nobody /tftpboot
You should also create an empty file where you’d like to save your configuration and rerun the above command to adjust permissions.
# touch /tftpboot/config # chown -R nobody:nobody /tftpboot
We can now test our newly configured tftpd server:
Create a new file in your home dir called config and put some random text in it.
# cat /home/user/config test 12 # tftp tftp> open localhost tftp> put config Sent 146 bytes in 0.0 seconds # cat /tftpboot/config test 12
Excellent! We’re ready to receive config files from the Cisco device.
Below you will find an example script:
#!/usr/bin/expect ## TomDV ## http://blog.penumbra.be/2010/02/expect-scripts-backup-cisco-config/ # ---------------- configuration ---------------- # set device 192.168.0.100 # cisco device set tftp 192.168.0.200 # tftp server set user someuser # username set pass ultrasecret # password set config # config destination set timeout 60 # -------------- do not edit below -------------- # spawn telnet $device expect "Password:" send "$pass\n" expect ">" send "en\n" expect "Password:" send "$pass\n" send "copy running-config tftp://$tftp/$config\n\n" expect "$tftp" send "\n" expect "$config" send "\n" send "exit\n"
Save it anywhere you like and run it from the shell. You’ll see something like this in your logs:
user in.tftpd[22304]: connect from 192.168.0.200 (192.168.0.200) user tftpd[22305]: tftpd: trying to get file: config user tftpd[22305]: tftpd: serving file from /tftpboot
That’s it. Your current Cisco config has been saved to /tftpboot/config.
I wouldn’t recommend using this into production without proper firewalling. You can get the same results by using snmp. But that’s however a subject for another howto.
Have you tried a similar script that uses ssh instead of telnet?
Scott
http://www.xpresslearn.com
Not yet.
I haven’t had the chance to run an AdvancedSecurity IOS yet.
So most of the devices I’ve layed my hands on didn’t support SSH. But I assume it should work in a similar way. Or without sending the password if you’d use key based authentication.
Nice!
I used to do this with the (non-free) Kiwi CatTools.
Something else available in Debian’s repositories is RANCID, which does the above without TFTP,
works with more than just IOS [eg HP Procurve, Juniper, …] and stores the configs in SVN, so you
get an email summary with config changes in every time it runs.
I’m aware of Rancid, however it’s not so much more than a config diff tool and clogin. As far as I know it’s not possible to script it, but I could be mistaking off course.
The main goal of this howto was to show how easy it is to run scripts to do stuff on your cisco devices. The backup part was merely a practical example. 🙂
rancid script to download router (or switch) config:
$ROUTERS = “r1 r2 r3″
D=”`date +%Y%m%d%H%M`”
function getRouterConfig {
(clogin -c “show run” $1) > “configs/$D/$1”
echo “$1 got conf”
(clogin -c “show tech” $1) > “configs/$D/$1.showtech”
echo “$1 got show tech”
}
mkdir -p “configs/$D”
for R in $ROUTERS; do
getRouterConfig $R &
done
The advantage of getting “show tech” too is that you have everything you need in case of failure : what serialnumbers of equipment failed, what the error counters are (and how they were historically), …
The problem is the 15 logins vty limit. Clogin will make sure it actually does the logout, but if you’re over the limit, you’re thoroughly fucked.
Oele: thanks for the tip!
I’ll look into it when I have some time to spare.
Can you use if statements with expect scripting, for example when you do a “show interface description” on a cisco, you need to page through the output until it has completed. So the script would have to search for “–More—“ ; then send a space bar character?
To accomplish that you might want to use the expect command in your expect scripts.
E.g.:
expect “–More–”
send “\n”
This will send a new line if it comes across “–More–“.
Thanks Tom, that works a treat.
However, as this script will be running on several devices I am not sure how much paging or “\n” will be needed. Hence, I was hoping to do some kind of while loop for example: –
send “show interface description”
while (match = –More–) {
send “\n”
}
This would then allow me to move onto the next command and complete a network audit of sorts :-).
Do you think that expect performs conditional checks like this?
Hi Al
Have a look at this example. This might help.
for {} {1} {} {
expect \
-exact “Enter to proceed.” { send — “\r” } \
-exact “–More–” { send — ” ” } \
-exact “Do you agree? \[yes/no\]” { send — “yes\r” } \
eof break
}
Awesome. Thanks!
This works really nicely. I had a problem at first where I was only getting up to about port 38 in my config files and the rest was truncated. I thought it was TFTP issues, but it came down to the script hanging up on the switch before the TFTP upload was completed. I had to make it wait for the “total bytes copied” statement before sending the exit command. The lower half of my config looks like this now …
send “copy system:running-config tftp://$tftp/$config\n\n”
expect “$tftp”
send “\n”
expect “$config”
send “\n”
expect “bytes copied”
send “exit\n”
Hi,
you don’t need to mess around with expect to filter for –More– from the output of a “show run” or “show tech” command.
You just need to send a “term length 0” to the Cisco IOS device before sending your various show commands. This command disables paging for the whole time of your session.
Cheers
Zalph.
Thank for sharing zalph.
This might come in handy.
I followed your instructions but when I run the script, I get the following error.
wrong # args: should be “set varName ?newValue?”
while executing
“set device 192.168.1.1 # cisco device”
(file “./getConfig” line 7)
That’s strange.
It still does the trick over here with the same syntax.
@tzh
delete comments on the set variable lines
this:
set device 192.168.0.100 # cisco device
in
set device 192.168.0.100
I slightly modified the script to save configs in .txt files named as the device without tftp server.
usage: expscript device user password
#!/usr/bin/expect
## http://blog.penumbra.be/2010/02/expect-scripts-backup-cisco-config/
# —————- configuration —————- #
set device [lrange $argv 0 0]
set user [lrange $argv 1 1]
set pass [lrange $argv 2 2]
set timeout 60
# ————– do not edit below ————– #
spawn telnet $device
expect “Password:”
send “$pass\n”
expect “>”
send “en\n”
expect “Password:”
send “$pass\n”
log_file $device.txt
send “term len 0\n”
send “show running-config\n”
expect “end\r”
send “\n”
send “exit\n”
log_file
hey tom…
do you have any script that will allow uploading cisco configuration backup from linux directly to router?
i need to do a mass configuration changes and i think expect scripts is the right solution..
[…] routine tests are probably run better with other mechanisms like SNMP monitoring, but the tool you'll probably want to look as is called "expect", there's a nice little example of an expect script for ios here… http://blog.penumbra.be/2010/02/expe…-cisco-config/ […]
Please note that doing a “show running-config” will not give you all the info you need on devices.. you will not see passwords that are encrypted so this is NOT a valid backup of the device if you need to restore.
you could try to turn off the encrypted passwords first however probably not practical…
Turning off password encryption will not decrypt your password, it will simple not encrypt newly configured password. “sh run” should contain encrypted passwords, on routers and switches at least, which can be copied back just fine to restore a config. No need to know the password if you just need to restore the config.
What may be an issue is that in default config interfaces are shutdown, which is normally the case when replacing hardware during outages. But hey that’s common knowledge, right?
When backing up firewalls you can use other commands to see the _full_ configuration (hint hint…). 😉
I don’t like the idea to put plain text password in a config file. That’s unsecure.
I use ACL to allow TFTP access from a specific device/s and I am using plain TFTP directly from the shell. No passwords involved.
Example:
access-list 55 remark PERMIT hosts requesting TFTP access
access-list 55 permit 172.16.0.27
!
!
!
tftp-server nvram:startup-config 55
and from the shell on 172.16.0.27 (of course could be put in a script) I run
tftp 172.16.0.3 -c get startup-config
where 172.16.0.3 is the device with the ACL settings above.
If you ask: what if the box is hacked? Well, if I am in your shoes and the box is hacked, the hacker will have all my passwords for all my devices if I use your way.
I setup
service password-encryption
in my router/switch etc.
and if the box is hacked the hacker will get the configurations without any passwords. Good luck cracking all of them in my case, and in your case you give them in plain text.
Just sharing =)
First of all, Thank you for this script. I have never even looked at an expect script before, and this made it easy to understand what is going on.
I have found that the comments in the configuration break the script with the version of Expect on OS X.
I have modified the script to work with SSH, as I do not use Telnet on my router.
Again, Thank you for this wonderful script.. I probably would not have figured out so easily without your help, and now Im not afraid of Expect scripts 🙂
–Brian
#!/usr/bin/expect
## TomDV
## http://blog.penumbra.be/2010/02/expect-scripts-backup-cisco-config/
##
## Modified for SSH support by Brian Cooney
# —————- configuration —————- #
set device 10.20.3.1
set tftp 10.20.3.107
set user UserNameHere
set pass PasswordHere
set config rt-HOSTNAME-confg
set timeout 60
# ————– do not edit below ————– #
spawn ssh $user@$device
expect “Password:”
send “$pass\n”
expect “>”
send “en\n”
expect “Password:”
send “$pass\n”
send “copy running-config tftp://$tftp/$config\n\n\n”
expect “$tftp”
send “\n”
expect “$config”
send “\n”
send “exit\n”
Thank you for the Q&A.
I’ve taken the reins of rancid from someone else but there
are things I haven’t learned yet, and while I’ve googled and
read man pages there are things I’m not finding.
There is a script above, contributed by oelewapperke
but I find after trying rancid-run and perl, that I haven’t
been able to figure out how to run it.
My objective is to download “show cdp neighbor” and
“show tech” for about 50 switches.
The language in the script above is ‘similar but
different’ I suspect I can put the 50 switch names
in a file and read it in?
thank you,
Brian
————–
E.g.:
expect “–More–”
send “\n”
This will send a new line if it comes across “–More–“.
——————-
See CLI command
terminal length 0
Hi Tom!
I’m a freshman in using CISCO product and I’m pleasent to use it. One of my new purchaise is Cisco ACE 4710 HARDWARE-4GBPS- ACE-4710-04-K9 from here http://hardware.nl/cisco I’m very proud to buy it and I tried to use ftp server with the name and password for each Office Listings
It will help to block access by casual users. It looks like this:
cli copy running-config startup-config
cli show run | redirect ftp://user:password@london.admin/router_1.config
cli show run | redirect ftp://user_london:password_london@center.admin/London/router_1.config
exit
kron occurrence Backup in 0:1:0 recurring
policy-list Backup
??
[…] Si vous avez rencontrer des problèmes d’installation au préalable : #purge old config sudo aptitude purge tftpd-hpa openbsd-inetd# install only tftpd-hpa sudo aptitude -R install tftpd-hpa Note sur la sécurité : http://www.scip.ch/fr/?vuldb.61380 Code de l’exploit : http://git.kernel.org/cgit/network/tftp/tftp-hpa.git/diff/tftpd/tftpd.c?id=f3035c45bc50bb5cac87ca01e7ef6a12485184f8 sources : http://www.it-connect.fr/configurer-un-serveur-tftp-sous-ubuntu-server/ Automatiser la procédure : http://blog.penumbra.be/2010/02/expect-scripts-backup-cisco-config/ […]
[…] sudo apt–get install tftpd–hpa sudo apt–get install tftp–hpa 2) Configurer le serveur sudo nano /etc/default/tftpd-hpa Editer la configuration TFTP_USERNAME=« tftp » // Utilisateur de connexion TFTP_DIRECTORY=« /var/lib/tftpboot » // Répertoire personnel de l‘utilisateur tftp TFTP_ADDRESS=« 0.0.0.0:69 » // Adresse d‘écoute du serveur – Accepte les connexions en local TFTP_OPTIONS=« –secure –create » 3 ) Gestion des groupes et des droits cd /var/lib mkdir tftpboot // créer le dossier si il n’est pas présent chgrp tftp tftpboot/ // Le répertoire tftpboot appartient au groupe tftp chmod 777 tftpboot/ // Attribution des droits sur le dossier tftpboot 4 ) Redémarrer le service sudo /etc/init.d/tftpd-hpa restart Pour lancer et stoper le service vous pouvez utiliser ces commandes : sudo /etc/init.d/tftpd-hpa start sudo /etc/init.d/tftpd-hpa stop 5 ) Tester le service avec votre routeur Si vous avez rencontrer des problèmes d’installation au préalable : #purge old config sudo aptitude purge tftpd-hpa openbsd-inetd# install only tftpd-hpa sudo aptitude -R install tftpd-hpa Note sur la sécurité : http://www.scip.ch/fr/?vuldb.61380 Code de l’exploit : http://git.kernel.org/cgit/network/tftp/tftp-hpa.git/diff/tftpd/tftpd.c?id=f3035c45bc50bb5cac87ca01e7ef6a12485184f8 sources : http://www.it-connect.fr/configurer-un-serveur-tftp-sous-ubuntu-server/ Automatiser la procédure : http://blog.penumbra.be/2010/02/expect-scripts-backup-cisco-config/ […]