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!

Dovecot-Authentifizierung mit SSL

Diese kurze Anleitung beschreibt, wie man einen Dovecot IMAP-/POP3-Server so einrichtet, dass eine Anmeldung mit Klartext-Passwort nur noch über eine verschlüsselte SSL-Verbindung funktioniert. Ausprobiert habe ich das ganze zuhause auf meinem Server, der unter Ubuntu 8.0.4.1 x86 läuft und auf dem Dovecot bereits seit einigen Tagen problemlos funktioniert (Update: Bei einer Neu-Installation von Ubuntu 9.10 hat es auch geklappt). Die meisten Infos zu dieser Anleitung stammen aus dem Ubuntu-Wiki und dem Dovecot-Wiki.

1. Das Passwort verschlüsselt ablegen
Für die Anmeldung am Mailserver will ich nicht das Systempasswort des Users (aus /etc/shadow) verwenden, sondern ein eigenes. Das soll aber nicht im Klartext irgendwo rumliegen, sondern nur als SHA-Hash. Dabei hilft das Programm dovecotpw, dem als Parameter das gewünschte Hash-Verfahren übergeben wird. Hier ein Beispiel, wie es mit Salted SHA aussieht, man könnte aber genauso gut salted MD5 oder etwas anderes verwenden.

dovecotpw -s ssha -u <username>

Das Ergebnis verwendet man, um einen Eintrag in der Datei /etc/passwd.dovecot zu erzeugen. Jede Zeile der Datei beginnt mit dem Benutzernamen, gefolgt von einem Doppelpunkt. Danach kommt die Ausgabe von dovecotpw, also das Passwort Schema und der Hashwert des Passworts. Ein Beispiel:
username:{SSHA}bhLzZ105Lh+hShJ8UK3jD+nQekwD0okG

Man muss Dovecot noch mitteilen, wo die Passwort-Datei abgelegt ist, da diese nicht /etc/passwd.dovecot sein muss, sondern auch anderswo liegen kann. Dazu folgenden Eintrag in /etc/dovecot/dovecot.conf machen:
passdb passwd-file {
args = /etc/passwd.dovecot
}

2. Unverschlüsselte Plaintext-Authentifizierung abschalten
Wenn bisher die Anmeldung mit Plaintext-Passwörtern über unverschlüsselte Verbindungen zulässig war, dann sollte man dies jetzt in der Datei /etc/dovecot/dovecot.conf abschalten.
disable_plaintext_auth = yes

3. SSL einrichten
Nach dieser Beschreibung im Dovecot-Wiki kann man sehr schnell die Verwendung einer SSL-Verbindung einrichten. In Ubuntu 8.0.4.1. funktioniert das ohne irgendeine Änderung bereits nach der Installation. Bei mir trat nur das Problem auf, dass das verwendete Snakeoil-Zertifikat bereits abgelaufen war. Mit folgendem Befehl kann man sich sehr einfach ein neues Zertifikat selbst erstellen:
sudo make-ssl-cert generate-default-snakeoil --force-overwrite
Leider lässt sich dabei keine Gültigkeit einstellen und das erzeugte Zertifikat müsste bereits nach einem Monat erneuert werden. (Update zu Ubuntu 9.10: Mittlerweile wurde die Default-Gültigkeit auf 10 Jahre geändert, man kann also direkt bei 4. weitermachen.) Ändern kann man das ganze, indem man make-ssl-cert anpasst. Dabei handelt es sich um ein einfaches Skript, das unter /usr/sbin liegt. Mit einem beliebigen Editor öffnen (z.B.sudo vim /usr/sbin/make-ssl-cert und nach openssl suchen. In die folgende Zeile (bei mir Zeile 124) fügt man den Parameter -days ein, der die Gültigkeitsdauer angibt:
openssl req -config $TMPFILE -new -x509 -nodes \
Nach der Änderung:
openssl req -config $TMPFILE -new -days 365 -x509 -nodes \

Für die „Nicht-Snakeoil-Variante“ findet man den zu änderenden Openssl-Aufruf einige Zeilen darüber.

4. Dovecot neu starten und testen
Zum Schluss muss man nur noch den Server neu starten (sudo /etc/init.d/dovecot restart) und die Einstellungen des Mail-Clients anpassen. Im Thunderbird wäre das bei den Konto-Einstellungen zu finden:
-> Server-Einstellungen -> Sicherheit & Authentifizierung -> Verschlüsselte Verbindung verwenden -> SSL
Das sollte es dann gewesen sein.