Annexe : Automatisation de l'exploitation iLinux v1
Script d'automatisation de la sauvegarde serveur (distant) web & databases
./sauvegarde_srv_web-db.sh
#!/bin/bash
###############################################################################
# #
# PGM : Script de sauvegarde serveur (distant) web & databases #
# #
# AUTEUR : Stephane (iLinux) #
# VERSION : 1.0.0 #
# #
# DATE : 03/06/2019 #
# #
# PARAM. : N/A #
# OUT > logger + mail #
# #
###############################################################################
# EN PREMIER LIEU
# On inclus les fonctions et variables communes:
. ~/Prod/Scripts/fonctions_variables.sh
# Variables de travail ...
# ... LOCALES
# ... DISTANTES
# N/A
# Au commencement il n'y a jamais d'erreur ... dans un script
G_ERREUR=0
# Serveur à sauvegarder :
SERVEUR=$1
# Surcharge var. fichier log (en attendant serveur mail !)
#G_FICHIER_LOG="/root/Prod/Journaux/Sauvegardes/$SERVEUR.log"
# Script actuellement en cours d'execution
echo "SCRIPT : $G_APPLI"
echo "" >> $G_FICHIER_LOG
echo ">>>> $G_APPLI sur serveur : \"$SERVEUR\", executé le $G_JOUR $G_DATE">> $G_FICHIER_LOG
echo "" >> $G_FICHIER_LOG
# 1 seul paramétre attendu
#if [ $# = 1 ] || [ -z "$1"]
#then
# G_ERREUR='Donnez 1 nom de serveur svp ...'
# # On sort du script avec $G_ERREUR
# g_log_message "ERROR" $G_MSG_FIN_SCRIPT
# exit $G_ERREUR
#fi
# DEBUT DU SCRIPT
g_log_message "INFO" $G_MSG_DEBUT_SCRIPT
g_log_message "INFO" "Parametres : \"$*\""
# Préparation sauvegarde
#
# On stoppe le serveur web distant ...
gestionServiceServeur $SERVEUR "stop" "nginx"
# On fait les "dump" Mysql et PostgreSQL des bases sur le serveur distant sous "/root/Prod/Sauvegardes/Bases" ...
# Rappel : sauvegardeBasesServeur server dbType dbDumpDir
sauvegardeBasesServeur $SERVEUR "mysql" "/root/Prod/Sauvegardes/Bases"
sauvegardeBasesServeur $SERVEUR "postgresql" "/root/Prod/Sauvegardes/Bases"
# On lance la sauvegarde du système de fichiers ... (localement via le montage sshFS)
depotBorgBackup="/Sauvegardes/Prod/$SERVEUR"
mountDist="/root/Prod/mnt/BorgBackup/$SERVEUR"
# ATTENTION : /root/Prod/mnt/BorgBackup/ ... (via sshFS)
repertoiresAsauvegarder="$mountDist/etc $mountDist/root $mountDist/home $mountDist/var"
sauvegardeBorgBackupServeur $SERVEUR "$depotBorgBackup" "$repertoiresAsauvegarder"
# On relance le serveur Web distant
gestionServiceServeur $SERVEUR "start" "nginx"
# On audit le système de fichier distant (volumétrie etc)
statutSFServeur $SERVEUR
# On audit le système de sauvegarde
statutBorgBackup "$depotBorgBackup"
# On sort du script avec $G_ERREUR
g_log_message "INFO" $G_MSG_FIN_SCRIPT
exit $G_ERREUR
# FIN DU SCRIPT
Boîte à outils : script de fonctions et variables réutilisables
./fonctions_variables.sh
#!/bin/bash
###############################################################################
# #
# PGM : Script de fonctions et variables réutilisables #
# #
# AUTEUR : Stephane #
# VERSION : 1.0.0 #
# #
# DATE : 02/06/2019 #
# #
# PARAM. : IN < N/A #
# OUT > N/A #
# #
###############################################################################
# Variables de travail ...
# ... LOCALES
# ... DISTANTES
# N/A
# Chemin complet des outils utilises A GARDER POUR PORTABILITE MULTI-PLATEFORME etc ...
# Ce fichier, amene a evoluer, contient en ensemble de fonctions et variables
# globales courament utilisees.
########################### NOMENCLATURE (rajouter ici vos régles de nommage)
#
# Variable GLOBALE (doit etre reutilisee dans plusieurs script)
# Elle est prefixee d'un "G_" comme "G_lobale"
# G_<nom_variable>
# Variable LOCALE (utilisable dans un script particulier)
# a Elle n'est pas prefixee, et n'a donc pas lieu d'etre dans ce fichier
# ormis leur présence dans les fonctions
# <nom_variable>
# IDEM pour les fonctions : g_<nom_fonction>
# Par defaut quand nous definissons un chemin (PATH) nous ne mettrons jamais de "/"
# en fin de chemin (cf. code ci-dessous)
# Ce fichier contient une section GLOBALE et une section APPLI (specifique a certains scripts)
###############################################################################
# #
# GLOBALE #
# #
###############################################################################
#
####### VARIABLES GLOBALES #####################################################
# ELLES SONT OBLIGATOIRES POUR TOUT SCRIPT ECRIT
export LANG=fr_FR.UTF-8 # NE PAS MODIFIER => sinon les jours ci-dessous seront en anglais.
# MERCI
G_DATE=`date +%d\ %b\ %T`
G_JOUR=`date "+%A"`
#G_NOM_MACHINE=`hostname`
G_NOM_MACHINE=$1
G_APPLI=`basename $0`
G_PID_APPLI=$$
G_FICHIER_LOG="/root/Prod/Journaux/Sauvegardes/$G_APPLI.log"
G_COURRIEL_TXT="/root/Prod/Journaux/Sauvegardes/$G_APPLI-COURRIEL.txt"
G_CONTACTS_MAIL="yourMonitoringMail@domain.tld"
G_SUJET_MAIL="$G_APPLI sur $G_NOM_MACHINE"
# Message de debut et fin de script
G_MSG_DEBUT_SCRIPT="DEBUT-SCRIPT"
G_MSG_FIN_SCRIPT="FIN-SCRIPT"
# Il faudra mettre G_ERREUR=1 en cas de soucis et
# bien sure ne jamais remettre a "0" cette variable !!!
# Chemin complet des outils utilises A GARDER POUR PORTABILITE MULTI-PLATEFORME etc ...
SSH="/usr/bin/ssh"
#TAR="/bin/tar"
MKDIR="/bin/mkdir"
#LN="/bin/ln"
#CHOWN="/bin/chown"
#CHMOD="/bin/chmod"
#CP="/bin/cp"
#USERMOD="/usr/sbin/usermod"
LOGGER="/usr/bin/logger"
#MAIL="/usr/bin/mail"
MSMTP="/usr/bin/msmtp"
RM="/bin/rm"
CAT="/bin/cat"
DU="/usr/bin/du"
DF="/bin/df"
TEE="/usr/bin/tee"
SYSTEMCTL='/bin/systemctl'
SLEEP='/bin/sleep'
SYNC='/bin/sync'
UMOUNT='/bin/umount'
MOUNT='/bin/mount'
GREP='/bin/grep'
GZIP='/bin/gzip'
HOSTNAME='/bin/hostname'
SMARTCTL='/usr/sbin/smartctl'
CEPH='/usr/bin/ceph'
WHICH='/usr/bin/which'
# -> NE PAS ENLEVER MERCI.
# Fonction qui permet de loger les messages d'erreurs, d'informations, de warning etc ...
# Param IN $1 = TYPE du Message, gravité( INFO ou ERROR)voir doc. facility syslog
# $2 = MESSAGE a loger
# ex: g_log_message "INFO" "script arrêté"
function g_log_message ()
{
local TYPE=$1
local MESSAGE=$2
#Mise à jour de la date et de l'heure
G_DATE=`date +%d\ %b\ %T`
G_JOUR=`date "+%A"`
# On prépare le formatage du type d'erreur pour le systeme SYSLOG (utilisation des priorités de logger : les "facilities" de syslog)
case $TYPE in
INFO) LOG_FACILITY=local3.info
;;
ERROR) LOG_FACILITY=local3.error
;;
WARNING) LOG_FACILITY=local3.warning
;;
# AUTRE_TYPE) LOG_FACILITY=prefix.type
# ;;
*) #TODO codage type inconnu : on ne fait rien
;;
esac
# Mise en forme des informations pour affichage :
local INFOS_APPLI="$G_NOM_MACHINE $G_APPLI[$G_PID_APPLI]:"
# ... sur sortie standard
echo $G_JOUR $G_DATE $INFOS_APPLI [$TYPE] $MESSAGE
# ... dans le fichier log
echo $G_JOUR $G_DATE $INFOS_APPLI [$TYPE] $MESSAGE >> $G_FICHIER_LOG
# ... dans les log du système d'exploitation
local DETAIL_APPLI="$G_APPLI[$G_PID_APPLI]"
$LOGGER -t $DETAIL_APPLI -p $LOG_FACILITY $MESSAGE
# Si c'est la fin du script on envoie un mail avec le fichier de log complet
if [ "$MESSAGE" == "$G_MSG_FIN_SCRIPT" ]
then
if [ $G_ERREUR -eq 0 ]
then
G_SUJET_MAIL="SUCCES : $G_SUJET_MAIL"
else
G_SUJET_MAIL="ECHEC : $G_SUJET_MAIL"
fi
# On log la tache en cours ...
echo $G_JOUR $G_DATE $INFOS_APPLI [$TYPE] "Courriel de notification" >> $G_FICHIER_LOG
# Puis on prépare le fichier du courriel ($G_COURRIEL_TXT) et on lui ajoute le contenu du log ($G_FICHIER_LOG)
echo -e "Subject: "$G_SUJET_MAIL"\r\n""Content-Type: text/plain; charset=UTF-8""\r\n" > $G_COURRIEL_TXT
$CAT $G_FICHIER_LOG >> $G_COURRIEL_TXT
# On envoie le courriel
$CAT $G_COURRIEL_TXT | $MSMTP $G_CONTACTS_MAIL
# ... et on les supprime (option -v disparue)
$RM -f $G_FICHIER_LOG
$RM -f $G_COURRIEL_TXT
fi
}
function statutSF ()
{
# Statistiques diverses
echo "" >> $G_FICHIER_LOG
echo " >>>> Statistiques du système de fichiers ..." >> $G_FICHIER_LOG
echo "" >> $G_FICHIER_LOG
$DF -Hl >> $G_FICHIER_LOG
echo "" >> $G_FICHIER_LOG
}
function statutSFServeur ()
{
local server=$1
# Statistiques diverses
echo "" >> $G_FICHIER_LOG
echo " >>>> Statistiques du système de fichiers distant de \""$server\"" ..." >> $G_FICHIER_LOG
echo "" >> $G_FICHIER_LOG
local command="$DF -Hl"
$SSH $server $command >> $G_FICHIER_LOG
echo "" >> $G_FICHIER_LOG
}
function statusSmartServeur ()
{
local server=$1
shift # On enlève le premier arguments ($SERVEUR), pour traiter les devices (/dev/sdx)
while [ $# -ge 1 ]; do #on sort après avoir traiter tous les arguments $#=0) => LOOP pas top a virer !!! ASAP
# Récupération état SMART du périphérique passé en paramètre ...
echo "" >> $G_FICHIER_LOG
echo " >>>> Etat SMART du périphérique \""$1\"" de \""$server\"" ..." >> $G_FICHIER_LOG
echo "" >> $G_FICHIER_LOG
local command="$SMARTCTL -H -i $1"
$SSH $server $command >> $G_FICHIER_LOG
echo "" >> $G_FICHIER_LOG
shift
done
}
function statusCephServeur ()
{
local server=$1
# Récupération état SMART du périphérique passé en paramètre ...
echo "" >> $G_FICHIER_LOG
echo " >>>> Etat du système de fichiers distribué CEPH de \""$server\"" ..." >> $G_FICHIER_LOG
echo "" >> $G_FICHIER_LOG
local command="$CEPH health"
$SSH $server $command >> $G_FICHIER_LOG
local command2="$CEPH df"
$SSH $server $command2 >> $G_FICHIER_LOG
echo "" >> $G_FICHIER_LOG
}
function statusRaidServeur ()
{
local server=$1
# Récupération état système RAID ...
echo "" >> $G_FICHIER_LOG
echo " >>>> Etat du système RAID de \""$server\"" ..." >> $G_FICHIER_LOG
echo "" >> $G_FICHIER_LOG
local command="$CAT /proc/mdstat"
$SSH $server $command >> $G_FICHIER_LOG
echo "" >> $G_FICHIER_LOG
}
function statutBorgBackup ()
{
local borgBackupRepository=$1
# Chemin complet des outils utilises A GARDER POUR PORTABILITÉ MULTI-PLATEFORME etc ...
local BORG='/usr/bin/borg'
echo "" >> $G_FICHIER_LOG
echo " >>>> Statistiques du système de sauvegarde ..." >> $G_FICHIER_LOG
$BORG list $borgBackupRepository >> $G_FICHIER_LOG
echo "" >> $G_FICHIER_LOG
}
function serveurJoignable ()
{
local server=$1
$SSH $server $HOSTNAME > /dev/null
ret=$?
if [ $ret -ne 0 ];then # ... erreur pour récupérer le nom d'hote du serveur distant
G_ERREUR=$ret
g_log_message "ERROR" "Serveur \"$server\" injoignable, ssh: \"$G_ERREUR\""
return $G_ERREUR
else
g_log_message "INFO" "Serveur \"$server\" en ligne"
return 0
fi
}
function gestionService ()
{
local action=$1
local service=$2
$SYSTEMCTL $action $service
ret=$?
if [ $ret -ne 0 ];then # ... erreur à l'arrêt/démarrage du service
G_ERREUR=$ret
g_log_message "ERROR" "$action \"$service\" impossible \"$G_ERREUR\""
return $G_ERREUR
else
g_log_message "INFO" "$action \"$service\""
return 0
fi
}
function gestionServiceServeur ()
{
local server=$1
local action=$2
local service=$3
# Serveur en ligne ?
serveurJoignable $server
ret=$?
if [ $ret -ne 0 ];then # ... erreur serveur injoignable, on sort avec le code erreur.
return $ret
fi
local command="$SYSTEMCTL $action $service"
$SSH $server $command > /dev/null
ret=$?
if [ $ret -ne 0 ];then # ... erreur à l'arrêt/démarrage du service
G_ERREUR=$ret
g_log_message "ERROR" "Serveur \"$server\" : \"$action\" \"$service\" impossible \"$G_ERREUR\""
return $G_ERREUR
else
g_log_message "INFO" "Serveur \"$server\" : \"$action\" \"$service\""
return 0
fi
}
function demontage ()
{
local pointMontage=$1
$UMOUNT $pointMontage
ret=$?
if [ $ret -ne 0 ];then # ... erreur au démmontage
G_ERREUR=$ret
g_log_message "ERROR" "Impossible de démonter \"$pointMontage\" erreur \"$G_ERREUR\""
return $G_ERREUR
else
g_log_message "INFO" "Démontage de \"$pointMontage\""
return 0
fi
}
function montageHdd ()
{
local pointMontage=$1
$MOUNT $pointMontage
ret=$?
if [ $ret -ne 0 ];then # ... erreur au montage
G_ERREUR=$ret
g_log_message "ERROR" "Impossible de monter \"$pointMontage\" erreur \"$G_ERREUR\""
return $G_ERREUR
else
g_log_message "INFO" "Montage de \"$pointMontage\""
return 0
fi
}
function montageSshFS ()
{
local SSHFS='/usr/bin/sshfs'
#local SSHFS='/usr/bin/sshfs -oCiphers=arcfour'
local server=$1
local pointMontage=$2
$SSHFS $server:/ $pointMontage &>> $G_FICHIER_LOG
ret=$?
if [ $ret -ne 0 ];then # ... erreur au montage
G_ERREUR=$ret
g_log_message "ERROR" "Impossible de monter \"$pointMontage\" de \"$server\" erreur \"$G_ERREUR\""
return $G_ERREUR
else
g_log_message "INFO" "Montage \"$pointMontage\" de \"$server\""
return 0
fi
}
#function sauvegardeBase () # SI utilisé : CODE à RELIRE !!!
#{
#
#}
function sauvegardeBasesServeur ()
{
local server=$1 #serveur cible
local dbType=$2 #mysql ou postgresql
local dbDumpDir=$3 #répertoire ou sera placé le dump sur le $server distant
# Chemin complet des outils utilises A GARDER POUR PORTABILITÉ MULTI-PLATEFORME etc ...
local MYSQLDUMP='/usr/bin/mysqldump'
local POSTGRESQLDUMP='/usr/bin/pg_dump'
local POSTGRESQLDUMPALL='/usr/bin/pg_dumpall'
local SYNC='/bin/sync'
local dbUser=''
local dbName=''
local dbPwd=''
# Preparation env. dump sur serveur distant
# Note : Il n'y a théoriquement plus de transaction sur la base de données car les services susceptibles de provoquer des update etc sont arrêtés, les FS SYNC
local command="$SSH $server [ -d $dbDumpDir]"
if [ command ];then # Si le repertoire ou sera déposé le dump n'est pas présent ...
local command="$MKDIR -p $dbDumpDir" # ... alors nous le créons.
$SSH $server $command > /dev/null
ret=$?
if [ $ret -ne 0 ];then # ... erreur à la création du répertoire contenant le dump des bases de données
G_ERREUR=$ret
g_log_message "ERROR" "Impossible d'acceder au repertoire de dump \"$dbDumpDir\" erreur \"$G_ERREUR\""
return $G_ERREUR
fi
fi
case $dbType in
mysql)
# On test si MySQL est présent ... sinon on sort
command="$WHICH mysql"
$SSH $server $command > /dev/null
ret=$? # On stocke le code retour de la commande
if [ $ret -ne 0 ];then # ... erreur
g_log_message "WARNING" "\"$dbType\" non disponible"
return 0
fi
# ... mysql présent , on continue !
dbName='--all-databases' # Toutes les bases (option Mysql, donc ne pas changer SVP!!!!!)
dbUser='root'
dbPwd=$pwd_cache
# Préparation de la commande pour MySql
#local command="$MYSQLDUMP -u$dbUser -p$dbPwd -h localhost --single-transaction --opt $dbName > $dbDumpDir/$server-$dbType-$dbName.sql"
local command="$MYSQLDUMP -u$dbUser -p$dbPwd -h localhost --opt $dbName > $dbDumpDir/$server-$dbType-$dbName.sql"
;;
postgresql)
# On test si PostgreSQL est présent ... sinon on sort
command="$WHICH psql"
$SSH $server $command > /dev/null
ret=$? # On stocke le code retour de la commande
if [ $ret -ne 0 ];then # ... erreur
g_log_message "WARNING" "\"$dbType\" non disponible"
return 0
fi
# ... postgresql présent , on continue !
dbName='--full' # Toutes les bases (nommage ilinux)
dbUser='postgres' # fonctionne avec le fichier /root/.pgpass, en chmod 0600, et un password à postgres (psql : \password)
# Préparation de la commande pour PostgreSQL
local command="$POSTGRESQLDUMPALL -U $dbUser -h localhost > $dbDumpDir/$server-$dbType-$dbName.sql"
;;
*) # Base de donnée inconnue : ERREUR
G_ERREUR=1
g_log_message "ERROR" "Impossible de sauvegarder le type de base \"$dbType\""
return $G_ERREUR
;;
esac
# On lance l'export des bases de données :
$SSH $server $command > /dev/null
ret=$? # On stocke le code retour de la commande
# on teste le resultat de l'export des bases de données :
if [ $ret -ne 0 ];then # ... erreur durant le dump(export)
G_ERREUR=$ret
g_log_message "ERROR" "Export impossible des bases \"$dbType\" erreur \"$G_ERREUR\""
return $G_ERREUR
else
g_log_message "INFO" "Export des bases \"$dbType\" sous \"$dbDumpDir\""
fi
# Compression de l'export des bases de données, avec SYNC du systéme de fichiers préalable :
command="$SYNC ; $GZIP -f $dbDumpDir/$server-$dbType-$dbName.sql"
$SSH $server $command > /dev/null
ret=$? # On test le resultat de la compression ...
if [ $ret -ne 0 ];then # ... erreur durant la compression de l'export
G_ERREUR=$ret
g_log_message "ERROR" "Compression impossible du fichier \"$dbDumpDir/$server-$dbType-$dbName.sql\" erreur \"$G_ERREUR\""
return $G_ERREUR
else
g_log_message "INFO" "Compression du fichier \"$dbDumpDir/$server-$dbType-$dbName.sql\" sous \"$dbDumpDir\""
return 0
fi
# On synchronise les I/O (entrée sorties du système de fichiers en vue de la sauvegarde BorgBackup)
$SYNC
}
######### FONCTION ######################################################
#
# Sauvegarde une liste de répertoire vers une destination avec BorgBackup
# Param IN $1 = Serveur à sauvegarder
# $2 = dépot BorgBackup à utiliser
# $3 = Répertoires à sauvegarder
#
# Ex. appel : sauvegardeBorgBackup $SERVER "$depotBorgBackup" "$repertoiresAsauvegarder"
#
# Note la politique de rétention de données est : --keep-within=15d --keep-weekly=4 --keep-monthly=12 --keep-yearly=5
# - 5 ans,
# - 12 mois,
# - 4 semaines,
# - 15 jours consécutifs,
function sauvegardeBorgBackupServeur () # sauvegarde serveur distant avec sshFS
{
local server=$1
local borgBackupRepo=$2
local dirsToBackup=$3
local borgMntPoint="/root/Prod/mnt/BorgBackup/$server" # Point de montage du système de fichiers du serveur distant (/, racine)
# Chemin complet des outils utilises A GARDER POUR PORTABILITÉ MULTI-PLATEFORME etc ...
local BORG='/usr/bin/borg'
local SYNC='/bin/sync'
# Serveur en ligne ?
serveurJoignable $server
ret=$?
if [ $ret -ne 0 ];then # ... erreur serveur injoignable, on sort avec le code erreur.
return $ret
fi
# Verification du répertoire du point de montage pour sshFS
if [ ! -d $borgMntPoint ];then # Si le repertoire pour le pt de montage de sshFS n'est pas présent ...
$MKDIR -p $borgMntPoint # ... alors nous le créons.
ret=$?
if [ $ret -ne 0 ];then # ... erreur à la création du repertoire (sshFS)
G_ERREUR=$ret
g_log_message "ERROR" "Impossible de creer le repertoire pour sshFS \"$borgMntPoint\" erreur \"$G_ERREUR\""
return $G_ERREUR
fi
fi
# Montage du système de fichier / (root/racine) distant sur $borgMntPoint (répertoire temporaire pour la sauvegarde)
montageSshFS $server $borgMntPoint
ret=$?
if [ $ret -ne 0 ];then # ... erreur pour le montage du systéme de fichiers distant, on sort avec le code erreur.
return $ret
fi
# Verification du dépot BorgBackup $borgBackupRepo
if [ ! -d $borgBackupRepo ];then # Si le dépôt BorgBackup n'est pas présent ...
$BORG init --encryption=none $borgBackupRepo # ... alors nous le créons, sans cryptage (CPU eater...).
ret=$?
if [ $ret -ne 0 ];then # ... erreur à la création du dépôt BorgBackup
G_ERREUR=$ret
g_log_message "ERROR" "Impossible d'initialiser le dépôt BorgBackup \"$borgBackupRepo\" erreur \"$G_ERREUR\""
# ARRET de la sauvegarde (on synchronise les i/O et demonte le système de ficher racine distant)
$SYNC #synchro des IO disques (pour laisser un FS distant propre)
demontage $borgMntPoint
return $G_ERREUR
fi
fi
# On lance la sauvegarde ...
g_log_message "INFO" "Sauvegarde de \"$dirsToBackup\" en cours"
# ... on corrige le bug
export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=yes
$BORG create -v --stats $borgBackupRepo::$server-{now:%d_%m_%Y:%M} $dirsToBackup &>> $G_FICHIER_LOG
# On vérifie que la sauvegarde s'est bien déroulée ...
ret=$?
if [ $ret -eq 2 ];then # ... erreur durant la sauvegarde, on sort en erreur.
G_ERREUR=$ret
g_log_message "ERROR" "Borg backup erreur \"$G_ERREUR\""
# ARRET de la sauvegarde (on synchronise les i/O et demonte le système de ficher racine distant)
$SYNC #synchro des IO disques
demontage $borgMntPoint
return $G_ERREUR
else
#Rétention, 15 jours, 4 semaines, 1 par mois, sur 5 ans ...
$BORG prune --error --keep-within=15d --keep-weekly=4 --keep-monthly=12 --keep-yearly=5 $borgBackupRepo &>> $G_FICHIER_LOG
# On vérifie que la rétention a bien fonctionné ... (nettoyage des anciennes sauvegardes)
ret=$?
if [ $ret -eq 2 ];then # ... erreur durant la rétention, on sort en erreur.
G_ERREUR=$ret
g_log_message "ERROR" "Borg prune erreur \"$G_ERREUR\""
# ARRET de la sauvegarde (on synchronise les i/O et demonte le système de ficher racine distant)
$SYNC #synchro des IO disques
demontage $borgMntPoint
return $G_ERREUR
fi
fi
# Fin de la sauvegarde (on synchronise les i/O et demonte le système de ficher racine distant)
$SYNC #synchro des IO disques
demontage $borgMntPoint
}
function sauvegardeBorgBackup () # Sauvegarde locale
{
local server=$1
local borgBackupRepo=$2
local dirsToBackup=$3
# Chemin complet des outils utilises A GARDER POUR PORTABILITÉ MULTI-PLATEFORME etc ...
local BORG='/usr/bin/borg'
local SYNC='/bin/sync'
# Verification du dépot BorgBackup $borgBackupRepo
if [ ! -d $borgBackupRepo ];then # Si le dépôt BorgBackup n'est pas présent ...
$BORG init --encryption=none $borgBackupRepo # ... alors nous le créons, sans cryptage.
ret=$?
if [ $ret -ne 0 ];then # ... erreur à la création du dépôt BorgBackup
G_ERREUR=$ret
g_log_message "ERROR" "Impossible d'initialiser le dépôt BorgBackup \"$borgBackupRepo\" erreur \"$G_ERREUR\""
# ARRET de la sauvegarde
$SYNC #synchro des IO disques
return $G_ERREUR
fi
fi
# On lance la sauvegarde ...
g_log_message "INFO" "Sauvegarde de \"$dirsToBackup\" en cours"
# ... on corrige le bug
export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=yes
$BORG create -v --stats $borgBackupRepo::$server-{now:%d_%m_%Y:%M} $dirsToBackup &>> $G_FICHIER_LOG
# On vérifie que la sauvegarde s'est bien déroulée ...
ret=$?
if [ $ret -eq 2 ];then # ... erreur durant la sauvegarde, on sort en erreur.
G_ERREUR=$ret
g_log_message "ERROR" "Borg backup erreur \"$G_ERREUR\""
# ARRET de la sauvegarde
$SYNC #synchro des IO disques
return $G_ERREUR
else
#Rétention, 10 jours, 4 semaines, 1 par mois, sur 5 ans ...
$BORG prune --error --keep-within=15d --keep-weekly=4 --keep-monthly=12 --keep-yearly=5 $borgBackupRepo &>> $G_FICHIER_LOG
# On vérifie que la rétention a bien fonctionné ... (nettoyage des anciennes sauvegardes)
ret=$?
if [ $ret -eq 2 ];then # ... erreur durant la rétention, on sort en erreur.
G_ERREUR=$ret
g_log_message "ERROR" "Borg prune erreur \"$G_ERREUR\""
# ARRET de la sauvegarde (on synchronise les i/O et demonte le système de ficher racine distant)
$SYNC #synchro des IO disques
demontage $borgMntPoint
return $G_ERREUR
fi
fi
# Fin de la sauvegarde (on synchronise les i/O et demonte le système de ficher racine distant)
$SYNC #synchro des IO disques
}
Ordonnancement de l'automatisation de l'exploitation d'iLinux v1
/var/spool/cron/crontabs/root
crontab -l
MAILTO=""
###############################"##
# Sauvegarde serveurs Prod (LAN20)
#
20 0 * * * /root/Prod/Scripts/Sauvegardes/sauvegarde_srv_std.sh nsmaster > /dev/null
30 0 * * * /root/Prod/Scripts/Sauvegardes/sauvegarde_srv_std.sh ns > /dev/null
40 0 * * * /root/Prod/Scripts/Sauvegardes/sauvegarde_srv_std.sh nsbackup > /dev/null
20 1 * * * /root/Prod/Scripts/Sauvegardes/sauvegarde_srv_fd.sh ldap1 > /dev/null
# Grosse volumetrie (courriels, nuages, sites ...)
00 2 * * * /root/Prod/Scripts/Sauvegardes/sauvegarde_srv_std.sh mx1 > /dev/null
30 2 * * * /root/Prod/Scripts/Sauvegardes/sauvegarde_srv_web-db.sh web1 > /dev/null
00 3 * * * /root/Prod/Scripts/Sauvegardes/sauvegarde_srv_web-db.sh web2 > /dev/null
30 3 * * * /root/Prod/Scripts/Sauvegardes/sauvegarde_srv_web-db.sh web3 > /dev/null
##################################
# Sauvegarde serveurs Prod (DMZ10)
#
50 0 * * * /root/Prod/Scripts/Sauvegardes/sauvegarde_srv_std.sh ns1 > /dev/null
00 1 * * * /root/Prod/Scripts/Sauvegardes/sauvegarde_srv_std.sh ns2 > /dev/null
10 1 * * * /root/Prod/Scripts/Sauvegardes/sauvegarde_srv_std.sh rpx1 > /dev/null
30 1 * * * /root/Prod/Scripts/Sauvegardes/sauvegarde_srv_std.sh rpx2 > /dev/null
00 5 * * * /root/Prod/Scripts/Sauvegardes/sauvegarde_srv_web-db.sh web666 > /dev/null
00 6 * * * /root/Prod/Scripts/Sauvegardes/sauvegarde_srv_std.sh proxy1 > /dev/null
00 4 * * * /root/Prod/Scripts/Sauvegardes/sauvegarde_srv_std.sh rmx1 > /dev/null
20 4 * * * /root/Prod/Scripts/Sauvegardes/sauvegarde_srv_std.sh rmx2 > /dev/null
#################################
# Sauvegarde serveurs Prod (ADMIN)
#
10 0 * * * /root/Prod/Scripts/Sauvegardes/sauvegarde_srv_std.sh bastion > /dev/null
00 0 * * * /root/Prod/Scripts/Sauvegardes/sauvegarde_local_std.sh orion > /dev/null
Courriel généré par l'exploitation quotidienne iLinux v1
Serveur Web (DMZ)
>>>> sav_srv_ilinux.sh sur serveur : "websrv", executé le lundi 14 oct. 05:00:01
lundi 14 oct. 05:00:01 websrv sav_srv_ilinux.sh[2838]: [INFO] DEBUT-SCRIPT
lundi 14 oct. 05:00:01 websrv sav_srv_ilinux.sh[2838]: [INFO] Parametres : "websrv"
lundi 14 oct. 05:00:01 websrv sav_srv_ilinux.sh[2838]: [INFO] Serveur "websrv" en ligne
lundi 14 oct. 05:00:01 websrv sav_srv_ilinux.sh[2838]: [INFO] Serveur "websrv" : "stop" "nginx"
lundi 14 oct. 05:00:02 websrv sav_srv_ilinux.sh[2838]: [INFO] Export des bases "mysql" sous "/root/Prod/Sauvegardes/Bases"
lundi 14 oct. 05:00:02 websrv sav_srv_ilinux.sh[2838]: [INFO] Compression du fichier "/root/Prod/Sauvegardes/Bases/websrv-mysql---all-databases.sql" sous "/root/Prod/Sauvegardes/Bases"
lundi 14 oct. 05:00:03 websrv sav_srv_ilinux.sh[2838]: [INFO] Export des bases "postgresql" sous "/root/Prod/Sauvegardes/Bases"
lundi 14 oct. 05:00:04 websrv sav_srv_ilinux.sh[2838]: [INFO] Compression du fichier "/root/Prod/Sauvegardes/Bases/websrv-postgresql---full.sql" sous "/root/Prod/Sauvegardes/Bases"
lundi 14 oct. 05:00:04 websrv sav_srv_ilinux.sh[2838]: [INFO] Serveur "websrv" en ligne
lundi 14 oct. 05:00:04 websrv sav_srv_ilinux.sh[2838]: [INFO] Montage "/root/Prod/mnt/BorgBackup/websrv" de "websrv"
lundi 14 oct. 05:00:04 websrv sav_srv_ilinux.sh[2838]: [INFO] Sauvegarde de "/root/Prod/mnt/BorgBackup/websrv/etc /root/Prod/mnt/BorgBackup/websrv/root /root/Prod/mnt/BorgBackup/websrv/home /root/Prod/mnt/BorgBackup/websrv/var" en cours
------------------------------------------------------------------------------
Archive name: websrv-14_10_2019:00
Archive fingerprint: dae2ce16ahdfh4df9hd4h94dh4h9dd14fc6fcd6fe6ff8573378a55022f5dfd1
Time (start): Mon, 2019-10-14 05:00:05
Time (end): Mon, 2019-10-14 05:01:18
Duration: 1 minutes 13.38 seconds
Number of files: 51726
------------------------------------------------------------------------------
Original size Compressed size Deduplicated size
This archive: 1.21 GB 1.21 GB 30.24 MB
All archives: 36.33 GB 36.33 GB 2.45 GB
Unique chunks Total chunks
Chunk index: 42252 1554816
------------------------------------------------------------------------------
lundi 14 oct. 05:01:22 websrv sav_srv_ilinux.sh[2838]: [INFO] Démontage de "/root/Prod/mnt/BorgBackup/websrv"
lundi 14 oct. 05:01:22 websrv sav_srv_ilinux.sh[2838]: [INFO] Serveur "websrv" en ligne
lundi 14 oct. 05:01:22 websrv sav_srv_ilinux.sh[2838]: [INFO] Serveur "websrv" : "start" "nginx"
>>>> Statistiques du système de fichiers distant de "websrv" ...
Sys. de fichiers Taille Utilisé Dispo Uti% Monté sur
/dev/mapper/Raid1Data-vm--107--disk--0 270G 2,8G 253G 2% /
none 504k 0 504k 0% /dev
udev 8,4G 0 8,4G 0% /dev/tty
tmpfs 8,4G 4,1k 8,4G 1% /dev/shm
tmpfs 8,4G 18M 8,4G 1% /run
tmpfs 5,3M 0 5,3M 0% /run/lock
tmpfs 8,4G 0 8,4G 0% /sys/fs/cgroup
tmpfs 1,7G 0 1,7G 0% /run/user/1000
tmpfs 1,7G 0 1,7G 0% /run/user/0
>>>> Statistiques du système de sauvegarde ...
websrv-31_07_2019:00 Wed, 2019-07-31 05:00:02
websrv-31_08_2019:00 Sat, 2019-08-31 05:00:02
websrv-08_09_2019:00 Sun, 2019-09-08 05:00:03
websrv-15_09_2019:00 Sun, 2019-09-15 05:00:03
websrv-22_09_2019:00 Sun, 2019-09-22 05:00:03
websrv-29_09_2019:00 Sun, 2019-09-29 05:00:03
websrv-30_09_2019:00 Mon, 2019-09-30 05:00:02
websrv-01_10_2019:00 Tue, 2019-10-01 05:00:02
websrv-02_10_2019:00 Wed, 2019-10-02 05:00:02
websrv-03_10_2019:00 Thu, 2019-10-03 05:00:03
websrv-04_10_2019:00 Fri, 2019-10-04 05:00:02
websrv-05_10_2019:00 Sat, 2019-10-05 05:00:02
websrv-06_10_2019:00 Sun, 2019-10-06 05:00:03
websrv-06_10_2019:45 Sun, 2019-10-06 16:45:04
websrv-06_10_2019:50 Sun, 2019-10-06 16:50:36
websrv-06_10_2019:52 Sun, 2019-10-06 16:52:29
websrv-06_10_2019:56 Sun, 2019-10-06 16:56:27
websrv-06_10_2019:12 Sun, 2019-10-06 17:12:17
websrv-06_10_2019:15 Sun, 2019-10-06 17:15:59
websrv-06_10_2019:18 Sun, 2019-10-06 17:18:03
websrv-06_10_2019:22 Sun, 2019-10-06 20:22:09
websrv-06_10_2019:16 Sun, 2019-10-06 21:16:29
websrv-07_10_2019:00 Mon, 2019-10-07 05:00:08
websrv-08_10_2019:00 Tue, 2019-10-08 05:00:05
websrv-09_10_2019:00 Wed, 2019-10-09 05:00:05
websrv-10_10_2019:00 Thu, 2019-10-10 05:00:05
websrv-11_10_2019:00 Fri, 2019-10-11 05:00:05
websrv-12_10_2019:00 Sat, 2019-10-12 05:00:05
websrv-13_10_2019:00 Sun, 2019-10-13 05:00:05
websrv-14_10_2019:00 Mon, 2019-10-14 05:00:05
lundi 14 oct. 05:01:23 websrv sav_srv_ilinux.sh[2838]: [INFO] FIN-SCRIPT
lundi 14 oct. 05:01:23 websrv sav_srv_ilinux.sh[2838]: [INFO] Courriel de notification
Script de synchronisation Rsync serveur local / distant
./rsync_srv_STD.sh
#!/bin/bash
###############################################################################
# #
# PGM : Script de synchronisation rsync serveur local / distant #
# #
# AUTEUR : Stephane (iLinux) #
# VERSION : 1.0.0 #
# #
# DATE : 24/10/2019 #
# #
# PARAM. : N/A #
# OUT > logger + mail #
# #
###############################################################################
# EN PREMIER LIEU
# On inclus les fonctions et variables communes:
. /root/Prod/Scripts/sauvegarde/outils/fonctions_variables.sh
# Variables de travail ...
# ... LOCALES
# ... DISTANTES
# N/A
# Au commencement il n'y a jamais d'erreur ... dans un script
G_ERREUR=0
# Serveur à sauvegarder :
SERVEUR=$1
# Surcharge var. fichier log (en attendant serveur mail !)
#G_FICHIER_LOG="/root/Prod/Journaux/Sauvegardes/$SERVEUR.log"
# Script actuellement en cours d'execution
echo "SCRIPT : $G_APPLI"
echo "" >> $G_FICHIER_LOG
echo ">>>> $G_APPLI sur serveur : \"$SERVEUR\", executé le $G_JOUR $G_DATE">> $G_FICHIER_LOG
echo "" >> $G_FICHIER_LOG
# 1 seul paramétre attendu
#if [ $# = 1 ] || [ -z "$1"]
#then
# G_ERREUR='Donnez 1 nom de serveur svp ...'
# # On sort du script avec $G_ERREUR
# g_log_message "ERROR" $G_MSG_FIN_SCRIPT
# exit $G_ERREUR
#fi
# DEBUT DU SCRIPT
g_log_message "INFO" $G_MSG_DEBUT_SCRIPT
g_log_message "INFO" "Parametres : \"$*\""
# Lancement de la synchronisation avec le serveur $SERVEUR...
repertoireSourceDistant="/Sauvegardes/Prod/"
repertoireCibleLocal="/Externalisation/"
synchroServeur $SERVEUR "$repertoireSourceDistant" "$repertoireCibleLocal"
# On audit le système de fichier local (volumétrie etc)
statutSF
# On sort du script avec $G_ERREUR
g_log_message "INFO" $G_MSG_FIN_SCRIPT
exit $G_ERREUR
# FIN DU SCRIPT