Blog |Follow Nick on Twitter| About
 

If you look in the Cisco forums for scripts to backup ASAs you'll find various SSH / Expect , complicated examples... not sure why since in 2006 I showed it can be done with a single wget command ;-)

Recently I needed something that would support Multi-Context firewalls, so I pimped my one line command into the below shell script.

Copy/paste into a new file as backup_cisco_asa.sh then chmod 700 the file as necessary.

Run the file with no options ./backup_cisco_asa.sh and it'll ask you for IP address, username and password to make the connection.

For this to work the ASA needs appropriate HTTP statements (i.e. allow ASDM access from where you are running the script)

The file supports in-line backup of a single device such as ./backup_cisco_asa.sh 10.10.10.10

Multi-context support is via an environment variable or a config file ~/.asa_config. You must set an array containing entries for each context you want to backup. e.g.

ASA_CONTEXTS=( 
 "172.31.9.10:system"
 "172.31.9.10:admin"
 "172.31.9.10:Edge"
 "172.31.2.254:system"
 "172.31.2.254:admin"
 "172.31.2.254:Core" )

If you're feeling insecure you can also save your username/password variables into the ~/.asa_config as ASA_UID and ASA_PW respectively (or as environment variables)

Given that the script is a bash shell script I assume that SCP isn't required (because you are probably already on your linux SSH/SCP server running the script) but to keep the router team happy you might need to copy the files up via TFTP, this can be set with the ASA_TFTP_IP variable in ~/.asa_config.

By default the backup files will be saved to ./ (i.e. where ever you run the script from) and you can change that with the ASA_FILEPATH variable.

backup_cisco_asa.sh

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/bin/bash

# Nick Bettison - LINICKX.com - 2015 - v1
# Bash Shell Scipt for backing up Cisco ASA's via HTTPS (i.e. ASDM)
# 
# Read the file comments, you can setup a config file ~/.asa_config to store variables.
# ASA_UID & ASA_PW for credentials (if you're feeling insecure)
# ASA_CONTEXTS for multi-context support
# and ASA_TFTP_IP for copying the files via TFTP (for insecure router boys)
#
# Tested on.
# Cisco Adaptive Security Appliance Software Version 9.2(3)4 <context>
# Device Manager Version 7.4(2)

# Timestamp for file names
TIMESTAMP=`date "+%Y%m%d-%H%M%S"`

# Allow single ASA IP address to be passed from CLI
# e.g ./backup_cisco_asa.sh 10.10.10.10
if [ -n "$1" ]
    then
    ASA_IP="$1"
fi

# Check for Curl
type curl >/dev/null 2>&1 || { echo >&2 "I require curl but it's not installed.  Aborting."; exit 1; }

# Read Variables from a config file (if it exits)
# The config file can be used for storing multi-context configurations... and for the insecure username/password ;-)
if [ -e ~/.asa_config ]
then
  . ~/.asa_config
fi

# Default File Path
if [ -z "$ASA_FILEPATH" ]
    then
    ASA_FILEPATH="./"
fi

# Check for UID/PW Variables - Ask if not found
if [ -z "$ASA_UID" ]
        then
        read -p "ASA Username:" ASA_UID
fi
if [ -z "$ASA_PW" ]
        then
        read -s -p "ASA Password:" ASA_PW
        echo
fi

# Check to see if single or multi-context mode.
if [ -z "$ASA_CONTEXTS" ]
        then
        if [ -z "$ASA_IP" ]
                then
                read -p "ASA IP Address:" ASA_IP
        fi

        ASA_tFILE="$ASA_FILEPATH.$TIMESTAMP.asaconfig.txt"

        # Download the "show run" via the unofficial CLI.
        curl -s -k -o $ASA_tFILE -u $ASA_UID:$ASA_PW "https://$ASA_IP/admin/exec/show%20running-config%20asdm/show%20running-config"

        if [ -e $ASA_tFILE ]
            then
            # Look for hostname in config file
            ASA_HOSTNAME=`grep ^hostname $ASA_tFILE | awk '{print $2}'`
            # rename the temp file to something sensible.
            mv $ASA_tFILE "$ASA_FILEPATH$TIMESTAMP.$ASA_HOSTNAME.txt"
            # Setup an array for TFTP later.
            ASA_FILES=("${ASA_FILES[@]}" "$ASA_FILEPATH$TIMESTAMP.$ASA_HOSTNAME.txt")
            # Done.
            echo "DONE: $ASA_FILEPATH$TIMESTAMP.$ASA_HOSTNAME.txt"
        else
            echo "FAILED: $ASA_IP"
            exit 1
        fi
else
    # Example ASA_CONTEXTS array:
    # 172.31.9.10 is the admin context IP, admin & Edge are the names of the two contexts to backup.
    # 172.31.2.254 is the admin context IP, admin & Core are the names of the two contexts to backup.
    # "system is obviously the system context"
    # ASA_CONTEXTS=( 
    #     "172.31.9.10:system"
    #     "172.31.9.10:admin"
    #     "172.31.9.10:Edge"
    #     "172.31.2.254:system"
    #     "172.31.2.254:admin"
    #     "172.31.2.254:Core" )

    # Loop through the array
    for firewall in ${ASA_CONTEXTS[@]} ; do
         ASA_IP=${firewall%%:*}
         ASA_CONTEXT=${firewall##*:}

         # Feedback on progress
         printf "Connecting to %s for %s \n" $ASA_IP $ASA_CONTEXT
         # Filename
         ASA_FILE="$ASA_FILEPATH$TIMESTAMP.$ASA_IP.$ASA_CONTEXT.txt"

         # Download the CONTEXT "show run" via the unofficial API.
         curl -s -k -o $ASA_FILE -u $ASA_UID:$ASA_PW "https://$ASA_IP/admin/exec/changeto%20context%20$ASA_CONTEXT/show%20running-config/show%20running-config%20asdm"

         if [ -e $ASA_FILE ]
             then
             # Setup an array for TFTP later.
             ASA_FILES=("${ASA_FILES[@]}" "$ASA_FILE")
             # Done!
             echo "DONE: $ASA_FILE"
         else
             echo "FAILED: $ASA_IP"
         fi
     done
fi

# Optional Backup to insecure tftp - you know, to keep the router boys happy!
if [ -n "$ASA_TFTP_IP" ]
    then
    # Check for TFTP binary
    type tftp >/dev/null 2>&1 || { echo >&2 "tftp client not installed.  Aborting."; exit 1; }
    type wc >/dev/null 2>&1 || { echo >&2 "wc not installed (needed for counting stuff).  Aborting."; exit 1; }
    type awk >/dev/null 2>&1 || { echo >&2 "awk not installed.... seriously?!?!  Aborting."; exit 1; }

    # Loop through array
    for file in ${ASA_FILES[@]} ; do
        LOCAL_FILE=$file
        # backup separator
        OIFS=$IFS
        # Change separator to /
        IFS='/'
        # Split the filename from the path
        AWK_POSITION=`echo $file | wc -w`
        REMOTE_FILE=`echo $file | awk -v w=$AWK_POSITION '{print $w}'`
        # restore separator
        IFS=$OIFS
        # TFTP the file.
        tftp -v $ASA_TFTP_IP -c put $LOCAL_FILE $REMOTE_FILE
    done
fi

 

 
Nick Bettison ©