Systemverwaltung und Wartung

Wichtig zu wissen, dass es zcat, zless, bzcat, bzless, xzcat, xzless gibt:

$> zless /usr/share/doc/firefox-esr/changelog.Debian.gz

Dies macht nämlich das Lesen von Dokumentation, die oft in komprimierter Form vorliegt, viel einfacher.

Eine Datei komprimieren:

$> cp /etc/services .
cp: „./services“ überschreiben? j
$> gzip services
gzip: services.gz already exists; do you wish to overwrite (y or n)? y
$> ls -l services*
-rw-r--r-- 1 root root 7554 Aug  9 09:24 services.gz
-rw-r--r-- 1 root root 7554 Mai  5 12:34 services-via-stdout-zipped.gz
$>

Entpacken kann man nun mit ‚gzip -d‘ oder ‚gunzip‘:

$> gzip -d services.gz
$> ls -l services*
-rw-r--r-- 1 root root 19605 Aug  9 09:24 services
-rw-r--r-- 1 root root  7554 Mai  5 12:34 services-via-stdout-zipped.gz

Den Vorgang wiederholen, wobei ‚gunzip‘ verwendet werden soll:

$> gzip services
$> ls -l services*
-rw-r--r-- 1 root root 7554 Aug  9 09:24 services.gz
-rw-r--r-- 1 root root 7554 Mai  5 12:34 services-via-stdout-zipped.gz
$> gunzip services.gz
$> ls -l services*
-rw-r--r-- 1 root root 19605 Aug  9 09:24 services
-rw-r--r-- 1 root root  7554 Mai  5 12:34 services-via-stdout-zipped.gz
$>

Wenn wir nicht direkt an der Datei selber operieren wollen (Originaldatei nicht komprimieren), muss mit stdout (Option ‚-c‘) gearbeitet werden:

$> gzip -c services > services-mit-Option-c-gepackt
$> ls -l services*
-rw-r--r-- 1 root root 19605 Aug  9 09:24 services
-rw-r--r-- 1 root root  7554 Aug  9 09:33 services-mit-Option-c-gepackt
-rw-r--r-- 1 root root  7554 Mai  5 12:34 services-via-stdout-zipped.gz

Beim Entpacken der Datei hilft leider die Tab-Taste nicht, weil das Suffix nicht mitgegeben wurde:

$> gunzip services-mit-Option-c-gepackt
gzip: services-mit-Option-c-gepackt: unknown suffix -- ignored
$>

Schlimmer noch: Das Kommando weigert sich direkt! Deshalb erst umbenennen:

$> mv services-mit-Option-c-gepackt services-mit-Option-c-gepackt.gz
$> gunzip -v services-mit-Option-c-gepackt.gz
services-mit-Option-c-gepackt.gz:     61.6% -- replaced with services-mit-Option-c-gepackt
$>

Was passiert, wenn gzip mehrmals hintereinander ohne ‚-d‘ angewendet wird:

$> ls -l services*
-rw-r--r-- 1 root root 19605 Aug  9 09:24 services
-rw-r--r-- 1 root root 19605 Aug  9 09:33 services-mit-Option-c-gepackt
-rw-r--r-- 1 root root  7554 Mai  5 12:34 services-via-stdout-zipped.gz
$> gzip services
$> ls -l services*
-rw-r--r-- 1 root root  7554 Aug  9 09:24 services.gz
-rw-r--r-- 1 root root 19605 Aug  9 09:33 services-mit-Option-c-gepackt
-rw-r--r-- 1 root root  7554 Mai  5 12:34 services-via-stdout-zipped.gz
$> gzip services.gz
gzip: services.gz already has .gz suffix -- unchanged

Auf direktem Wege funktioniert es nicht, vielleicht via stdout:

$> gzip -c services.gz > services.gz.gz
$> ls -l services*
-rw-r--r-- 1 root root  7554 Aug  9 09:24 services.gz
-rw-r--r-- 1 root root  7589 Aug  9 09:39 services.gz.gz
-rw-r--r-- 1 root root 19605 Aug  9 09:33 services-mit-Option-c-gepackt
-rw-r--r-- 1 root root  7554 Mai  5 12:34 services-via-stdout-zipped.gz
$>

Das ist dann tatsächlich möglich, bringt aber keinen Gewinn, im Gegenteil ist die Datei durch die neuen Kontrollinformationen größer geworden!

Mit mehreren Dateien arbeiten

Wir erzeugen drei Dateien:

2047  echo INHALT > datei1.txt
2048  echo INHALT > datei2.txt
2049  echo INHALT > datei3.txt

Wir testen, ob sich die drei Dateien OHNE direkt (ohne separates Verzeichnis) archivieren lassen:

2051  pwd
2052  tar cvf drei-textdateien.tar datei*
2053  ls -l drei-textdateien.tar
2054  file drei-textdateien.tar

Den Inhalt (table of content) lediglich auflisten:

$> tar tf drei-textdateien.tar
$> ls -l
insgesamt 24
-rw-r--r-- 1 root root     7 Aug  9 09:45 datei1.txt
-rw-r--r-- 1 root root     7 Aug  9 09:45 datei2.txt
-rw-r--r-- 1 root root     7 Aug  9 09:45 datei3.txt
-rw-r--r-- 1 root root 10240 Aug  9 09:52 drei-textdateien.tar
$> cat datei?.txt
INHALT
INHALT
INHALT
$> echo Datei1 > datei1.txt
$> echo Datei2 > datei2.txt
$> echo Datei3 > datei3.txt
$> cat datei?.txt
Datei1
Datei2
Datei3

Werden beim Entpacken des Archivs im selben Verzeichnis einfach die alten Dateien überschreiben? Wir testen es:

