Last active
August 9, 2016 20:04
-
-
Save samirfor/5076212e47857907c3808acf9f85123f to your computer and use it in GitHub Desktop.
Backup das configurações do pfSense 2.x de forma remota
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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