Backup med Linux

Bilde av Markus Winkler fra Unsplash

Bilde av Markus Winkler fra Unsplash

Denne guiden tar utgangspunkt i at du har en skybasert webserver hvor du har filer som bilder, pdf'er og annet som du ønsker å ta backup av til en lokal backup server.

Jeg har valgt å løse det i tre trinn. Først lager vi ett script som kjører på webserveren, og tar backup av filene. Så, lager vi ett script som kan kjøres etter at det første er ferdig. Dette kjøres på backup serveren, og laster ned den siste backupen for trygg lagring der. Til slutt kombinerer vi de to scriptene til ett som kan kjøres fra backup server. Dette scriptet er også laget for å gi litt mer tilbakemelding om hva som foregår når scriptet kjører.

Guiden er skrevet på denne måten for å gi en forståelse av prosessen rundt backup og gi deg som leser guiden nok innsikt til å kunne tilpasse scriptene til ditt behov.

Backup av filene

Steg 1 - Grunnsteget - Oppretting av komprimert TAR

Vi starter med å lage ett script som tar backup av filene

nano /home/stanley/fileBackup.sh
/home/stanley/fileBackup.sh
#!/bin/bash
# Written by Stanley Skarshaug 15.04.2021
# Script intended to be run once a day, to backup files on a webserver
# Saved the changes from one day to another in increments
#
# Every Sunday a new full backup is created, and the rest of the
# week the changes are archived in increments
#
# Change these three variables to fit your need
sourceDir=/var/www/website.no
backupDir=/home/stanley/backup
backupName=website.no

dateString=`date +"%Y.%U.%w"`
weekString=`date +"%Y.%U"`

incrementalFile=${backupDir}/${backupName}.${weekString}.snar
destinationFile=${backupDir}/${backupName}.${dateString}.tar.gz

tar -cz --listed-incremental=$incrementalFile -f ${destinationFile} ${sourceDir}

Det som egentlig skjer i dette scriptet er at vi lager en komprimert tarball. Denne tarballen inneholder endringene i filene siden sist backup. Den vil dermed inkludere informasjon som følger med på om en fil har blitt slettet siden sist sist backup.

Filen som følger med på endringene siden forrige backup er ".snar" filen. I scriptet over har denne filen ett filnavn basert på år og ukenummer. I Linux starter ukene på søndag, så når det er søndag, vil det automatisk bli opprett en ny .snar fil. Når vi tar backup på søndag er denne filen ny og tom. Derfor vil backup som utføres på søndag være en "full backup", som inneholder alle filene i mappen vi ønsker å ta backup av.

Mandag og de andre dagene i uken vil vi kun ta backup av endringene som ble gjort siden forrige dag. Siden det kun er endringene vi daglig tar backup av, vil disse backupene bli relativt små.

Det fine med denne løsningen er at om vi ønsker å gjenopprette filene slik de var på onsdag er det bare å gjenopprette de daglige backupene i denne rekkefølgen: søndag, mandag, tirsdag og onsdag.

For at scriptet skal kunne kjøres av brukeren din må det legges til execute rettighet på den.

chmod u+x /home/stanley/fileBackup.sh

Scriptet kan nå kjøres

/home/stanley/fileBackup.sh

Etter at scriptet kjører første dag vil det lage to filer

ls -l /home/stanley/backup
-rw-r--r-- 1 stanley stanley  669 april 15 21:24 website.no.2021.15.4.tar.gz
-rw-r--r-- 1 stanley stanley  629 april 15 21:32 website.no.2021.15.snar

Om du ønsker at dette sciptet skal kjøres daglig må det legges til i din crontab som en cron-job.

crontab -e
/etc/crontab
...
30 1 * * * /home/stanley/fileBackup.sh

Denne cron-jobben blir kjørt kl: 01:00 hver natt, søndag til lørdag

Lokal lagring av backup

Steg 2 - Ta kopi av backup på webserveren, og lagre den lokalt

Nå som vi har automatisert backup av filene på webserveren kan vi ta en kopi av backupen til den lokale backup serveren for trygg lagring.

Da lager vi ett script som henter backupen.

nano /home/admin/backupSync.sh
/home/admin/backupSync.sh
#!/bin/bash
# Written by Stanley Skarshaug 15.04.2021
# Script intended to be run once a day, to backup files on a webserver
# Saved the changes from one day to another in increments
#
# Every Sunday a new full backup is created, and the rest of the
# week the changes are archived in increments
#
# Change these three variables to fit your need
sourceDir=/var/www/website.no
backupDir=/home/stanley/backup
backupName=website.no
remoteHost=192.168.239.141
remoteUser=stanley
localPath=/home/stanley/backup/

dateString=`date +"%Y.%U.%w"`
destinationFile=${backupDir}/${backupName}.${dateString}.tar.gz

rsync ${remoteUser}@${remoteHost}:${destinationFile} ${localPath}

Når scriptet er lagret må det kunne bli executed.

chmod u+x /home/admin/backupSync.sh

