BIG-IP Backup Script with SCP

Problem this snippet solves:

BIP-IP 10.2 backup script with SCP transfer option This script creates tar.bz2 archives which include a .ucs file and a .scf of the F5's configuration. It optionally stores them locally and/or transfers them to a remote system using SCP.

Code :

#!/bin/bash
# f5backup.sh
# Copyright (C) 2010 Colin Stubbs 
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <>
#
# Additional files you'll need to create, example content:
#
# # /etc/cron.d/f5backup
# SHELL=/bin/bash
# PATH=/sbin:/bin:/usr/sbin:/usr/bin
# MAILTO=user@somewhere
# HOME=/var/tmp
# 0 0 * * * root /bin/bash /var/local/bin/f5backup.sh 1>/var/tmp/f5backup.log 2>&1
# # EOF
#
# # /root/.ssh/f5archive_config
#
# Host *
#   User f5archive
#   PasswordAuthentication no
#   StrictHostKeyChecking yes
#   IdentityFile /root/.ssh/f5archive_dsa
#   Port 22
#   Protocol 2
#   Ciphers aes128-cbc,aes192-cbc,aes256-cbc
#   UserKnownHostsFile /root/.ssh/f5archive_host
#  
# # EOF
#
# REQUIRES:
#  F5 BIG-IP 10.2.x

# Debug ? Set to non-blank if so.
DEBUG=''

# Current date/time stamp
DATETIME="`date +%Y%m%d%H%M%S`"

# Base f5backup.sh working directory
OUT_DIR='/var/tmp'

# Unique temporary output location
TEMP_DIR="`mktemp -d ${OUT_DIR}/f5backup.XXXXXXXXXX`"

# Backup options
# Export a UCS archive
DO_UCS='x'
# Export a single config file
DO_SCF='x'
# Export SCF with oneline bigpipe statements
DO_SCF_ONELINE='x'

# Use SCP with pubkey to export to remote system
DO_SCP_EXPORT=1

# SCP options must be set if you want to use this
SCP_OPTIONS=""
# Destination list, can be a list of username:IPorHostname if you want to
# transfer to multiple destinations. Same public key used for auth to all.
# ** MAKE SURE YOU INCLUDE :<%DIRECTORY%> HERE
SCP_DESTINATION="f5archive@192.0.2.10:"
# All SCP options should be encapsulated in a special config file
SCP_CONFIG="/root/.ssh/f5archive_config"

# UCS output location
UCS_FILE="${TEMP_DIR}/ucs.${DATETIME}.backup"

# Encrypt UCS archive with passphrase
# ** If blank this will not be used
UCS_PASSPHRASE=''

# SCF output location
SCF_FILE="${TEMP_DIR}/scf.${DATETIME}.backup"

# Local archive location
# ** If this variable is blank, or the destination is not writable then
#    this script will not copy the backup to the local archive.
LOCAL_ARCHIVE="/var/local/backups"

# Remove all older local backups than this many days
LOCAL_CLEANUP_DAYS=7

# Name of compressed backup archive to produce
OUTPUT_FILE="f5backup-${HOSTNAME}-${DATETIME}.tar.bz2"

if [ "${DEBUG}x" != "x" ] ; then
  for i in HOSTNAME DATETIME OUT_DIR TEMP_DIR DO_UCS DO_SCF DO_SCF_ONELINE DO_SCP_EXPORT SCP_DESTINATION SCP_OPTIONS SCP_CONFIG ASM_POLICY_LIST UCS_FILE UCS_PASSPHRASE SCF_FILE LOCAL_ARCHIVE OUTPUT_FILE ; do
    eval var=\$$i
    echo "${i} = $var"
  done
fi

function usage {
  echo "Usage: f5backup.sh"
  exit 0
}

function export_scf() {
  if [ "${DEBUG}x" != "x" ] ; then echo "in ${FUNCNAME}(${*})" ; fi
  if [ "${DO_SCF}x" != "x" ] ; then
    if [ "${DO_SCF_ONELINE}x}" != "x" ] ; then
           bigpipe export oneline "${SCF_FILE}"
    else
           bigpipe export "${SCF_FILE}"
    fi
  fi
}

