Desktop
System
- Ansible from scratch
- Ansible
- AWX
- Using Docker
- MySQL Replication
- Nginx
- Percona XtraDB Cluster
- SELinux Samba share
- Sphinx
- Systemd
Bash
Awk
- Getting Started with awk
- Running awk and gawk
- Regular Expressions
- Reading Input Files
- Record number
- Record splitting with standard awk
- Record splitting with gawk
- Fields
- Contents of a field
- How fields are separated
- Each character a separate field
- FS from the command line
- Field-splitting summary
- Record-splitting summary
- Multiple-line records
- Explicit input with getline
- Getline summary
- Input with a timeout
- Printing Output
- Expressions
- Patterns, Actions, and Variables
- Arrays in awk
- Functions
Backup pfSenseΒΆ
See also
#!/bin/bash
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
# guisam
set -u
set -o pipefail
# General variables
typeset TARGET="false"
typeset USER="admin"
typeset PASSWD="pfsense"
typeset WGET="wget --no-check-certificate --quiet"
typeset -r TMPDIR=$(mktemp -d)
typeset -r COOKIE="${TMPDIR}/cookie.txt"
typeset -r CSRF1_FILE="${TMPDIR}/csrf1.txt"
typeset -r CSRF2_FILE="${TMPDIR}/csrf2.txt"
typeset -r TIMESTAMP="$(date +%F%T|sed 's/[-:]//g')"
typeset BACKUPDIR="$HOME"
typeset BACKUPNAME="config-router"
typeset -r BACKUPTMP="${TMPDIR}/${BACKUPNAME}.${TIMESTAMP}.xml"
typeset -r RETENTION_PATTERN="^[0-9]+$"
typeset RETENTION="false"
# Display variables
typeset -r NORMAL="\e[0m"
typeset -r BOLD="\e[1m"
typeset -r RED="\e[0;31m"
# Functions
backup_config () {
local BACKUPFILE="${BACKUPDIR}/${BACKUPNAME}.${TIMESTAMP}.xml"
local BACKUPTMP_HASH=$(get_file_hash ${BACKUPTMP})
local BACKUPFILE_PATTERN="${BACKUPDIR}/${BACKUPNAME}*.xml"
ls ${BACKUPFILE_PATTERN} &> /dev/null
[[ $? == 0 ]] && \
for BACKUPLIST_FILE in ${BACKUPFILE_PATTERN}; do
local BACKUPLIST_FILE_HASH=$(get_file_hash ${BACKUPLIST_FILE})
[[ ${BACKUPTMP_HASH} == ${BACKUPLIST_FILE_HASH} ]] && \
return
done
cp "${BACKUPTMP}" "${BACKUPFILE}"
}
check_dir_option () {
local DIR_OPTION="$1"
[[ -d ${DIR_OPTION} ]] && \
BACKUPDIR="${DIR_OPTION}" || \
error "${DIR_OPTION}: no such directory found on ${HOSTNAME}."
}
check_ret_option () {
local RETENTION_OPTION="$1"
[[ ${RETENTION_OPTION} =~ ${RETENTION_PATTERN} ]] || \
error "${RETENTION_OPTION} is not an integer." && \
[[ ${RETENTION_OPTION} == 0 ]] && \
error "Option -r have to be greater than 0." || \
RETENTION="${RETENTION_OPTION}"
}
check_target_option () {
local TARGET_OPTION="$1"
TARGET=${TARGET_OPTION}
nc -z -w1 ${TARGET_OPTION} 443 || \
error "Port 443 is unreachable on ${TARGET_OPTION}."
}
clean_backup_directory () {
local CURRENT_DIR=$(ls -tr1 ${BACKUPDIR}/${BACKUPNAME}.*.xml|wc -l)
[[ ${RETENTION} != false ]] && \
[[ ${RETENTION} -lt ${CURRENT_DIR} ]] && \
ls -tr1 ${BACKUPDIR}/${BACKUPNAME}.*.xml | \
head -n -"${RETENTION}" | xargs -d '\n' rm --
}
clean_tmp () {
rm -rf "${TMPDIR}"
}
error ()
{
echo -e "${RED}${BOLD}$*${NORMAL}\n" >&2
exit 1
}
get_current_config () {
local URL="https://${TARGET}/diag_backup.php"
${WGET} -O- --keep-session-cookies --save-cookies ${COOKIE} \
${URL} | grep "name='__csrf_magic'" \
| sed 's/.*value="\(.*\)".*/\1/' > ${CSRF1_FILE}
${WGET} -O- --keep-session-cookies --load-cookies ${COOKIE} --save-cookies ${COOKIE} \
--post-data "login=Login&usernamefld=${USER}&passwordfld=${PASSWD}&__csrf_magic=$(cat ${CSRF1_FILE})" \
${URL} | grep "name='__csrf_magic'" | sed 's/.*value="\(.*\)".*/\1/' > ${CSRF2_FILE}
${WGET} --keep-session-cookies --load-cookies ${COOKIE} \
--post-data "download=download&donotbackuprrd=yes&__csrf_magic=$(head -n 1 ${CSRF2_FILE})" \
${URL} -O ${BACKUPTMP}
}
get_file_hash () {
local BACKUPFILE="$1"
local BACKUPFILE_HASH=$(sha256sum < ${BACKUPFILE} | awk '{print $1}')
echo ${BACKUPFILE_HASH}
}
parse_options ()
{
while getopts ":ht:u:p:vd:n:r:" OPTION
do
case ${OPTION} in
h)
usage
clean_tmp
exit 0
;;
t)
check_target_option "${OPTARG}"
;;
u)
USER="${OPTARG}"
;;
p)
PASSWD="${OPTARG}"
;;
v)
WGET="wget --no-check-certificate"
;;
d)
check_dir_option "${OPTARG%\/}"
;;
n)
BACKUPNAME="${OPTARG}"
;;
r)
check_ret_option "${OPTARG}"
;;
:)
error "Missing option argument for -${OPTARG}."
;;
*)
error "Unknown option: -${OPTARG}."
;;
esac
done
[[ ${TARGET} = false ]] && \
error "Option -t (target) is mandatory.\nSee help with -h option."
}
usage ()
{
local CMD=$(basename $0)
cat <<-EOL
backup_pfsense
Create a backup for Pfsense version 2.3.3 and later.
Back up the configuration only if this one changed.
Usage : ${CMD} -t <target> [-u <user>] [-p <passwd>] [-v] [-d <dir>] [-n <name>] [-r <num>]
Options:
-h display this help
-t target address IP, mandatory
-u target account user, default: admin
-p target account password, default: pfsense
-d local backup directory, default: \$HOME
-n local backup file name, default: config-router
-r local backup retention, default: keep all
-v verbose donwload
Example:
backup_pfsense -t 172.16.0.254 -u backup -p toto1234 -d /home/guigui/Desktop -n my_pfsense -r 2
EOL
}
# Main
parse_options "$@"
get_current_config
backup_config
clean_backup_directory
clean_tmp
exit 0