For at scriptet skal kunne kjøres automatisk med en cron-job, må du opprette ett RSA nøkkelpar, hvor en kopi av din public key blir lagt på webserveren. Hvordan dette gjøres, kan du lese mere om her. Hvis det ikke finnes et RSA nøkkelpar vil scriptet feile, siden det ikke vil klare å automatisk autentisere innlogging på webserveren.

Nå er det bare å legge til scriptet som en cron-job på den lokale backup serveren.

crontab -e
/etc/crontab
...
30 1 * * * /home/admin/backupSync.sh

Helautomatisering

Steg 3 - Automatisere det hele i ett script som også rydder opp etter seg

Til nå har backup av filene vært delt opp i to separate script. Ett script som lager backup av filene på webserveren, og ett annet script som henter en kopi av backupen ned til backup serveren. Dette fungerer helt fint, men det er mye enklere om man heller kombinerer de to scriptene i ett som kan kjøres fra backup serveren. Som en bonus vil vi rydde opp i at det nå eksistere to backuper. En på webserveren, og en på backup serveren. Vi trenger bare en kopi.

Under kan du se scriptet for automatisk backup av filene på webserveren, men som kun lagres på backup serveren.

nano /home/stanley/totalBackup.sh
/home/stanley/totalBackup.sh
#!/bin/bash
#
# Originally written by Stanley Skarshaug 16.04.2021
# Script intended to be run once a day, to backup files on a remote host
# Saved the changes from one day to another in increments
#
# Every Sunday a new full backup is created, and the rest of the
# week the changes are archived in increments
#
# Change these six variables to fit your need
sourceDir=/var/www/website.no
backupDir=/home/stanley/backup
backupName=website.no
remoteHost=192.168.239.140
remoteUser=stanley
localPath=/home/stanley/backup/website.no/

dateString=`date +'%Y.%U.%w'`
weekString=`date +'%Y.%U'`

incrementalFile=${backupDir}/${backupName}.${weekString}.snar
destinationFile=${backupDir}/${backupName}.${dateString}.tar.gz

infoColor='\033[0;32m'
noColor='\033[0m'
infoBox="${infoColor}[INFO]${noColor}"

# Create backup on the remote host
printf "${infoBox} Creating a backup on the remote host... "
ssh ${remoteUser}@${remoteHost} "tar -cz --listed-incremental=${incrementalFile} -f ${destinationFile} ${sourceDir} 2>/dev/null"
printf "   DONE \n"

# Check if the local backup directory exists, if not create it.
if  [[ ! -d ${localPath} ]]; then
	printf "${infoBox}   Local backup folder was not found, creating it now. \n"
	mkdir -p ${localPath}
fi

# Transfer TAR to backup server
printf "${infoBox} RSYNC backup... "
rsync ${remoteUser}@${remoteHost}:${destinationFile} ${localPath}
printf "   DONE \n"

# Cleanup. Delete the TAR from the remote host
printf "${infoBox} Cleanup: Remove backup file on remote host..."
ssh ${remoteUser}@${remoteHost} "rm ${destinationFile}"
printf "   DONE \n"

printf "${infoBox} FINISHED - Backup job complete!\n"

Scriptet over ser kanskje litt voldsomt ut, men det er oversiktlig hvis man bryter det ned i mindre deler.

Linje 11-16: Her oppretter vi variablene som vi senere skal bruke i scriptet. Ved å gjøre dette slipper vi å måtte endre verdier flere steder i scriptet, noe som nesten garantert vil føre til menneskelig feil. I del 1 og 2 var det kanskje ikke så kritisk, men i dette scriptet er disse variablene brukt såpass mange ganger at det er mer viktig.

Linje 28-31: Her tas det backup av filene på serveren, den bruker ukens endringsfil slik at det kun er endringer siden sist komplett backup som blir lagt inn i den nye backup filen.

Linje 33 -37: Her kontrollerer vi om mappen vi har satt som lagringssted for backup eksiterer lokalt, om den ikke eksisterer opprettes den mappen.

Linje 39 - 42: Her overføres backup fra serveren til den lokale backup mappen vår.

Linje 44 - 47: Her slettes backup filen på serveren, slik at vi kun har en backup lokalt. Dette gjøres for at det ikke skal være to kopier av backupen, både på serveren og lokalt.

I likhet med scriptet i del 2 krever også dette scriptet at du har laget ett RSA nøkkelpar som brukes til autentisere innloggingen over SSH og med rsync.

Legg til execute rettigheter og kjør scriptet for å teste

chmod u+x /home/stanley/totalBackup.sh
/home/stanley/totalBackup.sh
[INFO] Creating a backup on the remote host...    DONE 
[INFO] Local backup folder was not found, creating it now. 
[INFO] RSYNC backup...    DONE 
[INFO] Cleanup: Remove backup file on remote host...   DONE 
[INFO] FINISHED - Backup job complete!

Du skal nå se backup filen på backup serveren din

tree /home/stanley/backup
backup
└── website.no
    └── website.no.2021.15.4.tar.gz

Nå kan det være praktisk å fjerne de to forrige cron-jobbene som ble opprettet på webserveren i del 1, backup serveren i del 2, og erstatte det med det nye som vil legger på backup serveren.

crontab -e
/etc/crontab
...
30 1 * * 0-6 /home/admin/totalBackup.sh