BIG-IP backup script with SCP transfer

Problem this snippet solves:

BIP-IP backup script with SCP transfer option. First version works with 10.2 (bigpipe) command. Second version works with 11.2 (tmsh). 11.2 version also contains some logic fixes.

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 
# Changes to 11.2.x (tmsh syntax) and additional logic by Tim Davies 
#
# 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 11.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@10.50.108.12:"
# 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"

# tar output location
TAR_FILE="${TEMP_DIR}/scf.${DATETIME}.backup.tar"
# 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
           tmsh save sys config one-line file "${SCF_FILE}"
    else
           tmsh save sys config one-line file "${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
      tmsh save sys ucs "${UCS_FILE}" passphrase "${UCS_PASSPHRASE}"
    else
      tmsh save sys ucs "${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" ]  ; 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}
if [ -f "${OUT_DIR}/${OUTPUT_FILE}" ] ; then
     rm -f "${OUT_DIR}/${OUTPUT_FILE}"
    fi
}

# 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:

11.2
Published Mar 12, 2015
Version 1.0