Säkerhetskopiering med DAR

Klienten

På klienten installeras DAR på samma sätt som på servern. Det som skiljer är lite annorlunda script och anrop av dessa. Eftersom jag skrev scripten för backup från klient till server före de för lokal backup, så ser inte anropet helt obekant ut:

/home/backup/_scripts/dar_full_backup.sh "-R /home" backup@192.168.1.65 backupserver home

Det enda som skiljer är att den parameter som inte användes i scripten för lokal backup nu är satt till en SSH-användare ('backup') på den server som ska få allt data '192.168.1.65' (namn eller IP).

Om du inte skapat ett ställe att lägga lokala backupfiler på (index och pekare till senaste backup), så är det enklast att du lägger i /home/backup/_scripts, som hela guiden utgår ifrån:

mkdir -p /home/backup/_scripts

Lösenordsfri inloggning med hjälp av SSH-nycklar

För att backupen ska gå att göra automatiskt, så behöver det skapas en SSH-nyckel på klientdatorn som sen läggs in i 'authorized_hosts' filen i backup-användarens hemkatalog på servern. Allt detta går att göra från klienten.

Inloggad på klienten skriver du:

ssh-keygen -q -t rsa -f  $HOME/.ssh/id_rsa -C client_1

Tryck bara enter (två gånger) när det frågas efter lösenord.
Kopiera sen den publika nyckeln till backup-servern. Du måste veta backup-användarens lösenord för att kunna göra det, har du glömt bort det så kan du ändra det genom att på servern (inloggad som 'root') skriva

passwd backup

Ändra till ett lösenord som du kommer ihåg i minst fem minuter :)

För att kopiera den publika nyckeln till servern (och i fortsättningen kunna logga in på backup-kontot utan lösenord) kör du kommandot:

ssh backup@192.168.1.65 < $HOME/.ssh/id_rsa.pub 'mkdir -p .ssh; cat >>.ssh/authorized_keys'

Du blir frågad efter lösenordet för backup-användaren, men det här är den enda gången du kommer att bli det från den här klientdatorn om allt går bra.

Testa att det går att logga in på backup-servern utan lösenord:

ssh backup@192.168.1.65

Om det funkar blir du inloggad på backup-servern utan att bli frågad efter lösenordet, du får upp en '$'-prompt, och din hemkatalog är satt till '/home/backup' (kolla med pwd). Om det inte fungerade, gör om och gör rätt (jag har mao aldrig råkat ut för att det inte fungerar).

Backup script för remote backup

Då scripten och dess anrop till stor del liknar de för lokal backup, så går jag inte igenom vad scripten gör här. Vill du veta det, kan du läsa det på Sida 3 - Servern. Precis som för scripten för lokal backup sätts en sökväg för stället där lokala filer som hör till backupen ska hamna. Det som lagras på klienten har samma struktur som på servern, förutom att det inte lagras hela backuper på klientdatorn, utan bara filer som innehåller ett index över innehållet i den riktiga backupfilen som hamnar i 'backup'-användarens hemkatalog på servern.

I början på alla script finns sökvägen för vart backupfilerna ska läggas:
LOCAL_DIR="/home/backup"

dar_full_backup.sh

Tar en full backup på de filer som ges som parameter till scriptet. För att ta en full backup av den klientens (webserver) /home

/home/backup/_scripts/dar_full_backup.sh "-R /home" backup@192.168.1.65 webserver home

Parametrarna talar om för scriptet att 'root' för backupen ska sättas till /home (-R /home), och att filerna ska lagras i månadskatalogen i webserver i hemkatalogen för användaren 'backup' på backupservern (många i blev det). Om hemkatalogen för användaren 'backup' på backupservern är satt till /home/backup, så kommer den fullständiga sökvägen på backupservern för denna backup vara /home/backup/webserver/2007-05.

Filernas namn kommer att börja på 'home'. På klienten backup-scriptet körs från kommer det i månadskatalogen i /home/backup sparas en indexfil för varje backup som gjorts den månaden. I /home/backup sparas en fil som innehåller namnen på de senaste backuperna som gjorts.

För en liknande backup på hela systemet utom /home används kommandot:

