Script Shell de backup de dossier via FTP

J'ai optimisé le précédent script de backup de dossier en y ajoutant une sauvegarde via FTP.

J'ai mis du temps à mettre en place cette technique car cela ne me convenait pas pour la simple et bonne raison que le transfert de l'archive générée peut-être longue (et lourde), surtout si on sauvegarde une quantité conséquente de fichiers !

Mais après en avoir parlé à Pierre, il s'est avéré que le temps de transfert, même pour de gros fichier, se faisait de manière très rapide, surtout entre serveurs.

Donc à défaut d'avoir les moyens de se payer deux serveurs et de les mettres en mirroring (ca ne saurait tarder) (les deux serveurs .... pas l'argent ...), je suis bien obligé d'utiliser une sauvegarde via FTP.

Voici donc le fameux script que j'utilise :

#!/bin/bash
#
# Shell script (BASH) used in cron to made a backup of the indicated directory

# In order to run this script, you must have following tools installed:
# - gpg
# - ncftp

# And we will use theses :
# - tar
# - rm
# - chown
# - chmod
#
#
# Installation
# Customize the script according to your need. You need to setup :
# - A list of folders, separated by space, and finished with the last /
# - A GPG passphrase
# - The file where to log the messages                         (default /var/log/backup.log)
# - The number of days the backups are stored         (default 5)
# - The FTP credentials
# - The Folders in that FTP
# - The Email to send reports when error occurs
#
# --------------------------------------------------------------------
# This is a free shell script under GNU GPL version 3.0 or above
# Copyright (C) 2005 ReFlectiv project.
# Feedback/comment/suggestions : http://www.reflectiv.net/
# -------------------------------------------------------------------------

# List of folders to save
LIST_F0LDERS="/etc/ /home/ /var/lib/mysql/";

# The password for the archive
GPG_PASS="my_passwd";

# File name where to log the messages
LOG_FILE="/var/log/backup.log";

# Number of days the archives are keeped
KEEPING_DAYS=5;

# FTP Credentials
FTP_SERVER="ftp.server.tld"
FTP_USER="user"
FTP_PASS="password"

# Backup directory on the FTP :
FTP_DIR="/backups/files"

# Email to send when error occurs
USER_EMAIL="email"

# Only change if your UNIX stores bin in diffrent location
GPG="/usr/bin/gpg";
NCFTP="/usr/bin/ncftp"

#######################################################################
# Do not change anything below
#######################################################################

# We mades some vars
UNIX_DATE=`date +"%Y_%m_%d"`;
CURRENT_DATE=`date +"%d/%m/%Y - %H:%M:%S"`;
TBZ_FILE="/tmp/"$UNIX_DATE".tbz";
GPG_FILE=$TBZ_FILE".gpg";

# Adding new clear entry to the log file
echo "" >> $LOG_FILE."tmp";
echo "----------------------------------------------------------------------------------------------------" >> $LOG_FILE."tmp";
echo "" >> $LOG_FILE."tmp";

# Function called to log info into the file
function log {
    echo "["$CURRENT_DATE"] - "$1 >> $LOG_FILE".tmp";

    if [ ! $2 == "" ]; then
                mail -s "[$(hostname)] - Remote backup error" $USER_EMAIL > $LOG_FILE;
                rm $LOG_FILE".tmp";
        exit 1;
    fi
}

log "Starting remote backup";

# Preliminary tests
[ -x $GPG ] || log "gpg not found" 1;
[ -x $NCFTP ] || log "ncftp not found" 1;

for FOLDER in $LIST_FOLDERS
do
        # We test if the original folder exists
    [ -d $FOLDER ] || log "The folder "$FOLDER" does not exists !" 1;
done

# We make the archive
tar -cjf $TBZ_FILE $LIST_F0LDERS
# If an error occured ...
[ $? -eq 0 ] || log "An error occured with the command tar" 1;

# We encrypt the archive
$GPG --yes -c --passphrase $GPG_PASS --s2k-cipher-algo RIJNDAEL256 $TBZ_FILE;
# If an error occured ...
[ $? -eq 0 ] || log "An error occured with the command gpg" 1;

# We delete the archive
rm $TBZ_FILE;
# If an error occured ...
[ $? -eq 0 ] || log "An error occured with the command rm" 1;

# We modify the rights for the file
chmod 400 $GPG_FILE;
# If an error occured ...
[ $? -eq 0 ] || log "An error occured with the command chmod" 1;

# We modify the owner and group of the file
chown $UID $GPG_FILE;
# If an error occured ...
[ $? -eq 0 ] || log "An error occured with the command chown" 1;


# We build the name of the archive from $KEEPING_DAYS days ago
OLD_ARCHIVE=`date --date $KEEPING_DAYS' days ago' "+%Y_%m_%d"`".tbz.gpg";

log "Starting update to FTP server "$FTP_SERVER;

$NCFTP -u$FTP_USER -p$FTP_PASS $FTP_SERVER > $LOG_FILE;
rm $LOG_FILE".tmp";

exit 0;

Le script effectue une sauvegarde des répertoires dans une archive tar.bz. Il chiffre ensuite cette archive avec gpg en utilisant un algorithme synchrone, puis envoie l'archive au serveur distant. Il prends aussi soin de bien supprimer les éléments qui ne sont plus utilisés afin d'éviter toute tentative de lecture (droits et accès aux fichier tbz et gpg puis suppression de tous les éléments).

Beaucoup de paramètres sont modifiable, comme vous pouvez le voir, et ce afin que vous puissiez l'adapter au mieux.

Le seul problème restant est que je n'ai pas réussi à faire taire ncftp ! Si quelqu'un connait une solution (l'argument -v quiet semble fonctionner pour les anciennes versions et n'y est vraisemblablement plus présent :s), je suis preneur !

Bon backup à vous :)

Filed under  //  Development   Scripts   Unix/Linux   backup   bash   dossier   fichier   file   folder   ftp   script   shell  
Posted by Cyril Nicodème 

Trouver une chaine dans des fichiers

Voici quelques commandes bash qui permettre de trouver une chaine contenue dans les fichiers d'un répertoire (utile par exemple pour trouver quels fichiers ont été infectés par le virus Gumblar :D)

La solution la plus simple est rgrep, mais qui n'est pas installé par défaut.

rgrep 'chaine' /arborescence

Sinon, vous avez la solution avec grep.
Cette méthode n'affiche que le fichier concerné

grep -lir "chaine" /arborescence

Cette méthode affiche le fichier concerné, la ligne ou la chaine à été trouvée, et la chaine trouvée :

grep -oHnr "chaine" /arborescence

Sinon, la méthode indiquée par Arkezis, toujours avec grep :

grep "chaine" **/*

Ou la solution avec find :

find /arborescence -name "*extension_du_fichier" -exec grep -l "chaine" {} \;

Enfin, limiter la recherche à certaines extensions :

for i in `find /arborescence -type d`; do grep "chaine" $i/*.{txt,log}; done 2>/dev/null

Parfois très utile ! :)

Filed under  //  Development   Scripts   Unix/Linux   bash   chaine   fichier   find   folder   recursive   repertoire   rgrep   récursif   shell   string   trouver  
Posted by Cyril Nicodème