function export_ucs() {
  if [ "${DEBUG}x" != "x" ] ; then echo "in ${FUNCNAME}(${*})" ; fi
  if [ "${DO_UCS}x" != "x" ] ; then
    if [ "${UCS_PASSPHRASE}x" != "x" ] ; then
      bigpipe config save "${UCS_FILE}" passphrase "${UCS_PASSPHRASE}"
    else
      bigpipe config save "${UCS_FILE}"
    fi
  fi
}

function create_backup() {
  if [ "${DEBUG}x" != "x" ] ; then echo "in ${FUNCNAME}(${*})" ; fi
  tar -v -j -c -f "${OUT_DIR}/${OUTPUT_FILE}" -C "${TEMP_DIR}" .
}

# Transfer backup archive to offsite location/s
function backup_remote() {
  if [ "${DEBUG}x" != "x" ] ; then echo "in ${FUNCNAME}(${*})" ; fi
  if [ -f "${OUT_DIR}/${OUTPUT_FILE}" ] ; then
    if [ "${DO_SCP_EXPORT}x" != "x" ] ; then

      echo "Copying to remote archive ${SCP_DESTINATION}${OUTPUT_FILE}"

      if [ "${DEBUG}x" != "x" ] ; then echo "Exec: /usr/bin/scp ${SCP_OPTIONS} -F ${SCP_CONFIG} ${OUT_DIR}/${OUTPUT_FILE} ${SCP_DESTINATION}" ; fi
      /usr/bin/scp ${SCP_OPTIONS} -F "${SCP_CONFIG}" "${OUT_DIR}/${OUTPUT_FILE}" "${SCP_DESTINATION}" || echo "Error: SCP ${OUT_DIR}/${OUTPUT_FILE} ${SCP_DESTINATION} failed!"

    fi
  else
    echo "Error: ${OUT_DIR}/${OUTPUT_FILE} doesn't exist, something has gone wrong!"
  fi
}

function backup_local() {
  if [ "${DEBUG}x" != "x" ] ; then echo "in ${FUNCNAME}(${*})" ; fi
  if [ "${LOCAL_ARCHIVE}x" != "x" ] && [ -d "${LOCAL_ARCHIVE}" ] ; then

    echo "Copying to local archive ${LOCAL_ARCHIVE}/${OUTPUT_FILE}"

    if [ ! -d "${LOCAL_ARCHIVE}" ] ; then
      mkdir "${LOCAL_ARCHIVE}"
      if [ ${?} -ne 0 ] ; then
        echo "Error: ${LOCAL_ARCHIVE} doesn't exist and I can't create it."
      fi
    fi

    mv -f "${OUT_DIR}/${OUTPUT_FILE}" "${LOCAL_ARCHIVE}"/

    find "${LOCAL_ARCHIVE}" -type f -mtime +${LOCAL_CLEANUP_DAYS} -exec rm -v -f {} \;
  fi
}

# Cleanup what this script has done
function cleanup() {
  if [ "${DEBUG}x" != "x" ] ; then echo "in ${FUNCNAME}(${*})" ; fi
  rm -rf ${TEMP_DIR}
}

# Sanity checking
# 1. Must be run as root
if [ "`id -u`x" != "0x" ] ; then
  echo "Error: You need to run this script as root."
  exit 1
fi

# 2. Command line args
#  not applicable yet

# 3. Temp dir must exist
if [ ! -d "${TEMP_DIR}" ] ; then
  echo "Error: ${TEMP_DIR} was not created for some reason. Fix this issue and try again."
  exit 1
fi

echo "${0} start `date +%Y%m%d%H%M%S`"

export_ucs
export_scf

create_backup

backup_remote
backup_local

cleanup

echo "${0} finish `date +%Y%m%d%H%M%S`"

# EOF

Tested this on version:

10.2
Published Jan 30, 2015
Version 1.0