Skip to content

Using expect scripts to backup your Cisco configuration

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

  • A working tftp server
  • Expect
  • 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.

    Published inHowto'sLinuxNetwork

    31 Comments

    1. Tom Tom

      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.

    2. alex alex

      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.

    3. Tom Tom

      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. 🙂

    4. oelewapperke oelewapperke

      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.

    5. Tom Tom

      Oele: thanks for the tip!
      I’ll look into it when I have some time to spare.

    6. Al Al

      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?

    7. Tom Tom

      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–“.

    8. Al Al

      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?

    9. Peter Peter

      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
      }

    10. Tom Tom

      Awesome. Thanks!

    11. 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”

    12. zalph zalph

      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.

    13. Tom Tom

      Thank for sharing zalph.
      This might come in handy.

    14. tzh tzh

      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)

    15. Tom Tom

      That’s strange.
      It still does the trick over here with the same syntax.

    16. chewZ chewZ

      @tzh
      delete comments on the set variable lines

      this:
      set device 192.168.0.100 # cisco device
      in
      set device 192.168.0.100

    17. chewZ chewZ

      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

    18. fathul fathul

      hey tom…
      do you have any script that will allow uploading cisco configuration backup from linux directly to router?

    19. fathul fathul

      i need to do a mass configuration changes and i think expect scripts is the right solution..

    20. Me Me

      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…

    21. 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…). 😉

    22. GeorgeZ GeorgeZ

      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 =)

    23. 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”

    24. Brian Cuttler Brian Cuttler

      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

    25. slavko slavko

      ————–
      E.g.:
      expect “–More–”
      send “\n”

      This will send a new line if it comes across “–More–“.
      ——————-
      See CLI command
      terminal length 0

    26. Maryna Maryna

      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

      ??

    27. […] 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/ […]

    28. […] 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/ […]

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    Time limit is exhausted. Please reload CAPTCHA.