/home/backup/_scripts/dar_full_backup.sh "-R / -P home" x backupserver system

För att hindra att det tas backup på en viss sökväg så används parametern -P dirname, i det här fallet -P home.

#!/bin/sh
# full_backup.sh <darextra> <remotelogin> <remotedir> <basename>
# darextra = relative path from / to backup, directories to ignore...
if [ $# -ne 4 ]; then
  echo 1>&2 "Usage: $0 <darextra> <remotelogin> <remotedir> <basename>"
  exit 127
fi

# some configuration
DATE_Y_M=`date +%Y-%m`

# directory for remote storage ($3 = remotedir, append year and month)
BACKUP_DIR="$3/${DATE_Y_M}"

# directory for local storage (catalogs and pointers to last backup)
LOCAL_DIR="/home/backup"

REMOTE_LOGIN=$2
DARCMD="/usr/local/bin/dar -z7 -c - $1"
DATE=`date +%Y%m%d_%H%M`
FILE="${4}_${DATE}_full"
REMOTE_CMD="mkdir -p ${BACKUP_DIR}; cd ${BACKUP_DIR}; cat >${FILE}.1.dar"
#echo $DARCMD
#echo $REMOTE_CMD

# -- step 1 create backup
CMD1="$DARCMD | ssh $REMOTE_LOGIN '$REMOTE_CMD'"
#echo $CMD1
sh -c "$CMD1"

# -- step 2 create catalog and send back to client
mkdir -p ${LOCAL_DIR}/${DATE_Y_M}
REMOTE_CMD="cd ${BACKUP_DIR}; dar -w -A $FILE -C ${FILE}_CAT -z7"
CMD2="ssh >/dev/null -2 $REMOTE_LOGIN '$REMOTE_CMD'; scp -q $REMOTE_LOGIN:~/${BACKUP_DIR}/${FILE}_CAT.1.dar ${LOCAL_DIR}/${DATE_Y_M}"
#echo $CMD2
sh -c "$CMD2"

# -- step 3 store name of last full backup
cd ${LOCAL_DIR}
if [ -f ${DATE_Y_M}/${FILE}_CAT.1.dar ]; then
  echo >${4}_latest_full ${DATE_Y_M}/${FILE}

  # -- step 4 remove pointers to last incremental and diff backups
  rm ${4}_latest_incr
  rm ${4}_latest_diff
fi

dar_incr_backup.sh

Används på samma sätt som dar_full_backup.sh, men tar endast backup på filer som ändrats sen den senaste fullständiga backup gjordes.

#!/bin/sh
# dar_diff_backup.sh <darextra> <remotelogin> <remotedir> <basename>
# darextra = relative path from / to backup, directories to ignore...
#
# differential backup against last differential, incremental or full backup
#
if [ $# -ne 4 ]; then
  echo 1>&2 "Usage: $0 <darextra> <remotelogin> <remotedir> <basename>"
  exit 127
fi

# some configuration
DATE_Y_M=`date +%Y-%m`

# directory for remote storage ($3 = remotedir, append year and month)
BACKUP_DIR="$3/${DATE_Y_M}"

# directory for local storage (catalogs and pointers to last backup)
LOCAL_DIR="/home/backup"

cd ${LOCAL_DIR}
# get name of last full backup..
if [ -f ${4}_latest_full ]; then
  PREV_BACKUP=`cat ${4}_latest_full`
fi

# check that the backup file exists
if [ -f ${PREV_BACKUP}_CAT.1.dar ]; then
  echo $PREV_BACKUP
else
  echo "Can't do an incremental backup if no previous full backup have been made"
  exit 127
fi

REMOTE_LOGIN=$2
DARCMD="/usr/local/bin/dar -A ${LOCAL_DIR}/${PREV_BACKUP}_CAT -z7 -c - $1"
DATE=`date +%Y%m%d_%H%M`
FILE="${4}_${DATE}_incr"
REMOTE_CMD="mkdir -p ${BACKUP_DIR}; cd ${BACKUP_DIR}; cat >${FILE}.1.dar"
#echo $DARCMD
#echo $REMOTE_CMD

# -- step 1 create backup
CMD1="$DARCMD | ssh $REMOTE_LOGIN '$REMOTE_CMD'"
#echo $CMD1
sh -c "$CMD1"

# -- step 2 create catalog and send back to client
mkdir -p ${LOCAL_DIR}/${DATE_Y_M}
REMOTE_CMD="cd ${BACKUP_DIR}; dar -w -A $FILE -C ${FILE}_CAT -z7"
CMD2="ssh -2 $REMOTE_LOGIN '$REMOTE_CMD'; scp -q ${REMOTE_LOGIN}:~/${BACKUP_DIR}/${FILE}_CAT.1.dar ${LOCAL_DIR}/${DATE_Y_M}"
#echo $CMD2
sh -c "$CMD2"

# -- step 3 store name of last incr backup
cd ${LOCAL_DIR}
if [ -f ${DATE_Y_M}/${FILE}_CAT.1.dar ]; then
  echo >${4}_latest_incr ${DATE_Y_M}/${FILE}

  # -- step 4 remove pointers to last diff backup
  rm ${4}_latest_diff
fi

dar_diff_backup.sh

Används på samma sätt som dar_full_backup.sh, men tar endast backup på filer som ändrats sen den senaste backupen togs (fullständig, inkrementell eller differentiell).

#!/bin/sh
# dar_diff_backup.sh <darextra> <remotelogin> <remotedir> <basename>
# darextra = relative path from / to backup, directories to ignore...
#
# differential backup against last differential, incremental or full backup
#
if [ $# -ne 4 ]; then
  echo 1>&2 "Usage: $0 <darextra> <remotelogin> <remotedir> <basename>"
  exit 127
fi

# some configuration
DATE_Y_M=`date +%Y-%m`

# directory for remote storage ($3 = remotedir, append year and month)
BACKUP_DIR="$3/${DATE_Y_M}"

# directory for local storage (catalogs and pointers to last backup)
LOCAL_DIR="/home/backup"

cd ${LOCAL_DIR}
# get name of last full backup..
if [ -f ${4}_latest_full ]; then
  PREV_BACKUP=`cat ${4}_latest_full`
fi

# if a incremental has been made, use it in place of full backup
if [ -f ${4}_latest_incr ]; then
  PREV_BACKUP=`cat ${4}_latest_incr`
fi

# and use last diff in place of incremental if a diff has been made since last incremental
if [ -f ${4}_latest_diff ]; then
  PREV_BACKUP=`cat ${4}_latest_diff`
fi

# check that the backup file exists
if [ -f ${PREV_BACKUP}_CAT.1.dar ]; then
  echo $PREV_BACKUP
else
  echo "Can't do a diff backup if no previous backup have been made"
  exit 127
fi

REMOTE_LOGIN=$2
DARCMD="/usr/local/bin/dar -A ${LOCAL_DIR}/${PREV_BACKUP}_CAT -z7 -c - $1"
DATE=`date +%Y%m%d_%H%M`
FILE="${4}_${DATE}_diff"
REMOTE_CMD="mkdir -p ${BACKUP_DIR}; cd ${BACKUP_DIR}; cat >${FILE}.1.dar"
#echo $DARCMD
#echo $REMOTE_CMD

# -- step 1 create backup
CMD1="$DARCMD | ssh $REMOTE_LOGIN '$REMOTE_CMD'"
#echo $CMD1
sh -c "$CMD1"

# -- step 2 create catalog and send back to client
mkdir -p ${LOCAL_DIR}/${DATE_Y_M}
REMOTE_CMD="cd ${BACKUP_DIR}; dar -w -A $FILE -C ${FILE}_CAT -z7"
CMD2="ssh -2 $REMOTE_LOGIN '$REMOTE_CMD'; scp -q ${REMOTE_LOGIN}:~/${BACKUP_DIR}/${FILE}_CAT.1.dar ${LOCAL_DIR}/${DATE_Y_M}"
#echo $CMD2
sh -c "$CMD2"

# -- step 3 store name of last diff backup
cd ${LOCAL_DIR}
if [ -f ${DATE_Y_M}/${FILE}_CAT.1.dar ]; then
  echo >${4}_latest_diff ${DATE_Y_M}/${FILE}
fi

Provkörning och fler script

Samma tester som för backup servern utförs

Provkör dar_full

/home/backup/_scripts/dar_full_backup.sh "-R /etc" backup@192.168.1.65 webserver etc

Du bör få ett resultat liknande:

Reading config file: /etc/darrc


 --------------------------------------------
 281 inode(s) saved
 with 0 hard link(s) recorded
 0 inode(s) not saved (no file change)
 0 inode(s) failed to save (filesystem error)
 0 files(s) ignored (excluded by filters)
 0 files(s) recorded as deleted from reference backup
 --------------------------------------------
 --------------------------------------------
 Total number of file considered: 281
No terminal found for user interaction. All questions will be assumed a negative answer (less destructive choice),
which most of the time will abort the program.
Reading config file: /etc/darrc
rm: etc_latest_incr: No such file or directory
rm: etc_latest_diff: No such file or directory

Om allt gick bra bör du nu ha två nya filer i /home/backup

2007-05/etc_20070529_2224_full_CAT.1.dar
etc_latest_full

På backupservern ska det också finnas 2 filer i /home/backup/webserver

2007-05/etc_20070529_2224_full.1.dar
2007-05/etc_20070529_2224_full_CAT.1.dar

Provkör dar_diff minst en minut senare

Ändra gärna (eller lägg till) nån fil på platsen du tar backup på, för att vara säker på att något har hänt sen sist.

/home/backup/_scripts/dar_diff_backup.sh "-R /etc" backup@192.168.1.65 webserver etc

Du bör få ett resultat liknande:

2007-05/etc_20070529_2224_full
Reading config file: /etc/darrc


 --------------------------------------------
 1 inode(s) saved
 with 0 hard link(s) recorded
 281 inode(s) not saved (no file change)
 0 inode(s) failed to save (filesystem error)
 0 files(s) ignored (excluded by filters)
 0 files(s) recorded as deleted from reference backup
 --------------------------------------------
 --------------------------------------------
 Total number of file considered: 282
No terminal found for user interaction. All questions will be assumed a negative answer (less destructive
choice), which most of the time 
will abort the program.
Reading config file: /etc/darrc

1 inode(s) saved betyder att det fanns en fil som ändrats sen den senaste backupen togs. I mitt fall med webservern så är det jag som skapat filen /etc/ny_fil för att ha nåt att ta en diff på.

Du kan (som för lokal backup) lista de filer som sparats i backupen. På klienten använder du backupens index-fil:

# dar -as -l /home/backup/2007-05/etc_20070529_2237_diff_CAT
Reading config file: /etc/darrc
[data ][ EA  ][compr] | permission | user  | group | size  |          date                 |    filename
----------------------+------------+-------+-------+-------+-------------------------------+------------
[InRef]       [-----]   -rw-r--r--   root       wheel   0       Tue May 29 22:37:48 2007        ny_fil

[InRef] betyder att filen finns sparad i den riktiga backupfilen (som finns på backupservern).

På backupservern finns nu ytterligare två filer i /home/backup/webserver/2007-05 och du kan lista innehållet på samma sätt:

# dar -as -l /home/backup/webserver/2007-05/etc_20070529_2237_diff
Reading config file: /etc/darrc
[data ][ EA  ][compr] | permission | user  | group | size  |          date                 |    filename
----------------------+------------+-------+-------+-------+-------------------------------+------------
[Saved]       [     ]   -rw-r--r--   root       wheel   0       Tue May 29 22:37:48 2007        ny_fil

Där listas filen som [Saved], dvs den finns i den listade backupfilen.

I övrigt fungerar remote-backuparna precis som de lokala. Gör du en inkrementiell (incr) backup, så sparas filerna som ändrats sen den senaste fullständiga backupen (vilket underlättar för återställning av förlorade filer).

Fler script gör backupen enklare

Oftast vill man ta backup på mer än en katalog, gärna automatiskt, och då kommer några enklare script till användning. Eftersom man med säkerhet inte vet hur länge backupen av en katalog kommer att ta, så är det säkrast att köra dessa i följd, och det med hjälp av ett mycket enkelt shell-script.
Principen är bara att bunta ihop körningen av ovanstående script, så att dessa går att köra i följd med bara ett enkelt kommando.

Scripten för remote backup är i stort sett samma som för lokal (liknande exempel).
Exemplen antar att vi vill ta separata backuper på /home, /etc och /var, samt ta en backup på resten av systemet.

Börjar igen från fel håll, med diff-backupen (det enklaste scriptet som kräver att man kört en inkrementell eller full backup tidigare):

all_diff.sh

#!/bin/sh
/home/backup/_scripts/dar_diff_backup.sh "-R /etc" backup@192.168.1.65 webserver etc
/home/backup/_scripts/dar_diff_backup.sh "-R /usr" backup@192.168.1.65 webserver usr
/home/backup/_scripts/dar_diff_backup.sh "-R /home" backup@192.168.1.65 webserver home
/home/backup/_scripts/dar_diff_backup.sh "-R -P home -P usr -P etc" backup@192.168.1.65 webserver system

all_incr.sh

#!/bin/sh
/home/backup/_scripts/dar_diff_backup.sh "-R /etc" backup@192.168.1.65 webserver etc
/home/backup/_scripts/dar_incr_backup.sh "-R /etc" backup@192.168.1.65 webserver etc
/home/backup/_scripts/dar_diff_backup.sh "-R /usr" backup@192.168.1.65 webserver usr
/home/backup/_scripts/dar_incr_backup.sh "-R /usr" backup@192.168.1.65 webserver usr
/home/backup/_scripts/dar_diff_backup.sh "-R /home" backup@192.168.1.65 webserver home
/home/backup/_scripts/dar_incr_backup.sh "-R /home" backup@192.168.1.65 webserver home
/home/backup/_scripts/dar_diff_backup.sh "-R / -P home -P usr -P etc" backup@192.168.1.65 webserver system
/home/backup/_scripts/dar_incr_backup.sh "-R / -P home -P usr -P etc" backup@192.168.1.65 webserver system

all_full.sh

#!/bin/sh
/home/backup/_scripts/dar_diff_backup.sh "-R /etc" backup@192.168.1.65 webserver etc
/home/backup/_scripts/dar_full_backup.sh "-R /etc" backup@192.168.1.65 webserver etc
/home/backup/_scripts/dar_diff_backup.sh "-R /usr" backup@192.168.1.65 webserver usr
/home/backup/_scripts/dar_full_backup.sh "-R /usr" backup@192.168.1.65 webserver usr
/home/backup/_scripts/dar_diff_backup.sh "-R /home" backup@192.168.1.65 webserver home
/home/backup/_scripts/dar_full_backup.sh "-R /home" backup@192.168.1.65 webserver home
/home/backup/_scripts/dar_diff_backup.sh "-R / -P home -P usr -P etc" backup@192.168.1.65 webserver system
/home/backup/_scripts/dar_full_backup.sh "-R / -P home -P usr -P etc" backup@192.168.1.65 webserver system

Att göra en 'diff' före en 'incr' eller 'full' är mest praktiskt på större mängder data, men används här på allt bara för att visa hur det fungerar. Är det lite data i backupen är det lika enkelt att återställa från den 'incr' eller 'full' backupen.

Arkiv med klientscript

Du kan ladda ner ett arkiv med alla script för klienten här:
http://www.bsd-guide.net/dar-backup/files/dar_scripts/dar_client_scripts.tgz
Och som vanligt får du lite klipp-och-klistra-fusk.. :)
mkdir -p /home/backup/_scripts
cd /home/backup/_scripts
wget http://www.bsd-guide.net/dar-backup/files/dar_scripts/dar_client_scripts.tgz
tar xfz dar_client_scripts.tgz
chmod 700 *sh
rm dar_client_scripts.tgz

Inte riktigt klar med guiden än

2007-05-29 23:00
I natt (och kanske inte heller på ett tag) får ni inte veta hur man återställer data som råkats raderas eller klantats sönder på annat sätt..
Det finns beskrivet rätt så bra i DAR's dokumentation, men en liten början är:

dar -x [backupfil] -R [destination]
Labbsugna får givetvis prova de fyra första sidorna..