Dateitransfer mit rsync: Eigentümer, Gruppen und Rechte behalten ohne root Login

Wenn man Verzeichnisse und Dateien von einem Linux Server auf einen anderen übertragen will, werden am Zielsystem Eigentümer und Gruppe der Dateien geändert und Zeitstempel neu gesetzt. Dadurch passen die Berechtigungen auf diese Dateien und Verzeichnisse eventuell nicht mehr. Außerdem verliert man die Information wann die Dateien zuletzt geändert wurden. In vielen Fällen will man diese Eigenschaften (Owner, Group, Permissions, Timestamps) aber unverändert behalten. Das Problem dabei ist, dass man am Zielsystem root-Rechte braucht, um sämtliche Dateieigenschaften bei den kopierten Dateien zu übernehmen. Ein direkter Login per SSH mit dem Benutzer root ist aber aus Sicherheitsgründen normalerweise nicht erlaubt ("PermitRootLogin no" in /etc/ssh/sshd_config) und das ist auch gut so. Das sollte man auch auf keinen Fall ändern! Braucht man auch nicht, denn dafür hat man folgende Alternativen:

Im einfachsten Fall will man die Daten nur einmal kopieren. Dann kann man die Dateien auf dem Quell-System per tar in eine Datei packen, per scp kopieren und am Zielsystem wieder auspacken. Die Eigenschaften der Dateien bleiben dabei erhalten.

Wenn man Dateien und Verzeichnisse mehrmals abgleichen will, ist der Umweg über tar sehr umständlich. Außerdem müssen dabei immer alle Daten übertragen werden. Das Kopieren per rsync hat den Vorteil, dass nur bei der ersten Übertragung alles kopiert wird. Ab dann werden nur noch geänderte oder neue Dateien übertragen. Bei Bedarf können am Zielsystem auch Dateien gelöscht werden, die seit der letzten Übertragung am Quellsystem gelöscht wurden (Parameter --delete). Damit man die Dateieigenschaften auf dem Zielsystem übernehmen kann verwendet man rsync zusammen mit sudo. So kann man das unter Debian und Ubuntu einrichten, bei anderen Linux-Derivaten wird es genauso (oder zumindest so ähnlich) funktionieren:

Zuerst erlaubt man dem Benutzer, der zum Kopieren verwendet wird (hier: myuser), die Benutzung von rsync ohne die Eingabe eines Passworts. Dazu wird am Zielserver die Datei /etc/sudoers bearbeitet (mit dem Befehl visudo, diese Datei immer mit visudo bearbeiten!) und folgende Zeile eintragen:

myuser ALL=NOPASSWD:/usr/bin/rsync

Mehr muss man nicht einrichten. Rsync startet man am Quellsystem dann zum Beispiel so (hier wird der Inhalt von /var/www in das selbe Verzeichnis am Zielserver example.com kopiert):

rsync -av -e ssh --rsync-path="sudo rsync" /var/www/ myuser@example.com:/var/www/

  • -a: Archiv-Modus, bei dem die Eigenschaften erhalten bleiben (Details siehe ManPage).
  • -v: Verbose, d.h. rsync gibt aus, was gemacht wird.
  • -e ssh: Verwende SSH zur verschlüsselten Übertragung.
  • --rsync-path="sudo rsync": Verwendet am Zielsystem rsync zusammen mit sudo.
  • --delete: Löscht am Zielsystem die Daten, die es am Quellsystem nicht mehr gibt (nicht im Beispiel oben, aber bei mehrmaligem Abgleich unter Umständen sinnvoll).

Sowohl beim Kopieren eines tar-Files als auch bei der eleganten rsync-Lösung gilt: Übernommen werden Benutzer-IDs und Gruppen-IDs, nicht deren Namen. Eine Grundvoraussetzung ist also, dass die Benutzer und Gruppen auf beiden Systemen die gleichen Benutzer-IDs bzw. Gruppen-IDs haben. Sonst hat man am Zielsystem nicht die Datei-Eigentümer und Gruppen, die man haben wollte.

Eigene externe IP-Adresse speichern (Bash-Skript)

Wegen einem Problem mit meiner DSL-Verbindung wollte ich ein Protokoll über die Häufigkeit der Verbindungsabbrüche haben. Die Idee war, jede Änderung der IP-Adresse zu speichern. Mein DSL-Problem ist mittlerweile behoben, aber vielleicht kann das Skript ja sonst noch jemand brauchen.

Das ganze besteht aus zwei Teilen: Einmal checkip.sh, das die aktuelle IP ermittelt und ausgibt. Und recordip.sh, das die aktuelle IP mit der letzten IP vergleicht und bei einer Änderung einen Eintrag in eine Protokolldatei macht (Datum, Uhrzeit, IP)  und einen Text ausgibt.

checkip.sh: Zur Ermittlung der externen IP-Adresse kann man wget (oder curl) und den Dienst http://checkip.dyndns.org/ benutzen. Das hat allerdings den Nachteil, dass bei jedem Check eine Abfrage an den DynDNS-Server geschickt wird. Eleganter geht es, wenn man eine Fritz!Box hat, bei der UPNP aktiviert ist. Die Idee dazu hatte ich von http://www.gimme-th.at. Irgendwann hat das aber nicht mehr funktioniert und ich musst mir selbst etwas basteln. War aber nicht besonders schwierig, die Grund-Idee war vorhanden und wie die Abfrage geht stand im Wiki von UbuntuUsers.de. Hier ist das Skript, das seit einigen Jahren bei meiner Firtz-Box 7270 funktioniert (umbenennen in checkip.sh und IP-Adresse der Fritz-Box anpassen):

Skript zum Download: checkip.txt

recordip.sh: Zum Ermitteln der IP wird ./checkip.sh aufgerufen, es sollte deshalb im selben Verzeichnis wie recordip.sh liegen. Die Protokoll-Datei und die Datei zum Zwischenspeichern der aktuellen IP können bei Bedarf am Anfang des Skripts geändert werden.


#!/bin/bash
# file to save the last recorded ip
LASTIPFILE=/tmp/lastip
# file to save an ip-history
LOGFILE=/home/username/ip.log

# if lastipfile does not exist, create it
if [ ! -e $LASTIPFILE ]; then
echo "NoIpSavedYet" > $LASTIPFILE
fi

# get the current ip with a script from www.gimme-th.at
IP=`./checkip.sh`
# Get the last ip
LASTIP=`cat $LASTIPFILE`

if [ $IP != $LASTIP ]; then
# output message
echo "IP geaendert, neue IP ist $IP";
# append ip to logfile
echo `/bin/date +%Y%m%d_%H%M%S` $IP >> $LOGFILE
# remember current ip until next check
echo $IP > $LASTIPFILE
fi

Skript zum Download: recordip.sh

Wenn man automatisch einmal pro Minute prüfen und bei Änderungen benachrichtigt werden will, kann man das sehr schön als Cron-Job einrichten. Ein Text wird nur bei einer Änderung ausgegeben, d.h. Mails bekommt man auch nur, wenn sich die IP tatsächlich geändert hat.

Getestet unter Ubuntu Linux mit einer Fritz!Box 7270. Bei Fragen oder Verbesserungsvorschlägen einfach einen Kommentar schreiben. Danke!