$> tar xvf drei-textdateien.tar
datei1.txt
datei2.txt
datei3.txt
$> cat datei?.txt
INHALT
INHALT
INHALT
$> ls -l
insgesamt 24
-rw-r--r-- 1 root root     7 Aug  9 09:45 datei1.txt
-rw-r--r-- 1 root root     7 Aug  9 09:45 datei2.txt
-rw-r--r-- 1 root root     7 Aug  9 09:45 datei3.txt
-rw-r--r-- 1 root root 10240 Aug  9 09:52 drei-textdateien.tar
$>

JA, und zwar OHNE Rückfrage!! Daher ist es besser die Dateien in ein separates Verzeichnis zu legen:

$> mkdir dateien
$> mv datei?.txt dateien/
$> tar cvf dateien.tar dateien/
dateien/
dateien/datei2.txt
dateien/datei3.txt
dateien/datei1.txt
$>

Beim Erzeugen von Archiven können die Dateien von verschiedenen Orten zusammengerufen werden. Es verhält sich das Kommando ‚tar‘ dabei so, wie es unter https://www.gnu.org/software/tar/manual/html_node/directory.html beschrieben ist:

$> cat /file*
123
123
$> ls -l /archiv/
insgesamt 12
-rw-r--r-- 1 root root 8 Aug  9 11:08 datei1.txt
-rw-r--r-- 1 root root 8 Aug  9 11:08 datei2.txt
-rw-r--r-- 1 root root 8 Aug  9 11:09 datei3.txt
$> tar -c -vf /tmp/myarchiv.tar /file* -C /archiv datei2.txt datei3.txt
tar: Entferne führende „/“ von Elementnamen
/file1
/file2
datei2.txt
datei3.txt
$> tar tf /tmp/myarchiv.tar
file1
file2
datei2.txt
datei3.txt
$>

Ein weiteres Beispiel:

$> tar -cvf /tmp/wichtige-files.tar /etc/fstab /etc/services  /etc/network/* -C /archiv datei1.txt datei2.txt
tar: Entferne führende „/“ von Elementnamen
/etc/fstab
/etc/services
/etc/network/if-down.d/
/etc/network/if-down.d/upstart
/etc/network/if-down.d/avahi-autoipd
/etc/network/if-down.d/postfix
/etc/network/if-down.d/wpasupplicant
/etc/network/if-post-down.d/
/etc/network/if-post-down.d/wireless-tools
/etc/network/if-post-down.d/avahi-daemon
/etc/network/if-post-down.d/wpasupplicant
/etc/network/if-pre-up.d/
/etc/network/if-pre-up.d/wireless-tools
/etc/network/if-pre-up.d/wpasupplicant
/etc/network/if-pre-up.d/ethtool
/etc/network/if-up.d/
/etc/network/if-up.d/upstart
/etc/network/if-up.d/avahi-autoipd
/etc/network/if-up.d/postfix
/etc/network/if-up.d/avahi-daemon
/etc/network/if-up.d/openssh-server
/etc/network/if-up.d/wpasupplicant
/etc/network/if-up.d/ntpdate
/etc/network/if-up.d/ethtool
/etc/network/if-up.d/mountnfs
/etc/network/interfaces
/etc/network/interfaces.d/
/etc/network/interfaces_ok
/etc/network/run
datei1.txt
datei2.txt
$>

Aber Achtung, die Option ‚-C‘ akzeptiert keine Dateijoker:

$> tar -cvf /tmp/wichtige-files.tar /etc/fstab /etc/services  /etc/network/* -C /archiv datei*
tar: Entferne führende „/“ von Elementnamen
/etc/fstab
/etc/services
/etc/network/if-down.d/
/etc/network/if-down.d/upstart
/etc/network/if-down.d/avahi-autoipd
/etc/network/if-down.d/postfix
/etc/network/if-down.d/wpasupplicant
/etc/network/if-post-down.d/
/etc/network/if-post-down.d/wireless-tools
/etc/network/if-post-down.d/avahi-daemon
/etc/network/if-post-down.d/wpasupplicant
/etc/network/if-pre-up.d/
/etc/network/if-pre-up.d/wireless-tools
/etc/network/if-pre-up.d/wpasupplicant
/etc/network/if-pre-up.d/ethtool
/etc/network/if-up.d/
/etc/network/if-up.d/upstart
/etc/network/if-up.d/avahi-autoipd
/etc/network/if-up.d/postfix
/etc/network/if-up.d/avahi-daemon
/etc/network/if-up.d/openssh-server
/etc/network/if-up.d/wpasupplicant
/etc/network/if-up.d/ntpdate
/etc/network/if-up.d/ethtool
/etc/network/if-up.d/mountnfs
/etc/network/interfaces
/etc/network/interfaces.d/
/etc/network/interfaces_ok
/etc/network/run
tar: datei: Funktion stat fehlgeschlagen: Datei oder Verzeichnis nicht gefunden
tar: datei.lnk: Funktion stat fehlgeschlagen: Datei oder Verzeichnis nicht gefunden
tar: Beende mit Fehlerstatus aufgrund vorheriger Fehler
$>

Nur eine einzelne Datei (‚etc/hosts.allow‘) aus dem Archiv extrahieren:

$> tar cJf /root/etc-vor-DNS-install.tar.xz /etc
tar: Entferne führende „/“ von Elementnamen
$> ls -l
insgesamt 1040
-rw-r--r-- 1 root root 1063120 Aug  9 12:11 etc-vor-DNS-install.tar.xz
$> file etc-vor-DNS-install.tar.xz
etc-vor-DNS-install.tar.xz: XZ compressed data
$> tar tf etc-vor-DNS-install.tar.xz | grep hosts
etc/ghostscript/
etc/ghostscript/cidfmap.d/
etc/ghostscript/cidfmap.d/90gs-cjk-resource-gb1.conf
etc/ghostscript/cidfmap.d/90gs-cjk-resource-korea1.conf
etc/ghostscript/cidfmap.d/90gs-cjk-resource-japan2.conf
etc/ghostscript/cidfmap.d/90gs-cjk-resource-cns1.conf
etc/ghostscript/cidfmap.d/90gs-cjk-resource-japan1.conf
etc/ghostscript/fontmap.d/
etc/ghostscript/fontmap.d/10gsfonts.conf
etc/hosts.allow
etc/apache2/conf-enabled/other-vhosts-access-log.conf
etc/apache2/conf-available/other-vhosts-access-log.conf
etc/icinga2/conf.d/hosts/
etc/icinga2/conf.d/hosts/localhost.conf
etc/icinga2/conf.d/hosts/localhost/
etc/icinga2/conf.d/hosts/localhost/load.conf
etc/icinga2/conf.d/hosts/localhost/apt.conf
etc/icinga2/conf.d/hosts/localhost/ssh.conf
etc/icinga2/conf.d/hosts/localhost/swap.conf
etc/icinga2/conf.d/hosts/localhost/disk.conf
etc/icinga2/conf.d/hosts/localhost/users.conf
etc/icinga2/conf.d/hosts/localhost/http.conf
etc/icinga2/conf.d/hosts/localhost/icinga.conf
etc/icinga2/conf.d/hosts/localhost/procs.conf
etc/avahi/hosts
etc/ImageMagick-6/type-ghostscript.xml
etc/hosts.deny
$> ls -l
insgesamt 2412
-rw-r--r-- 1 root root 1402963 Aug  9 12:12 etc-2017-08-09_12-12.tgz
-rw-r--r-- 1 root root 1063120 Aug  9 12:11 etc-vor-DNS-install.tar.xz
$>
$>
$> # ACHTUNG: Die Datei muss mit relativen Pfad angegeben werden:
$> tar xvJf etc-vor-DNS-install.tar.xz etc/hosts.allow
etc/hosts.allow
$>
$> # Zur Kontrolle:
$> ls -l
insgesamt 2416
drwxr-xr-x 2 root root    4096 Aug  9 12:13 etc
-rw-r--r-- 1 root root 1402963 Aug  9 12:12 etc-2017-08-09_12-12.tgz
-rw-r--r-- 1 root root 1063120 Aug  9 12:11 etc-vor-DNS-install.tar.xz
$> ls -l etc
insgesamt 4
-rw-r--r-- 1 root root 451 Jul 10 10:29 hosts.allow
$>

Bandlaufwerke mit ‚tar‘ ansprechen

Neben der normalen Arbeitsweise mit Dateien kann ‚tar‘ auch direkt auf Blockebene arbeiten:

$> dd if=/dev/zero of=/root/my-virtual-tape.img bs=1M count=250
250+0 Datensätze ein
250+0 Datensätze aus
262144000 Bytes (262 MB) kopiert, 0,930163 s, 282 MB/s
$> tar cJf /root/my-virtual-tape.img /etc
tar: Entferne führende „/“ von Elementnamen
$>

Überprüfen, ob es funktioniert hat:

$> mount /root/my-virtual-tape.img /mnt
mount: Falscher Dateisystemtyp, ungültige Optionen, der
Superblock von /dev/loop0 ist beschädigt, fehlende
Kodierungsseite oder ein anderer Fehler

       Manchmal liefert das Systemprotokoll wertvolle Informationen –
       versuchen Sie  dmesg | tail  oder ähnlich
$>
$> dmesg | tail -5
[30064.249408] e1000: eth1 NIC Link is Down
[30064.249435] e1000 0000:00:08.0 eth1: Reset adapter
[30066.309668] e1000: eth1 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX
[30069.141566] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX
[35231.086612] loop: module loaded
$>

Alles klar: Dies macht ja auch absolut keinen Sinn, Blockebene bedeutet hier „kein Dateisystem vorhanden“.

Sprechen wir daher einfach das Device direkt an:

$> tar tJf /root/my-virtual-tape.img | grep fstab
etc/fstab~
etc/fstab
$>

Bitte auswendiglernen, welche Gerätedateien für Bandlaufwerke in Frage kommen (S. 227 oben):

  • /dev/st0 - erstes SCSI-Tape, rückspulend

  • /dev/nst0 - erstes SCSI-Tape, NICHT rückspulend

  • /dev/ft0 - erstes Floppy-Tape, rückspulend (Nicht verwechseln mit Floppy Disks: /dev/fd0)

  • /dev/nft0 - erstes Floppy-Tape, NICHT rückspulend

Welche Tools werden in dem Zusammenhang verwendet? Dies sind nur ein paar wichtige:

  • dd

  • dump/restore

  • tar

  • mt (zum Steuern der Bandlaufwerke)

Siehe dazu auch https://www.cyberciti.biz/faq/linux-tape-backup-with-mt-and-tar-command-howto/

Backups mit Linux

Siehe Seite 223 - 225

Was muss gesichert werden? Siehe hier:

$> ls -ld /home /etc /var
drwxr-xr-x 158 root root 12288 Aug  9 14:23 /etc
drwxr-xr-x  16 root root  4096 Jun 21 08:50 /home
drwxr-xr-x  13 root root  4096 Jun  9 10:15 /var

Zu den Backupstrategien:

  • Kosten

  • Wiederherstellbarkeit (Testfall, verschiedene Softwarelösungen einsetzten, KISS-Regel)

  • Off Side Backups (Gebäudebrand, Hochwasser)

Zu den Sicherungsarten siehe auch http://www.grundlagen-computer.de/backup/backup-strategien-inkrementell-differentiell-und-vollbackup

Netzwerkfähige Backuplösungen:

Das Werkzeug schlechthin: rsync

Siehe Seite 230 f, grundlegendes:

  • Entwickelt vom Samba-Team, um die Daten des PDC mit dem BDC zu replizieren (wie zu Zeiten zu Windows NT 4.0; PDC: Primary Domain Controller, BDC: Backup Domain Controller)

  • Beherrscht differentielle Datenübertragung (Delta-Algorithmus)

  • Unidirektionales Übertragen (keine Konfliktbehandlung, Bidirektional sind z.B. unison, osync)

  • Lokales oder netzwerkbasiertes Arbeiten ist möglich

  • Bei netzwerkbasiertem Arbeiten wird per Default SSH verwendet (damit ist der Schalter ‚-e‘ erst einmal überflüssig)

  • Beim Synchronisieren muss dem Quellverzeichnis ein endender Splash mitgegeben werden, sonst wird es als Unterverzeichnis auf das Ziel kopiert.

Das Ganze nun praktisch, fangen wir mit letzterer Problematik an:

$> id
uid=1000(tux) gid=1000(tux) Gruppen=1000(tux),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),108(netdev),113(lpadmin),115(scanner),121(bluetooth)
$> mkdir QUELLE ZIEL
$> cp -v /etc/host* QUELLE/
„/etc/host.conf“ -> „QUELLE/host.conf“
„/etc/hostname“ -> „QUELLE/hostname“
„/etc/hosts“ -> „QUELLE/hosts“
„/etc/hosts.allow“ -> „QUELLE/hosts.allow“
„/etc/hosts.deny“ -> „QUELLE/hosts.deny“
$> du -sh /usr/share/doc/bash
208K /usr/share/doc/bash
$> cp -r /usr/share/doc/bash QUELLE/
$> rsync -av QUELLE ZIEL
sending incremental file list
QUELLE/
QUELLE/host.conf
QUELLE/hostname
QUELLE/hosts
QUELLE/hosts.allow
QUELLE/hosts.deny
QUELLE/bash/
QUELLE/bash/CHANGES.gz
QUELLE/bash/COMPAT.gz
QUELLE/bash/INTRO.gz
QUELLE/bash/NEWS.gz
QUELLE/bash/POSIX.gz
QUELLE/bash/RBASH
QUELLE/bash/README
QUELLE/bash/README.Debian.gz
QUELLE/bash/README.abs-guide
QUELLE/bash/README.bash_completion.gz -> ../bash-completion/README.gz
QUELLE/bash/README.commands.gz
QUELLE/bash/changelog.Debian.gz
QUELLE/bash/copyright
QUELLE/bash/inputrc.arrows

sent 189,067 bytes  received 377 bytes  378,888.00 bytes/sec
total size is 187,741  speedup is 0.99
$>

Wir prüfen den Inhalt von ZIEL:

$> ls -F ZIEL
QUELLE/
$>

Hier ist genau dieser Fehler passiert, dass QUELLE als UNTERverzeichnis kopiert wurde, wir beheben es:

$> rm -rf ZIEL/*
$> rsync -av QUELLE/ ZIEL
sending incremental file list
./
host.conf
hostname
hosts
hosts.allow
hosts.deny
bash/
bash/CHANGES.gz
bash/COMPAT.gz
bash/INTRO.gz
bash/NEWS.gz
bash/POSIX.gz
bash/RBASH
bash/README
bash/README.Debian.gz
bash/README.abs-guide
bash/README.bash_completion.gz -> ../bash-completion/README.gz
bash/README.commands.gz
bash/changelog.Debian.gz
bash/copyright
bash/inputrc.arrows

sent 189,054 bytes  received 376 bytes  378,860.00 bytes/sec
total size is 187,741  speedup is 0.99
$> ls -F ZIEL
bash/  host.conf  hostname  hosts  hosts.allow  hosts.deny
$>

Übertragung mit Statusinfos nach Änderung einer Datei:

$> echo '10.20.30.123  mySuperServer' >> QUELLE/hosts
$> rsync -av --progress --stats QUELLE/ ZIEL
sending incremental file list
hosts
            427 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=17/21)

Number of files: 21 (reg: 18, dir: 2, link: 1)
Number of created files: 0
Number of deleted files: 0
Number of regular files transferred: 1
Total file size: 187,769 bytes
Total transferred file size: 427 bytes
Literal data: 427 bytes
Matched data: 0 bytes
File list size: 0
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 1,011
Total bytes received: 36

sent 1,011 bytes  received 36 bytes  2,094.00 bytes/sec
total size is 187,769  speedup is 179.34
$> tail -1 ZIEL/hosts
10.20.30.123  mySuperServer
$>

Wichtige Optionen:

  • archiv: Wenn möglich alle Eigenschaften erhalten: ‚-a‘

  • verbose: ‚-v‘

  • Statusinformationen: ‚–progress –stats‘

  • Unix-Hardlinks beachten (Inode-Nummern!): ‚-H‘

  • Komprimieren: ‚-z‘

  • Löschen, was nicht auf der sendenden Seite existiert (Master/Slave-Mirror): ‚–delete‘

  • Testlauf only: ‚-n‘ oder ‚–dry-run‘

Wir testen den Master/Slave-Mirror:

$> echo '###' >> QUELLE/hosts
$> \rm QUELLE/host.conf
$> rsync -av --progress --stats --delete --dry-run QUELLE/ ZIEL
sending incremental file list
deleting host.conf
./
hosts

Number of files: 20 (reg: 17, dir: 2, link: 1)
Number of created files: 0
Number of deleted files: 1 (reg: 1)
Number of regular files transferred: 1
Total file size: 187,746 bytes
Total transferred file size: 431 bytes
Literal data: 0 bytes
Matched data: 0 bytes
File list size: 0
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 535
Total bytes received: 43

sent 535 bytes  received 43 bytes  1,156.00 bytes/sec
total size is 187,746  speedup is 324.82 (DRY RUN)
$>

AUFGABE:

  • Mit ‚rsync‘ das auf dem Server liegende Verzeichnis ‚/etc‘ als root sichern. Dazu ‚PermitRootLogin‘ in der Datei ‚/etc/ssh/sshd_config‘ auf ‚yes‘ setzen.

  • ‚PermitRootLogin‘ wieder auf ‚no‘ setzen, einen dedizierte Benutzer anlegen, der das Verzeichnis /etc nur lesend sichern darf.

  • Das Sichern mit dem dedizierten Benutzer automatisierbar machen (Autologin)

Ein paar angetestete Lösungsvorschläge:

Zurücksetzen von ‚PermitRootLogin yes‘ auf ‚PermitRootLogin without-password‘:

root@d8:~# vi /etc/ssh/sshd_config
root@d8:~#
root@d8:~# grep --color PermitRootLogin /etc/ssh/sshd_config
PermitRootLogin without-password
#PermitRootLogin yes
# the setting of "PermitRootLogin without-password".
root@d8:~#
root@d8:~# systemctl restart sshd
root@d8:~#

Wir testen als einfacher Benutzer, welche Dateien nicht lesbar sind:

tux@d8:~$ cp -r /etc/ etc_bk 2> read.errors
tux@d8:~$
tux@d8:~$ cat read.errors
cp: „/etc/security/opasswd“ kann nicht zum Lesen geöffnet werden: Keine Berechtigung
cp: „/etc/.pwd.lock“ kann nicht zum Lesen geöffnet werden: Keine Berechtigung
cp: „/etc/subgid-“ kann nicht zum Lesen geöffnet werden: Keine Berechtigung
cp: „/etc/subuid-“ kann nicht zum Lesen geöffnet werden: Keine Berechtigung
cp: „/etc/passwd-“ kann nicht zum Lesen geöffnet werden: Keine Berechtigung
cp: „/etc/shadow-“ kann nicht zum Lesen geöffnet werden: Keine Berechtigung
cp: „/etc/group-“ kann nicht zum Lesen geöffnet werden: Keine Berechtigung
cp: „/etc/gshadow-“ kann nicht zum Lesen geöffnet werden: Keine Berechtigung
cp: „/etc/shadow“ kann nicht zum Lesen geöffnet werden: Keine Berechtigung
cp: „/etc/gshadow“ kann nicht zum Lesen geöffnet werden: Keine Berechtigung
cp: Zugriff auf „/etc/lvm/backup“ nicht möglich: Keine Berechtigung
cp: „/etc/at.deny“ kann nicht zum Lesen geöffnet werden: Keine Berechtigung
cp: „/etc/exim4/passwd.client“ kann nicht zum Lesen geöffnet werden: Keine Berechtigung
cp: „/etc/ssh/ssh_host_rsa_key“ kann nicht zum Lesen geöffnet werden: Keine Berechtigung
cp: „/etc/ssh/ssh_host_dsa_key“ kann nicht zum Lesen geöffnet werden: Keine Berechtigung
cp: Zugriff auf „/etc/ssl/private“ nicht möglich: Keine Berechtigung
cp: „/etc/iscsi/iscsid.conf“ kann nicht zum Lesen geöffnet werden: Keine Berechtigung
cp: „/etc/sudoers.d/README“ kann nicht zum Lesen geöffnet werden: Keine Berechtigung
cp: „/etc/sudoers“ kann nicht zum Lesen geöffnet werden: Keine Berechtigung
tux@d8:~$

Kein Wunder, sehen wir uns mal drei solcher problematischen Dateien an:

tux@d8:~$ ls -l /etc/sudoers /etc/shadow /etc/ssh/ssh_host_rsa_key
-rw-r----- 1 root shadow  965 Aug 10 13:39 /etc/shadow
-rw------- 1 root root   1675 Sep 21  2016 /etc/ssh/ssh_host_rsa_key
-r--r----- 1 root root    714 Sep 22  2016 /etc/sudoers
tux@d8:~$

Vor dem Ändern der Dateireichte von /etc (was generell nicht empfehlenswert ist!!), legen wir als root ein Backup an:

root@d8:~# cp -a /etc/ /root/etc_orig
root@d8:~#
root@d8:~# getfacl /etc
getfacl: Entferne führende '/' von absoluten Pfadnamen
# file: etc
# owner: root
# group: root
user::rwx
group::r-x
other::r-x
root@d8:~#
root@d8:~# setfacl -R -m u:tux:r-x /etc
root@d8:~#
root@d8:~# getfacl /etc
getfacl: Entferne führende '/' von absoluten Pfadnamen
# file: etc
# owner: root
# group: root
user::rwx
user:tux:r-x
group::r-x
mask::r-x
other::r-x
root@d8:~# su - tux
tux@d8:~$
tux@d8:~$ cp -a /etc /home/tux/etc_von_tux_kopiert
tux@d8:~$
tux@d8:~$ du -s etc_*
4004 etc_bk
4076 etc_von_tux_kopiert
tux@d8:~$ exit

Damit konnte der Nutzer zwar alles kopieren, leider aber akzepiert der ssh-Daemon nicht einmal diese kleine, via File ACLs vorgenommene Rechteerweiterung. Beim Loginversuch des Nutzers kommt die Meldung „Read from socket failed: Connection reset by peer“. Daher müssen wir die ACLs für den Benutzer ‚tux‘ auf dem Server später wieder entfernen!

Auf dem Client-Rechner wird nun das Backup-Zielverzeichnis angelegt, die nächsten Schritte sind dann allerdings auch noch nicht erfolgreich:

$> mkdir backup-10.44.30.126
$>
$> rsync -n -a --progress --stats 10.44.30.126:/etc /home/tux/backup-10.44.30.126/
Connection closed by 10.44.30.126
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: error in rsync protocol data stream (code 12) at io.c(226) [Receiver=3.1.1]
$>

URSACHE: Es läuft zwar auf dem Server der sshd (Port 22), aber das Programm ‚rsync‘ fehlte dort noch. Nach der Installation mit ‚apt-get install rsync‘:

$> rsync -n -a --progress --stats 10.44.30.126:/etc /home/tux/backup-10.44.30.126/Read from socket failed: Connection reset by peer
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: error in rsync protocol data stream (code 12) at io.c(226) [Receiver=3.1.1]
$>

Das Rechteerweiterungs-Problem:

$> ssh tester@10.44.30.126
Read from socket failed: Connection reset by peer
$>

Die Meldung „Read from socket failed: Connection reset by peer“ weist auf ein größeres Problem hin. Im Syslog lesen wir „WARNING: UNPROTECTED PRIVATE KEY FILE!“. Daher entfernen wir die ACLs für den Benutzer ‚tux‘ auf dem Server wieder mit:

$> setfacl -R -x  u:tux: /etc

Danach ist ein Login per ssh wieder problemlos möglich. Lösungsmöglichkeiten, wenn am grundlegenden Konzept festgehalten werden soll, dass sich der Client die Daten selber ziehen soll:

  • Die Daten als ‚root‘ kopieren (Wobei aus Sicherheitsgründen nur mit einem eigenen, clientseitigen Schlüsselpaar operiert werden sollte. Dank der sinnvollen Voreinstellung in der ‚/etc/ssh/sshd_config‘, die da ‚PermitRootLogin without-password‘ lautet, ist sowieso kein Benutzername/Passwortpaar-Login möglich).

  • Ein Szenario mit einem dedizierten Benutzer umsetzten, wie es für die ähnlich gelagerte Software ‚rdiff-backup‘ unter https://www.howtoforge.com/linux_rdiff_backup beschrieben ist.

Zum Daemon-Mode von ‚rsync‘ siehe S. 232, hier ein paar wichtige Merkmale

  • Die Option ‚–deamon‘ aktiviert den standalone Daemon Mode.

  • Konfigdatei: /etc/rsync.conf

  • Port: 873 (unverschlüsselt!)

  • Besonderheit beim clientseitigen Zugriff: Zwei Doppelpunkte (‚::‘) trennen Server- und Sharename:

$> rsync ftp.halifax.rwth-aachen.de::debian-cd/
--------------------------------------------------------------
The features compression (-z) and checksums (-c) are disabled.

More information about this server is available via HTTP:
http://ftp.halifax.rwth-aachen.de/
--------------------------------------------------------------

drwxr-xr-x             98 2017/06/18 06:44:09 .
lrwxrwxrwx              5 2017/06/18 04:47:23 current
lrwxrwxrwx             10 2017/06/18 04:47:30 current-live
-rw-r--r--         12,475 2017/06/18 06:12:01 ls-lR.gz
drwxr-xr-x             30 2017/06/18 02:28:17 9.0.0-live
drwxr-xr-x            150 2017/06/18 04:36:46 9.0.0
drwxr-xr-x             20 2005/05/23 18:50:12 project
$>

Ein Kopiervorgang sieht dann z.B. so aus:

$> rsync ftp.halifax.rwth-aachen.de::debian-cd/project/build/9.0.0/source /tmp
--------------------------------------------------------------
The features compression (-z) and checksums (-c) are disabled.

More information about this server is available via HTTP:
http://ftp.halifax.rwth-aachen.de/
--------------------------------------------------------------

$> echo $?
0
$>
$> date
Do 10. Aug 14:46:10 CEST 2017
$> ls -l /tmp/source
-rw-r--r-- 1 tester tester 4 Aug 10 14:45 /tmp/source
$> cat /tmp/source
dvd
$>

Einrichtung eines rsync-Servers

Datum: 2017-08-11

OS: Debian 8.9 (Jessie)

Meist ist ‚rsync‘ schon vorinstalliert, das Paket bringt eine Beispielkonfiguration mit:

$> cp /usr/share/doc/rsync/examples/
logrotate.conf.rsync  rsyncd.conf
$> cp /usr/share/doc/rsync/examples/rsyncd.conf /etc

Damit haben wir die Datei an die richtige Stelle kopiert und wollen sie erstmal nur inspizieren:

$> grep -v '^\s*#\|^$' /etc/rsyncd.conf
[ftp]
     comment = public archive
     path = /var/www/pub
     use chroot = yes
     lock file = /var/lock/rsyncd
     read only = yes
     list = yes
     uid = nobody
     gid = nogroup
     strict modes = yes
     ignore errors = no
     ignore nonreadable = yes
     transfer logging = no
     timeout = 600
     refuse options = checksum dry-run
     dont compress = *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz

Dies ist der originale, aktive Inhalt, den wir nicht ändern brauchen. Wir legen nur den Freigabeordner und eine Testdatei an:

$> mkdir -p /var/www/pub
$> echo Willkommen... > /var/www/pub/willkommen.txt

Und kontrollieren und starten nun den rsync-Daemon, zuerst aber prüfen wir, ob er vielleicht schon läuft:

$> pgrep -a rsync
$> lsof -i:873
$> lsof -i:22
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd      655 root    3u  IPv4  13744      0t0  TCP *:ssh (LISTEN)
sshd      655 root    4u  IPv6  13746      0t0  TCP *:ssh (LISTEN)
ssh     27160  tux    3u  IPv4 175023      0t0  TCP 10.44.30.220:41954->lux.ptsa.de:ssh (ESTABLISHED)
ssh     30660  tux    3u  IPv4 207026      0t0  TCP 10.44.30.220:42243->lux.ptsa.de:ssh (ESTABLISHED)
$>

Er läuft natürlich noch nicht, wir versuchen ihn, manuell zu starten:

$> rsync --daemon
$> pgrep -a rsync
31429 rsync --daemon
$> lsof -i:873
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
rsync   31429 root    4u  IPv4 218618      0t0  TCP *:rsync (LISTEN)
rsync   31429 root    5u  IPv6 218619      0t0  TCP *:rsync (LISTEN)
$>

Das Starten mittels rsync --daemon war erfolgreich, der Dienst läuft nun. Nun schauen wir nach, was der Server zu bieten hat:

$> rsync localhost::
ftp                  public archive
$>

Mit der zuletzt ausgeführten Zeile haben wir einen direkten Zugriff auf den Server durchgeführt, der erst einmal nur die verfügbaren Shares auflistet.

Nun folgt ein richtiger Kopiervorgang:

$> mkdir /tmp/ftp
$> rsync -av --stats --progress localhost::ftp/ /tmp/ftp/
receiving incremental file list
./
willkommen.txt
             14 100%   13.67kB/s    0:00:00 (xfr#1, to-chk=0/2)

Number of files: 2 (reg: 1, dir: 1)
Number of created files: 1 (reg: 1)
Number of deleted files: 0
Number of regular files transferred: 1
Total file size: 14 bytes
Total transferred file size: 14 bytes
Literal data: 14 bytes
Matched data: 0 bytes
File list size: 64
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 50
Total bytes received: 143

sent 50 bytes  received 143 bytes  386.00 bytes/sec
total size is 14  speedup is 0.07
$>
$> ls -lisa /tmp/ftp/
insgesamt 12
1832170 4 drwxr-xr-x  2 root root 4096 Aug 11 10:57 .
1831425 4 drwxrwxrwt 17 root root 4096 Aug 11 11:09 ..
1832193 4 -rw-r--r--  1 root root   14 Aug 11 10:57 willkommen.txt
$>

Testen, ob der endende Slash auch bei der Nutzung des rsync-Daemons erforderlich ist:

$> rm -fv /tmp/ftp/*
„/tmp/ftp/willkommen.txt“ wurde entfernt
$> rsync -av --stats --progress localhost::ftp /tmp/ftp
receiving incremental file list
./
willkommen.txt
             14 100%   13.67kB/s    0:00:00 (xfr#1, to-chk=0/2)

Number of files: 2 (reg: 1, dir: 1)
Number of created files: 1 (reg: 1)
Number of deleted files: 0
Number of regular files transferred: 1
Total file size: 14 bytes
Total transferred file size: 14 bytes
Literal data: 14 bytes
Matched data: 0 bytes
File list size: 64
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 50
Total bytes received: 143

sent 50 bytes  received 143 bytes  386.00 bytes/sec
total size is 14  speedup is 0.07
$>
$> ls -lisa /tmp/ftp/
insgesamt 12
1832170 4 drwxr-xr-x  2 root root 4096 Aug 11 10:57 .
1831425 4 drwxrwxrwt 17 root root 4096 Aug 11 11:11 ..
1832193 4 -rw-r--r--  1 root root   14 Aug 11 10:57 willkommen.txt
$>

Wir sehen, dass hierbei der endende Slash bei Quelle NICHT erforderlich ist.

Im Gegensatz zu direkten Verzeichnisoperationen:

$> rm -fv /tmp/ftp/*
„/tmp/ftp/willkommen.txt“ wurde entfernt
$> ls -lisa /tmp/ftp/
insgesamt 8
1832170 4 drwxr-xr-x  2 root root 4096 Aug 11 11:14 .
1831425 4 drwxrwxrwt 17 root root 4096 Aug 11 11:11 ..
$> rsync -av /var/www/pub /tmp/ftp/
sending incremental file list
pub/
pub/willkommen.txt

sent 143 bytes  received 39 bytes  364.00 bytes/sec
total size is 14  speedup is 0.08
$> ls -lisa /tmp/ftp/
insgesamt 12
1832170 4 drwxr-xr-x  3 root root 4096 Aug 11 11:14 .
1831425 4 drwxrwxrwt 17 root root 4096 Aug 11 11:15 ..
1832193 4 drwxr-xr-x  2 root root 4096 Aug 11 10:57 pub

Dies ist allerding nicht das, was wir wollten! Das Verzeichnis ‚pub‘ ist ein Unterverzeichnis von /tmp/ftp geworden!

Immer, wenn wir mit ‚rsync‘ Verzeichnisse direkt ansprechen, muss der endende Slash an den Namen des Quell-Verzeichnisses angehängt werden:

$> rm -fvr /tmp/ftp/*
„/tmp/ftp/pub/willkommen.txt“ wurde entfernt
Verzeichnis wurde entfernt: „/tmp/ftp/pub“
$>
$> rsync -av /var/www/pub/ /tmp/ftp/
sending incremental file list
./
willkommen.txt

sent 131 bytes  received 38 bytes  338.00 bytes/sec
total size is 14  speedup is 0.08
$> ls -lisa /tmp/ftp/
insgesamt 12
1832170 4 drwxr-xr-x  2 root root 4096 Aug 11 10:57 .
1831425 4 drwxrwxrwt 17 root root 4096 Aug 11 11:30 ..
1832193 4 -rw-r--r--  1 root root   14 Aug 11 10:57 willkommen.txt

Nun haben wir wieder eine Ordnersynchronisation vorliegen, wie es meistens gewünscht ist.

Erforschen wir nun, ob der manuell gestartete rsync-Daemon als Background-Job der Shell läuft:

$> jobs
$> ps aux | grep rsync
root     31429  0.0  0.0   4424  2012 ?        Ss   11:02   0:00 rsync --daemon
root     32396  0.0  0.1   4576  2192 pts/7    D+   11:35   0:00 grep rsync
$>

Nein - man sieht besonders gut mittels der Kommandozeile ps aux | grep rsync, dass es kein Job ist. Es handelt sich eben um einen echten Daemon (siehe das Fragezeichen (‚?‘) in der Spalte TTY, was bedeutet, dass der Prozess keine Verbindung zu einem Terminal hat).

Daher können wir den Daemon nicht einfach mittels der Jobkontrolle beenden, sondern so:

$> killall rsync
$> killall rsync
rsync: Kein Prozess gefunden
$> rsync localhost::
rsync: failed to connect to localhost (::1): Connection refused (111)
rsync: failed to connect to localhost (127.0.0.1): Connection refused (111)
rsync error: error in socket IO (code 10) at clientserver.c(128) [Receiver=3.1.1]
$>

Leider gibt es laut man-Page von rsync (Abschnitt „DAEMON OPTIONS“) keinen Schalter, der das Logging im Vordergrund möglich macht. Mit Hilfe der Gerätedatei, die fürs eigene, aktuelle Terminal verantworlich zeichnet, gelingt es aber:

$> tty
/dev/pts/7
$>
$>
$> rsync --daemon --no-detach --log-file=/dev/pts/7
2017/08/11 11:50:36 [388] rsyncd version 3.1.1 starting, listening on port 873
2017/08/11 11:50:43 [393] connect from jessie (10.44.30.250)
2017/08/11 11:50:43 [393] module-list request from jessie (10.44.30.250)
  -- STRG+C gedrückt --
^C2017/08/11 11:50:53 [388] rsync error: received SIGINT, SIGTERM, or SIGHUP (code 20) at rsync.c(632) [Receiver=3.1.1]
$>

Wir können hierbei einen entfernten Zugriff beobachten, der mittels der Kommandozeile rsync 10.44.30.220:: ausgelöst wurde. Mit STRG + C lässt sich der Daemon dann wieder beenden.

Abschließend soll nun der Daemon über den systemeigenen init-Dienst ‚systemd‘ gestartet werden.

Zuerst interessiert uns hierbei, ob Debian überhaupt eine Unit-Datei für den rsync-Daemon mit ausliefert. Die erste Kommandozeile gibt allerdings keine Informationen aus, weil der Service nicht läuft, d.h. systemctl start rsync noch nicht ausgeführt wurde. Daher müssen wir systemctl list-unit-files verwenden:

$> systemctl list-units | grep rsync
$>
$> systemctl list-unit-files | grep rsync
rsync.service       disabled
$>

Nun Starten und Aktivieren wir den Daemon:

$> systemctl start rsync
$> systemctl list-units | grep rsync
rsync.service       loaded active running   fast remote file copy program daemon
$>
$> ps aux | grep rsync
root       527  0.0  0.1   4424  2316 ?        Ss   11:54   0:00 /usr/bin/rsync --daemon --no-detach
root       529  0.0  0.1   4576  2340 pts/7    S+   11:54   0:00 grep rsync
$> systemctl status rsync
● rsync.service - fast remote file copy program daemon
   Loaded: loaded (/lib/systemd/system/rsync.service; disabled)
   Active: active (running) since Fr 2017-08-11 11:54:25 CEST; 29s ago
 Main PID: 527 (rsync)
   CGroup: /system.slice/rsync.service
           └─527 /usr/bin/rsync --daemon --no-detach

Aug 11 11:54:25 Gast1 systemd[1]: Started fast remote file copy program daemon.
Aug 11 11:54:25 Gast1 rsyncd[527]: rsyncd version 3.1.1 starting, listening on port 873
$> systemctl enable rsync
Synchronizing state for rsync.service with sysvinit using update-rc.d...
Executing /usr/sbin/update-rc.d rsync defaults
Executing /usr/sbin/update-rc.d rsync enable
$>

Erweiterung um ein Writeable-Share

Wir fügen dazu ans Ende der Datei ‚/etc/rsyncd.conf‘ die folgenden Zeilen an:

 [backup]
   path = /srv/backup
   comment = Writeable Share for Backups
   read only = no
   auth users = tux
   secrets file = /etc/rsyncd.secrets
   uid = nobody
   gid = nogroup


Als nächstes legen wir die Datei an, die als Benutzerdatenbank dienen soll: ::

 $> echo 'tux:12345' > /etc/rsyncd.secrets

Danach müssen die Rechte angepasst werden, sonst erlaubt der Daemon keinen Zugriff auf das neue Share: ::

  $> chmod -v 600 /etc/rsyncd.*
  Modus von „/etc/rsyncd.conf“ als 0600 (rw-------) erhalten
  Modus von „/etc/rsyncd.secrets“ als 0600 (rw-------) erhalten
  $>
  $> ls -l /etc/rsyncd.secrets
  -rw------- 1 root root 10 Aug 11 12:09 /etc/rsyncd.secrets

Das Freigabeverzeichnis darf natürlich auch nicht fehlen:

$> mkdir -p -m 777 /srv/backup

Abschließend starten wir den Daemon neu und beginnen mit den Tests:

$> systemctl restart rsync
$>
$> rsync -v /etc/services   tux@localhost::backup
Password:
services

sent 19,689 bytes  received 35 bytes  3,034.46 bytes/sec
total size is 19,605  speedup is 0.99
$>

Um das Ganze automatisieren zu können, setzen wir die Variable ‚RSYNC_PASSWORD‘:

$> export RSYNC_PASSWORD="12345"
$>
$> rsync -v /etc/fstab   tux@localhost::backup
fstab

sent 1,345 bytes  received 35 bytes  2,760.00 bytes/sec
total size is 1,258  speedup is 0.91
$>
$> ls -ltrc /srv/backup/
insgesamt 48
-rw-r--r-- 1 root   root        6 Aug 11 12:15 hostname
-rw-r--r-- 1 root   root       27 Aug 11 12:15 host.conf
-rw-r--r-- 1 root   root      399 Aug 11 12:15 hosts
-rw-r--r-- 1 root   root      765 Aug 11 12:15 hosts.deny
-rw-r--r-- 1 root   root      451 Aug 11 12:15 hosts.allow
-rw-r--r-- 1 nobody nogroup  3316 Aug 11 12:24 passwd
-rw-r--r-- 1 nobody nogroup 19605 Aug 11 12:26 services
-rw-r--r-- 1 nobody nogroup  1258 Aug 11 12:28 fstab
$>

Anstelle das Passwort in dieser Variable zu speichern, kann es der Client auch aus einer Datei auslesen, die dann mittels --password-file= übergeben wird.

Happy syncing…