rsync
rsync dient der Synchronisation von Dateien und Verzeichnissen, auch über Rechnergrenzen hinweg. Mit rsync ist sowohl das Netzwerkprotokoll als auch die gleichnamige Programm-Implementierung gemeint.
Bei rsync läuft die Synchronisation immer unidirektional von einem Quellverzeichnis oder einer Datei (in den Beispielen src
) zu einem Zielverzeichnis oder einer Datei ab (dest
). Per Parameter lässt sich unter anderem steuern, ob Dateien im Zielverzeichnis auch gelöscht werden sollen, wenn sie im Quellverzeichnis nicht mehr existieren. Während der Synchronisation werden nur die geänderten Teile der Dateien übertragen (Delta-Kodierung), was Zeit spart. Abgebrochene Transfers werden ab der Stelle wieder aufgenommen, an denen wirklich abgebrochen wurde.
Endet eine Verzeichnisangabe mit einem /
, wechselt rsync in das Verzeichnis, ignoriert den Verzeichnisnamen und verarbeitet alle Dateien innerhalb des Verzeichnisses; fehlt der abschliessende Slash, wird der Verzeichnisname berücksichtigt und dieser ebenfalls gesynct.
Installation:
dnf -y install rsync
Kurz- vs. Lang-Parameter:
-A
:--acls
-D
:--devices --specials
-g
:--group
-H
:--hard-links
-l
:--links
-o
:--owner
-p
:--perms
-r
:--recursive
-t
:--times
-X
:--xattrs
Nützliche Parameter:
--archive
:Ist die Kurzform für-rlptgoD
. Meist wird er durch--human-readable
und--progress
ergänzt.--checksum
rsync soll nicht anhand von Modifikationsdatum, sondern anhand on Checksummen arbeiten.--delete
:Löscht Dateien im Zielverzeichnis, die im Quellverzeichnis nicht mehr existieren.--dry-run
Test-Modus.--exlude
:Dateien und/oder Verzeichnisse von der Synchronisation ausnehmen. Der Parameter kann mit Wildcards arbeiten und mehrfach verwendet werden.--one-file-system
:Lokal bleiben, Dateien auf Netzwerk-Mounts ignorieren.--password-file /path/to/secrets.rsync
:Datei, die das Passwort für den Zugriff auf einen per rsync-Daemon exportiertes Verzeichnis enthält. Muss perchmod 0400
geschützt werden.--times
:Zeitstempel beim Kopieren behalten.--update
:Ist die Datei im Zielverzeichnis neuer, wird sie nicht kopiert.
Verwendung von rsync
Achtung
Kopiert KEINE versteckten Dateien:
rsync source/* dest
Sync INKLUSIVE versteckter/hidden dot-Files:
rsync source/ dest
(also den Wildcard weglassen)
Der einfachste Aufruf: alle Dateien der obersten Verzeichnisebene synchronisieren:
rsync src dest
Eine Datei von lokal auf einen entfernten Server kopieren (ohne weitere Angaben wird das per SSH erledigt). Dabei „sudo“ verwenden:
rsync --archive --human-readable --progress --verbose --rsync-path='sudo rsync' src user@host:dest
Gewünschte Art der Remoteverbindung spezifizieren und für SSH zum Beispiel den Port ändern:
rsync --archive --human-readable --progress --verbose --rsh "ssh -p 2222" user@host:src dest
Eine Datei von lokal auf einen entfernten Server kopieren, hier per rsync:
rsync --archive --human-readable --progress --verbose src rsync://user@host:dest
Sync mit Ausnahmen von einem per rsync://
erreichbarem, entfernten Verzeichnis auf ein lokales Verzeichnis. Passwort wird nicht in einer Datei definiert, sondern als Umgebungsvariable gesetzt:
export RSYNC_PASSWORD=myrsyncpwd
rsync --archive --human-readable --progress --verbose --exclude=cache --exclude=files/*.pdf --delete rsync://user@host:src dest
Gegen einen rsync-Daemon authentifizieren; Passwort wird in einer Datei definiert:
mypassword
chmod 0600 secrets.rsync
rsync --human-readable --verbose --recursive --times --update --delete --password-file secrets.rsync src rsync://user@host:dest
Sync auf Basis einer Datei-Liste - nur ausgewählte Dateien auf einen Remote-Host kopieren. Hier wird ausgehend vom aktuellen Verzeichnis die relativ organisierte Datei-Liste abgearbeitet:
rsync --archive --human-readable --progress --files-from=myfilelist . host:dest
Alles bis auf einen Unterordner synchronisieren:
tree /tmp/src
# /tmp/src
# ├── config
# │ ├── data
# │ │ └── file
# │ ├── file1
# │ ├── file2
# │ └── file3
# └── data
# ├── file1
# ├── file2
# └── file3
# test using --dry-run and --debug
rsync --progress --archive --dry-run --debug=FILTER --exclude=/data/ /tmp/src/ /tmp/dest
# sending incremental file list
# [sender] hiding directory data because of pattern /data/
# created directory /tmp/dest
# ./
# config/
# config/file1
# config/file2
# config/file3
# config/data/
# config/data/file
# actually run
rsync --progress --archive --exclude=/data/ /tmp/src/ /tmp/dest
Rsync nice und bandbreitenschonend laufen lassen, in Units per Second (hier KByte/sec):
/usr/bin/nice --adjustment 19 /usr/bin/rsync --bwlimit 1.5K --archive --human-readable --progress --verbose src dest
Daemon-Mode
dnf -y install rsync-daemon
Für den Daemon-Modus muss ein Username/Passwort und eine Liste der zu exporierenden Verzeichnisse konfiguriert werden.
myuser1:mypassword1
myuser2:mypassword2
chmod 0600 /etc/rsyncd.secrets
Im Beispiel wird /etc
als etc
und /var/www/html
als var-www-html
exportiert. Der anzugebene Benutzername gilt nur innerhalb von rsync, muss also nicht auf dem System existieren:
1# global parameters go here
2auth users = myuser1,myuser2
3gid = root
4lock file = /var/lock/subsys/rsync.lock
5log file = /var/log/rsyncd.log
6pid file = /var/run/rsyncd.pid
7read only = yes
8secrets file = /etc/rsyncd.secrets
9uid = root
10
11[etc]
12path = /etc
13
14[var-www-html]
15path = /var/www/html
In SELinux erlauben, dass diese (eigentlich alle) Verzeichnisse read-only exportiert werden dürfen:
setsebool -P rsync_export_all_ro on
# and, if more needed (for /var/spool/postfix for example)
setsebool -P rsync_full_access on
Start des Daemons:
systemctl enable --now rsyncd
Firewall einrichten und Port 873 (tcp und udp) freigeben, zum Beispiel per
firewall-cmd --permanent --add-service=rsyncd
firewall-cmd --reload
rsync-Logdateien über Logrotate aufräumen, im Beispiel nach 14 Tagen:
cat >/etc/logrotate.d/rsync <<EOF
/var/log/rsyncd.log {
compress
daily
dateext
missingok
rotate 14
size 1
}
EOF
Der Client synct dann beispielshalber per:
export RSYNC_PASSWORD=mypassword1
rsync --archive rsync://myuser1@host:/var-www-html .
Robustes Backup-Skript mit Deduplizierung
Das nachfolgende Backup-Skript arbeitet mit Backup-Ordnern beginnend bei „00“ zum Beispiel bis „99“, wobei „00“ das aktuellste und „99“ das älteste Backup enthält. Die Backups werden bei jedem Aufruf rotiert - das älteste Backup „99“ wird entfernt, aus „98“ wird „99“ usw., bis aus „00“ das Verzeichnis „01“ wird. Mit Hilfe von rsync wird synchronisiert, mit Hilfe von Hard-Links wird dedupliziert und nur das gesichert, was sich geändert hat. Jedes Verzeichnis enthält durch die durchgehende Verwendung von Hard-Links die gesamte Quell-Verzeichnisstruktur, so dass sich ein Restore sehr einfach durchführen lässt. Die zu sichernden Rechner und deren Verzeichnisse werden in einer CSV-Datei gepflegt.
1#!/usr/bin/env bash
2
3# call with parameter: "backup daily.conf|weekly.conf|... myhostlist.csv"
4
5# http://mywiki.wooledge.org/BashFAQ/045
6LOCK_FILE=/var/lock/subsys/backup-$(basename $1 | cut -d. -f1)
7if mkdir -- $LOCK_FILE; then
8 trap 'rm -rf -- $LOCKFILE' EXIT # remove directory when script finishes
9 trap 'rm -rf -- $LOCKFILE' TERM # remove directory when script gets terminated
10 echo $$ > "$LOCKFILE/pid"
11 logger "$0 successfully acquired lock."
12else
13 logger "$0 - Backup is already running, exiting..."
14 exit 1
15fi
16
17# include configuration file given via first parameter
18BACKUP_TYPE=$1
19BACKUP_LIST=$2
20source "$BACKUP_TYPE"
21
22# create structure for backups if it does not exist
23mkdir -p $BACKUP_DIR
24for (( i = 0; i <= $BACKUP_MAX ; i++ ))
25do
26 if [ ${#i} == 1 ]; then
27 mkdir -p $BACKUP_DIR/0$i
28 else
29 mkdir -p $BACKUP_DIR/$i
30 fi
31done
32
33# rotate backup folders
34\mv $BACKUP_DIR/$BACKUP_MAX $BACKUP_DIR/tmp
35for (( i = $BACKUP_MAX ; i > 0 ; i-- ))
36do
37 j=$(($i - 1))
38 if [ ${#j} == 1 ]; then
39 j="0$j"
40 fi
41 if [ ${#i} == 1 ]; then
42 \mv $BACKUP_DIR/$j $BACKUP_DIR/0$i
43 else
44 \mv $BACKUP_DIR/$j $BACKUP_DIR/$i
45 fi
46done
47\mv $BACKUP_DIR/tmp $BACKUP_DIR/00
48
49# now let's do the backup
50cd $BACKUP_DIR
51
52# the backup takes place here, based on CSV files
53while IFS=\; read -r SERVER SRC OPTIONS
54do
55 if [ "$SERVER" != "" ]; then
56 if [ "${SERVER:0:1}" != "#" ]; then
57
58 TS=$(date +"%Y-%m-%d %H:%M:%S")
59 mkdir -p 00/$SERVER
60
61 logger "-------------------------------------------------------------------------------"
62 logger "Job:"
63 logger "* Current Dir: $(pwd)"
64 logger "* Source Dir: $SERVER:$SRC"
65 logger "* Destination Dir: 00/$SERVER$SRC/"
66 logger "* Options: $OPTIONS"
67 logger "* Start: $TS"
68 logger "$0 - $TS - $SERVER:$SRC - Start"
69
70 rsync --rsh="ssh" --recursive --links --perms --group --owner --devices --specials \
71 --human-readable --compress --compress-level=9 --checksum --delete \
72 $OPTIONS --link-dest=../../01/$SERVER $SERVER:$SRC 00/$SERVER
73
74 TS=$(date +"%Y-%m-%d %H:%M:%S")
75 logger "* Stop: $TS\n";
76
77 logger "$0 - $TS - $SERVER:$SRC - Stop"
78 fi
79 fi
80done < $BACKUP_LIST
81
82logger "-------------------------------------------------------------------------------"
83logger "Finished."
84
85logger "$0 - finished"
Eine passende Konfigurationsdatei dazu:
1#!/usr/bin/env bash
2
3# where to store the backups
4BACKUP_DIR=/backup/daily
5
6# number of backups: 01, 30, 99, whatever (don't forget the leading zero)
7BACKUP_MAX=99
Eine passende Serverliste, die angibt, welche Dateien und Verzeichnisse mit welchen Optionen zu sichern sind:
1# expecting "SERVER;SRC[; RSYNC-OPTIONS]" - don't forget an empty last line
2
3server1;/etc;--exclude-from=exclude-filelist.server.txt
4
5server2;/boot
6server2;/etc
7server2;/root
Aufruf mit:
mycoolbackup.sh daily.conf daily.csv
Um Dateien aus dem Backup wiederherzustellen, diese beispielsweise per tar
zusammenfassen und per rsync
oder scp
auf das Zielsystem kopieren.
tar czvf ~/backup.tar.gz FILES
scp ~/backup.tar.gz SERVER:/tmp
rm ~/backup.tar.gz
Troubleshooting
- rsync: opendir „/.“ (in dest) failed: Permission denied (13)
Neustart des rsync-Daemons, oder der rsyncd wird durch SELinux daran gehindert, die konfigurierten Verzeichnisse zu exportieren (
setsebool -P rsync_export_all_ro on
ausführen).- rsync: rsync_xal_set: lremovexattr(„/backup“,“security.selinux“) failed: Permission denied (13)
Taucht bei Verwendung von
--acls --xattrs
mit Quelle:xfs und Ziel:ZFS auf.rsync --archive
erzeugt trotz bzw. zusammen mit--checksum
und--link-dest
keine Hard-Links, wenn sich der Timestamp einer Datei, aber nicht deren Inhalt geändert hat.Hier hilft nur,
--archive
wegzulassen und selbst anzugeben, sowie die Option--time
dabei zu entfernen (--archive
=-rlptgoD no -H,-A,-X
; daraus macht man--recursive
,--links
,--perms
,--group
,--owner
,--acls
,--xattrs
,--devices --specials
).
Built on 2024-11-18