Skip to content

Instantly share code, notes, and snippets.

@samirfor
Last active August 9, 2016 20:04
Show Gist options
  • Save samirfor/5076212e47857907c3808acf9f85123f to your computer and use it in GitHub Desktop.
Save samirfor/5076212e47857907c3808acf9f85123f to your computer and use it in GitHub Desktop.
Backup das configurações do pfSense 2.x de forma remota
#!/bin/bash
#
## Backup das configurações do pfSense de forma remota
#####################
# Configurações #
#####################
DIR="/backups/pfsense" # sem o barra no final
COD_RETORNO=0 # 0-OK | 1-Erro de login | 2-Arquivo não é XML
PROTOCOLO="https" # https ou http
NUM_PINGS=3 # pinga para verificar se host está vivo
WGET_OPTIONS="--no-check-certificate --keep-session-cookies --timeout 3"
DEBUG=0 # 0-desativado | 1-ativado
# Lista de pfSenses
IPS[1]=""
USERNAMES[1]=""
PASSWORDS[1]="" # texto plano
IPS[2]=""
USERNAMES[2]=""
PASSWORDS[2]="" # texto plano
# TODO implementar lista de pfSenses em um JSON ou XML | lib jq
###############
# Funções #
###############
remote_backup(){
local IP=$1
local USERNAME=$2
local PASSWORD=$(urlencode $3)
local RAND=$(cat /dev/urandom | tr -cd 'a-f0-9' | head -c 32)
local COOKIES="/tmp/${RAND}cookies.txt"
local CSRF="/tmp/${RAND}csrf.txt"
local CSRF2="/tmp/${RAND}csrf2.txt"
local FILE="pfsense-config-$IP-`date +%Y%m%d%H%M%S`.xml"
local BKPFILE="$DIR/$FILE"
if [ $DEBUG == 0 ]; then WGET_OPTIONS="$WGET_OPTIONS -q"; fi # add verbose ao wget
# download xml
wget $WGET_OPTIONS -qO- --save-cookies "$COOKIES" \
"$PROTOCOLO://$IP/diag_backup.php" \
| grep "name='__csrf_magic'" | sed 's/.*value="\(.*\)".*/\1/' > "$CSRF"
wget $WGET_OPTIONS -qO- --load-cookies "$COOKIES" \
--save-cookies "$COOKIES" \
--post-data "login=Login&usernamefld=${USERNAME}&passwordfld=${PASSWORD}&__csrf_magic=$(cat $CSRF)" \
"$PROTOCOLO://$IP/diag_backup.php" | grep "name='__csrf_magic'" \
| sed 's/.*value="\(.*\)".*/\1/' > "$CSRF2"
wget $WGET_OPTIONS --load-cookies "$COOKIES" \
--post-data "Submit=download&donotbackuprrd=yes&__csrf_magic=$(head -n 1 $CSRF2)" \
"$PROTOCOLO://$IP/diag_backup.php" -O "$BKPFILE"
# verifica se retornou um html com erro
grep -i "Username or Password incorrect" "${BKPFILE}" > /dev/null 2>&1
ERROR1=$?
grep -i "<\/html>" "${BKPFILE}" > /dev/null 2>&1
ERROR2=$?
if [ $ERROR1 -eq "0" ]; then
if [ $DEBUG == 0 ]; then head ${BKPFILE}; fi
logger -s "usuário ou senha incorreto."
rm -f "${BKPFILE}"
rm -f "$CSRF" "$CSRF2" "$COOKIES"
COD_RETORNO=1
return $COD_RETORNO
fi
if [ $ERROR2 -eq "0" ]; then
if [ $DEBUG == 0 ]; then head ${BKPFILE}; fi
logger -s "erro no backup pfsense ${IPS[$c]}. ${BKPFILE} é um html ao invés de xml."
rm -f "${BKPFILE}"
rm -f "$CSRF" "$CSRF2" "$COOKIES"
COD_RETORNO=2
return $COD_RETORNO
fi
# verifica se arquivo xml é válido
xmllint --noout "${BKPFILE}" > /dev/null 2>&1
ERROR3=$?
if [ $ERROR3 -ne "0" ]; then
if [ $DEBUG == 0 ]; then head ${BKPFILE}; fi
logger -s "erro no backup pfsense ${IPS[$c]}. ${BKPFILE} é um xml inválido."
COD_RETORNO=3
rm -f "${BKPFILE}"
rm -f "$CSRF" "$CSRF2" "$COOKIES"
return $COD_RETORNO
fi
rm -f "$CSRF" "$CSRF2" "$COOKIES"
}
isalive() {
local HOST=$1
COUNT=$(ping -c $NUM_PINGS $HOST | \
grep 'received' | \
awk -F',' '{ print $2 }' | \
awk '{ print $1 }' \
)
if [ $COUNT -eq 0 ]; then
# 100% failed
logger -s "$HOST inacessível via ICMP (ping falhou $NUM_PINGS vezes)"
return 1
fi
return 0
}
urlencode() {
# urlencode <string>
old_lc_collate=$LC_COLLATE
LC_COLLATE=C
local length="${#1}"
for (( i = 0; i < length; i++ )); do
local c="${1:i:1}"
case $c in
[a-zA-Z0-9.~_-]) printf "$c" ;;
*) printf '%%%02X' "'$c" ;;
esac
done
LC_COLLATE=$old_lc_collate
}
#############
# Rodando #
#############
# verifica se as dependências estão instaladas
DEPENDENCIAS=( "wget" "xmllint" "grep" "awk" "ping" "logger" "head" )
for DEP in "${DEPENDENCIAS[@]}"
do
type $DEP > /dev/null 2>&1 || {
msg="$DEP não instalado. Abortando."
echo $msg
logger $msg
echo
COD_RETORNO=1
exit 1
}
done
# verifica se $DIR existe
if [ ! -d "$DIR" ]; then
logger -s "pasta $DIR não encontrada, usando /tmp"
DIR="/tmp"
fi
for (( c=1; c<=${#IPS[@]}; c++ )); do
if [ "${IPS[$c]}x" == "x" ] || \
[ "${USERNAMES[$c]}x" == "x" ] || \
[ "${PASSWORDS[$c]}x" == "x" ]; then
continue # ignore config em branco
fi
logger -s "backup [$c] pfsense ${IPS[$c]} ..."
isalive ${IPS[$c]}
if [ "$?" != 0 ]; then continue; fi
remote_backup ${IPS[$c]} ${USERNAMES[$c]} ${PASSWORDS[$c]}
if [ "$?" == "0" ]; then
logger -s "${IPS[$c]} - OK"
else
logger -s "${IPS[$c]} - erro"
fi
done
exit $COD_RETORNO
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment