Kategorie Code

Shell-Skript zum automatischen FTP-Download

11.04.2008 | Code | 0 Kommentare
Mal ein kleines Shell-Skript als Notiz, muss man ja net immer neu schreiben:

#!/bin/bash

ftp -pvin FTPSERVER < < END_SCRIPT
quote USER FTPUSER
quote PASS FTPPASSWORD
cd FTPDIR
lcd LOCALDIR
mget *
bye
END_SCRIPT

Die FTP-Platzhalter austauschen (FTPSERVER, FTPUSER, FTPPASSWORD, FTPDIR und LOCALDIR), das Skript ausführbar machen und evtl. als Cron Job eintragen. Das Teil lädt einfach alle Dateien in FTPDIR runter nach LOCALDIR.

Shell-History

11.04.2008 | Code | 0 Kommentare
Mal was interessantes, was ich mir einfach mal notieren will Wink
history|awk '{a[$2]++} END{for(i in a){printf "%5d\t%s\n",a [ i ],i}}'|sort -rn|head

Das gibt eine Liste der verwendeten Kommandos auf der Shell aus, zum Beispiel sowas:
84   sudo
19 l
16 cd
12 scp
12 python
10 kill
9 psx
7 exit
6 ./configure

Inkrementielle Backups auf "öffentlichem" FTP-Server

17.03.2008 | Code | 1 Kommentar
Sehr oft stellen Anbieter von Root-Servern oder vServern Backup-Platz auf einem FTP-Server im gleichen Subnetz zur Verfügung, also innerhalb des Rechenzentrum, in dem die eigene Kiste steht. Das Problem dabei: Der eigene Backupplatz dort ist nicht vor den Augen Dritter sicher, so kann der Anbieter selbst bzw. der Admin des Backup-Rechners mal vorbei gucken oder vielleicht gibts sogar einen Fehler im FTP-Server oder dem Netzsegment und die Daten stehen sperrangelweit offen (Fehler sind menschlich und passieren auch in den besten Umgebungen).

Natürlich möchte man nicht, dass alle Daten, ob Mails, Webseiten, SQL-Dumps oder Konfigurationsdateien einfach so offen liegen.

Des weiteren muss man natürlich auch regelmäßig Backups machen, damit diese was nützen. Dabei sollten diese aber wenig Platz verbrauchen. Meist hat man nur recht geringen Platz zur Verfügung (30 bis 50 GB sind so der Durchschnitt bei den meisten Anbietern nach meinen Erfahrungen).

Alle beiden Dinge kann man relativ simpel lösen: Duplicity!

Duplicity ist ein Programm, dass verschlüsselte, inkrementielle Backups erstellen und diese dann zum Beispiel auf FTP-Servern speichern kann. Duplicity ist im Debian-Repository (und auch in (K)Ubuntu) enthalten und kann einfach installiert werden:

sudo aptitude install gpg
sudo aptitude install duplicity

Nun kann man schon Backups erzeugen:

FTP_PASSWORD=secret duplicity /home/exampleuser ftp://backupuser@backup.example.com/subdirectory

Beim ersten Lauf wird ein Vollbackup erzeugt, erst bei erneutem Aufruf werden dann inkrementielle Backups erzeugt.

Mit dem Parameter --exclude kann man Verzeichnisse vom Backup ausschließen. Backups wiederherstellen geht auch relativ simpel:

FTP_PASSWORD=secret duplicity ftp://backupuser@backup.example.com/ /home/exampleuser

Allerdings kann man dies so noch nicht automatisiert verwenden (z.B. in Cron Jobs). Duplicity benötigt ein Passwort zur Verschlüsselung und fragt so jedesmal nach. Damit das reibungslos geht, müssen wir erstmal in GnuPG einen Schlüssel dafür anlegen.

debianserver:/home/exampleuser# gpg --gen-key

Ob das ganze richtig funktioniert hat, kann man einfach nachprüfen: gpg --list-keygibt eine Liste der Schlüssel aus. Da sollte der gerade angelegte mit den richtigen Daten dabei sein.

So, nun können wir uns ein kleines Skript schreiben, das den eigentlichen Aufruf von duplicity übernimmt:
#!/bin/bash

export PASSPHRASE=secret
export FTP_PASSWORD=ftpsecret

duplicity --encrypt-key "9D6F907C" --sign-key "9D6F907C" \
--exclude /proc \
--exclude /dev \
--exclude /sys \
--exclude /swap \
/ ftp://user@backup-server.de/

Natürlich muss man hier noch Anpassungen vornehmen. Als PASSPHRASE wird das Passwort für die GPG-Verschlüsselung eingetragen, das wir auch oben bei der Erstellung verwendet haben. Als encrypt-key und sign-key trägt man die ID des Schlüssels ein (das ist oben in rot markiert). Zur Erhöhung der Sicherheit kann man auch zwei unterschiedliche Schlüssel verwenden. Die FTP-Daten muss man entsprechend den Daten anpassen, die man von seinem Anbieter bekommen hat.
Auch sollte man sich überlegen, welche Verzeichnisse man genau ausklammern will und entsprechende Zeilen hinzufügen.

In diesem Beispiel wird die komplette Verzeichnisstruktur bis auf die paar mit exclude ausgenommenen Verzeichnisse gesichert (dafür ist das / in der letzten Zeile verantwortlich). Ob man wirklich so umfangreiche Sicherungen will, ist je nach Situation unterschiedlich. Darüber sollte man durchaus erstmal nachdenken und das Für und Wider einer großen, allgemeinen zu einer kleinen, speziellen Sicherung abwägen.

Wer will, kann sich das Ergebnis immer per Mail zuschicken lassen (dazu einfach | mail -s "duplicity backup" root@pumuckl-fanclub.de hinten dran anhängen). Wer sich aber Ergebnisse von Cron-Jobs eh per Mail zuschicken lässt (MAILTO-Anweisung in der crontab) kann darauf verzichten, da er diese Ergebnisse sowieso bekommt.

Als letzten Schritt speichert man obiges Skript z.B. unter /usr/local/bin/ftpbackup und macht dies mit chmod +x /usr/local/bin/ftpbackup ausführbar. Dann editiert man mit
crontab -e die Crontab von root (vorher evtl. mit sudo su auf root wecheln). Das Skript muss als root laufen, wenn wie im obigen Beispiel die gesamte Verzeichnisstruktur gesichert werden soll. Soll nur z.B. ein Homeverzeichnis eines bestimmten Benutzers gesichert werden, reicht es auch aus, den Aufruf in die crontab dieses Nutzers einzutragen.
Wie dem auch sei, man trägt eine Zeile für das Backup ein:

27 5 * * * /usr/local/bin/ftpbackup

Diese Zeile bewirkt, dass jeden Tag frühs um 05:27 Uhr das Backup gestartet wird.

Das sollte reichen. Jetzt startet man am besten erstmal manuell ein Backup, da das erste ja ein Full Backup wird und somit relativ lange dauern dürfte. In Zukunft kommen dann inkrementielle Backups hinzu.

Noch ein Tipp:
Mit folgender Zeile kann man sich den Restplatz auf dem FTP-Backup-Server anzeigen lassen (allerdings ist dieser Tipp nicht auf meinen Mist gewachsen, sondern das habe ich irgendwo aufgeschnappt, weiß aber leider die Quelle nicht mehr. Dennoch ein Dank an dieser Stelle an Unbekannt dafür Wink ):
echo du . | lftp -u FTPUSER,FTPPASSWORT FTPSERVER | awk -v LIMIT="50" '$1~/[0-9]+/ {QUOTA=LIMIT*1024*1024; print (QUOTA-$1)/1024/1024 " GB left"}'

Natürlich müssen die roten Werte an die Werte der eigenen Umgebung angepasst werden. Als LIMIT wird der vom Anbieter zugewiesene Platz in GB genannt, in diesem Fall 50 GB. Das ganze kann man auch (ähnlich wie oben) als Skript verpacken, z.B. unter /usr/local/bin/ftpbackupleft o.ä.

Backups aller MySQL-Datenbanken, Version 2

28.11.2007 | Code | 0 Kommentare
Ich habe das Skript, das in diesem Post beschrieben ist, überarbeitet. Nun macht es nicht nur Backups aller lokalen MySQL-Datenbanken, sondern löscht vorher auch alle Backups, die seit einer gewissen Anzahl an Tagen nicht mehr geändert wurden.
Vorteil: Im Backup-Verzeichnis liegt nun immer nur eine festgelegte Anzahl an Sicherungen. Das sieht dann z.B. so aus:

test@bheil-pc:~> ls /var/backups/sql/
insgesamt 28K
drwxr-xr-x 2 root root 4,0K 2007-11-22 06:03 2007.11.22
drwxr-xr-x 2 root root 4,0K 2007-11-23 06:03 2007.11.23
drwxr-xr-x 2 root root 4,0K 2007-11-24 06:03 2007.11.24
drwxr-xr-x 2 root root 4,0K 2007-11-25 06:03 2007.11.25
drwxr-xr-x 2 root root 4,0K 2007-11-26 06:03 2007.11.26
drwxr-xr-x 2 root root 4,0K 2007-11-27 06:03 2007.11.27
drwxr-xr-x 2 root root 4,0K 2007-11-28 15:27 2007.11.28

Man sieht also, es liegen generell immer Sicherungen der letzten 7 Tage bereit.

Hier nun das angepasst Skript:
#!/bin/bash

####################
# Das hier anpassen!
####################
# Das Sicherungsverzeichnis - hier landen alle Backups als
# Unterverzeichnisse und nach Datum sortiert
# Achtung: Dieses Verzeichnis muss existieren und das
# Skript muss dort Schreibrechte besitzen!
SAVEDIR="/home/backup/sql"

# Anzahl der Sicherungen, sprich Tage - 6 steht fuer eine
# Woche (7 Sicherungen, da die aktuelle nicht gezaehlt wird)
DAYSOLD="6"

# Temp-Verzeichnis (das Skript braucht dort Schreibrechte)
TMPDIR="/tmp"

# Root-Passwort zur MySQL-Datenbank
DBPWD="PASSWORT"

####################
# Ab hier i.d.R. keine Aenderung mehr noetig
####################

# Erzeuge Liste aller Datenbanken in $TMPDIR/dbaselist.txt
mysqlshow -u root -p$DBPWD | awk '{print $2}' | \
grep -v Databases | sort > $TMPDIR/dbaselist.txt

# Finde und loesche alles, was seit $DAYSOLD Tagen nicht
# veraendert wurde
find $SAVEDIR -maxdepth 1 -mindepth 1 \
-mtime +$DAYSOLD -exec rm -rf {} \;

# Geh ins Sicherungsverzeichnis und lege ein Verzeichnis
# des heutigen Datums an
cd $SAVEDIR
mkdir -p `date +%Y.%m.%d`
cd `date +%Y.%m.%d`

# Liste der Datenbanken durchgehen und Sicherung erstellen
for x in `cat /tmp/dbaselist.txt`; do
mysqldump --opt -u root -p$DBPWD $x >$x.sql;
done;

# Aufraeumen
rm -f *.gz
rm -f /tmp/dbaselist.txt

# Alle Dateien zippen
gzip *

Backups aller MySQL-Datenbanken

11.09.2007 | Code | 0 Kommentare
Wichtig:
Von diesem Skript gibt es eine überarbeitete Version hier!

Wie sichert man alle MySQL-Datenbanken eines Systems? Folgendes Skript funktioniert auf etlichen Systemen und erstellt ein Dump jeder Datenbank nach /var/backups/sql: