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