parallel rsync

parallel rsync

Große Datenmengen lokal via rsync kopieren

Folgende Ausgangssituation: Aufgrund warum auch immer muss eine große Datenmenge von einem Verzeichnis in ein anderes kopiert werden. Rahmenbedingung: Die Daten sollen so lange wie möglich weiterhin zugreifbar sein. Die Lösung: Kopie via rsync. Denn rsync überträgt ab dem zweiten Lauf nur noch die Änderungen an den Daten. Das macht man so lange bis es kaum noch Änderungen gibt. Danach stoppt man die Dienste, ein letzter rsync Lauf, Austausch der Verzeichnisnamen, Dienste wieder starten und fertig.

GroupWise POA via rsync kopieren

Ein sehr großes POA eines GroupWise Systems muss an einen anderen Ort kopiert werden. Der konkrete Auslöser in diesem Fall: Das darunter liegende NSS-Dateisystem soll von 32 nach 64 Bit migriert werden. Rahmenbedingung: Der Emailserver soll nur so kurz wie irgendwie möglich unterbrochen werden. Die Lösung: Kopie via rsync. Denn rsync überträgt ab dem zweiten Lauf nur noch die Änderungen an den Daten. Das macht man so lange bis es kaum noch Änderungen gibt. Danach stoppt man die GroupWise Dienste, ein letzter rsync Lauf, Austausch der Verzeichnisnamen, Dienste wieder starten und fertig.

Ok, die Ausgangsbasis mag eine andere sein. Aber unterm Strich liest sich das eine gleich wie das andere, oder? Zusammengefasst soll eine große Datenmenge lokal in ein anderes Verzeichnis verschoben werden. Bei näherer Betrachtung dieser Daten fallen mir zwei Dinge auf: Es handelt sich um mehrere Terabyte und diese sind in sehr, sehr vielen kleinen Dateien gespeichert. Also all das was man braucht wenn man schnell fertig sein will -Ironie Ende-. Nein, ernsthaft. Das ist gar nicht gut. Das klingt nach sehr, sehr langer Laufzeit.

Warum rsync und kein einfacher cp ist ja bereits durch. Mein Problem ist so lange bekomme ich keine Downtime genehmigt. Also rsync gestartet. Der läuft auch rasch an und macht sich ans Werk. Die zu kopierende Dateiliste wird erstellt, das dauert halt etwas. Aber dann geht die Kopiererei auch schon los. Die ersten Megabyte und auch ziemlich rasch die ersten Gigabyte erscheinen im Ziellaufwerk. Apropos rsync: Die Geschwindigkeit die rsync lokal erreichen kann ist limitiert durch die Geschwindigkeit der verfügbaren Platten. Eine VM mit einem All-Flash-Array im Hintergrund. Ok, das rennt. Sollte man meinen. Denn irgendwie tut der rsync gerade nichts mehr: Die Meldungen bleiben stehen, es werden kaum noch Daten kopiert. Das ist alles so langsam und träge. Ein Blick in top: rsync will Unmengen an RAM, macht CPU Last ohne Ende während der Disk-IO gegen 0 geht. An der Stelle habe ich auch schon mal erlebt, dass der Verfügbare RAM durchaus ausgehen kann sofern hier nur wenig Reserven da sind. Ein Blick ins dmesg verrät einem sofort ob der gefürchtete OOM-Killer unterwegs war...

Aber was kann man tun? Die erste Suche war ohne Ergebnis. Die Geschwindigkeit richtet sich nach dem lokalen Plattendurchsatz. Das passt aber hier nicht ganz ins Bild. Also mal die zu kopierenden Daten betrachtet. Der allergrößte Brocken liegt bei GroupWise im Ordner offiles. Direkt unterhalb von diesem gibt es 256 weitere Unterordner in denen dann die eigentlichen Daten liegen. Die Terabyte an Daten liegen also größtenteils in 256 Ordner verteilt die jeweils nur wenige Gigabyte groß sind. Na damit lässt sich doch was anfangen. Also was kann man tun?

GNU parallel

GNU parallel

Im Sinne von "teile und herrsche" (https://de.wikipedia.org/wiki/Teile-und-herrsche-Verfahren) kann man unlösbare Probleme lösen indem man sie in kleinere Teilprobleme zerlegt. Die Lösung dieser Unterschritte ergibt in Summe die Gesamtlösung.

In diesem Falle lässt sich der offiles Ordner in seine 256 "Einzelteile" zerlegen. Jeder dieser Ordner ist überschaubar bzgl. der Größe und die Anzahl der Dateien. Und damit es schneller geht werden diese Einzelteile anstatt allesamt einer nach dem anderen parallel abgearbeitet. Ich habe mich auf gleichzeitig 8 Verzeichnisse festgelegt: Das hat die Hardware super weggesteckt und sogar keiner der GroupWise Anwender hat sich beklagt, dass die Performance während eines Kopiervorgangs schlechter geworden wäre. Hier heißt es ggf. erstmals ausprobieren und sachte heranzutasten was ein geeigneter Wert für gleichzeitige Kopiervorgänge wäre.

Mit etwas geschickter bash Programmierung wäre es kein Thema die parallelen Jobs selbst zu verwalten. Aber wozu? Mit "parallel" aus den GNU Tools gibt es ein praktisches Werkzeug welches einem genau diese Arbeit abnimmt. Leider fehlt es vielen Linux Distributionen in den verfügbaren Paketen. Jedoch ist es aus den Quellen rasch übersetzt. Diese, sowie eine ausführliche Anleitung, finden sich auf der Homepage des GNU Projektes: https://www.gnu.org/software/parallel/.

 

Meine Lösung

Meine Lösung ist ein kurzes bash Skript welches im Kopf die beiden NSS Verzeichnisse als Quell- und Zielverzeichnis gelistet haben. Im Quellverzeichnis wird zunächst nach sämtlichen offiles Ordnern gesucht - ich habe hier Server stehen auf denen mehr als nur ein POA installiert sind. Im nächsten Schritt wird alles außer den offiles kopiert. Im folgenden Schritt werden anschließend alle offiles Unterordner via parallel aufgerufenen rsync Befehlen kopiert.

Bisher habe ich die Kopieraktion abgebrochen da nichts mehr vorwärts ging. Jetzt war der Erstsync innerhalb eines Tages fertig, die folgenden Läufe brauchten nur wenige Stunden. Vor der eigentlichen Umstellung wurde gerade nochmals eine knappe Stunde für den sync benötigt. Das passt, die Stunde Downtime im GroupWise bekomme ich im Rahmen der üblichen Wartungsfenster locker den Kunden gegenüber argumentiert.

NSS Kenner mögen jetzt fragen was mit den Trustees ist. Eine übliche GroupWise Installation legt keine Trustess an, somit gäbe es auch keine zu kopieren. Und falls doch: Ein nss /help zeigt den aktuellen Status und mittels nss /ListXaatrNWmetadata lässt sich eine xml-Datei aktivieren in der sämtliche Trustess gelistet sind. Diese Datei wird von rsync, sofern vorhanden, einfach mitkopiert. So können die Trustess auf dem Ziellaufwerk übernommen werden. Im Novell / MicroFocus / NetIQ NSS Migration Guide ist diese Variante mit rsync ausführlich beschrieben: https://www.novell.com/documentation/open-enterprise-server-2018/stor_nss_lx/data/t42v5hiqjnzn.html#t42v6m36om8w. Ich habe diesen Ansatz lediglich parallelisiert.

Und hier nun das von mir verwendete Hilfsskript. NSS Trustees werden zumindest erwähnt - ich habe halt wie bereits gesagt bei GroupWise keine im Einsatz. Somit sind die Trustee Blöcke rein informativer Natur.

#!/bin/bash

#
# Ein GroupWise NSS rsync Skript ;-) Mal kucken ob es damit besser läuft...
#

#
# 2019-12-13, Gehirn-Mag.Net: Init... (ob der Wochentag was aussagen soll?)
#

# sehr frei nach: https://www.novell.com/documentation/open-enterprise-server-2018/stor_nss_lx/data/t42v5hiqjnzn.html#t42v6m36om8w


# Source und Dest - wichtig der / am Ende!
SDIR=/media/nss/GROUPWISE/
DDIR=/media/nss/GROUPWISE64/
THREADS=8
#DRYRUN=--dry-run
LDIR=/tmp/gwrsync
START="$(date)"


# Logdir vorbereiten, alte Logs löschen
mkdir -pv $LDIR
find $LDIR -type f | xargs -n 50 rm -v

# NSS zumindest mal Trustee Status ausgeben
echo "nss /ListXattrNWmetadata <-- Sollte an sein ;-)"
nss /help | grep -A1 Xattr

# offiles Ordner suchen
cd $SDIR
find . -maxdepth 2 -type d -name "offiles" | cut -d/ -f2- > /tmp/gwrsync.exclude

# Alles außer offiles
rsync                                                       \\
   $DRYRUN                                                  \\
   -vv -r -h -lXHtS --stats --delete                        \\
   --exclude-from /tmp/gwrsync.exclude                      \\
   --exclude ._NETWARE/                                     \\
   --exclude '~DFSINFO.8-P'                                 \\
   --log-file=${LDIR}/wo-offiles.log                        \\
   $SDIR $DDIR

# Offiles
echo "--------------------------------------------------------------------"
echo "OFFILES"
while read FOLDER; do
   echo $FOLDER
   PO=$(echo $FOLDER | rev | cut -d'/' -f2 | rev)
   find ${SDIR}${FOLDER} -mindepth 1 -maxdepth 1 -type d |  \\
      parallel -j${THREADS}                                 \\
      rsync $DRYRUN -vv -r -h -lXHtS --stats --delete       \\
      --log-file=${LDIR}/{#}-{%}-${PO}-{/}.log              \\
      {} ${DDIR}${FOLDER}
done < <(cat /tmp/gwrsync.exclude)

# Trustees kopieren - ich hab halt keine ;-)

# Hinweis auf NSS wieder an ;-)
echo -e "\\n\\nnss ListXattrNWmetadata ggf. noch deaktivieren ;-)"
echo $START
date
exit

 

Warum das Ganze?

Der Auslöser war die schlichte Tatsache, dass auf dem GroupWise Server als Dateisystem für die Daten NSS verwendet wird - in der 32 Bit Version. Jetzt gibt es keine direkte Migrationsmöglichkeit von NSS 32 auf 64 Bit. Der offizielle Weg von MircoFocus sieht vor, dass man die Daten entsprechend kopiert. Das kann das NSS Migrationstool machen oder man kopiert mit Linux Bordmitteln. Ich habe mich für die Linux-Variante entscheiden. Und da mir das zu lange dauerte via parallel nachgeholfen.

Letztendlich zeigt diese Lösung, dass man sicherlich nicht alle, aber einige Kopierjobs parallel abgearbeitet deutlich beschleunigen kann. Im Falle GroupWise gibt es einige Verzeichnisse und noch ein paar mehr Dateien. Und es gibt den offiles Ordner. Dieser Ansatz lässt sich auf viele andere, große Kopierjobs, erfolgreich übertragen.

fail2ban Monitoring

fail2ban Monitoring

fail2ban

Fail2ban ist ein nützliches Werkzeug und ich habe ja schon einmal darüber geschrieben: fail2ban und dynamische IP-Adressen. Heute mal ein etwas anderes Thema welches mich beruflich ebenfalls häufig bewegt: Monitoring.

Also wie würde man vorgehen wenn man einen Check für Nagios, Icinga2, Shinken, ... braucht? Man sucht in der Suchmaschine des Vertrauens oder bemüht eine der Plugin-Sammlungen im Internet. Doch halt, ein Blick ins Repository von fail2ban verrät das ein passender Check bereits mitgebracht wird: https://github.com/fail2ban/fail2ban/tree/master/files/nagios.

Das ist ja mal richtig super 🙂 Was mir jetzt weniger gefällt ist die Ausgabe der Performance-Daten:

CHECK FAIL2BAN ACTIVITY - CRITICAL - 6 detected jails with 195 current banned IP(s) | apache.currentBannedIP=0 dovecot.currentBannedIP=0 fail2ban.currentBannedIP=0 postfix.currentBannedIP=0 roundcube.currentBannedIP=0 sshd.currentBannedIP=195

Viele Monitoringinstallationen die ich betreue verwenden zur Visuallisierung rrd basierte Systeme wie zum Beispiel PNP4Nagios (http://docs.pnp4nagios.org/start). Das ist jetzt weniger toll, da sich bei mir durchaus auch mal die Anzahl der jails ändern kann. Zweitens sind mir diese Daten eigentlich egal, viel interessanter finde ich die Anzahl der Jails sowie die aktuell geblockten IPs. Das täte mir reichen.

Naja, dann also mal in den Quellcode rein geschaut. Die passende Stelle sollte sich finden lassen. Ist in Python geschrieben. Das ist jetzt nicht so meins, aber so eine kleine Änderung/Ergänzung bekomme ich allemal hin. Ich hab ja schon das ein oder andere kleinere Skript in Python geschrieben. Doch halt, Moment: Der Nagios Check ist in perl geschrieben. Das ist jetzt allerdings sehr meins. Kurz den Code angelesen und tada, fertig. Nun in einen Pull Request gepackt und fertig: https://github.com/fail2ban/fail2ban/pull/2732.

Meine Ausgabe sieht jetzt so aus:

CHECK FAIL2BAN ACTIVITY - CRITICAL - 6 detected jails with 195 current banned IP(s) | jails=6 currentBannedIp=195

Die alte Ausgabe möchtest Du zusätzlich haben? Das geht natürlich ebenfalls:

CHECK FAIL2BAN ACTIVITY - CRITICAL - 6 detected jails with 195 current banned IP(s) | jails=6 currentBannedIp=195 apache.currentBannedIP=0 dovecot.currentBannedIP=0 fail2ban.currentBannedIP=0 postfix.currentBannedIP=0 roundcube.currentBannedIP=0 sshd.currentBannedIP=195

Oder man lässt alles so wie es ist, das geht selbstverständlich weiterhin 😛

Hier der Link zu meiner Variante von check_fail2ban: https://github.com/SteScho/fail2ban/tree/master/files/nagios.

RBLs von Spamhaus: Irgendwie anders herum…

RBLs von Spamhaus: Irgendwie anders herum…

Jeder der eine Emailadresse hat oder sogar einen eigenen Mailserver betreibt weiß es: UCE oder Spam ist einfach nur lästig... Zeit was dagegen zu tun. Blacklists sollen es sein. Dumm nur, wenn die von Spamhaus nicht mag...Doch der Reihe nach, was ist passiert? Folgendes Szenario: Ein kleiner Server steht irgendwo bei einem der großen Hoster im Schrank. Funktioniert alles wunderbar. Nur wenn man eine Testabfrage an Spamhaus senden will passiert rein gar nichts:

# host 2.0.0.127.zen.spamhaus.org d.gns.spamhaus.org
;; connection timed out; no servers could be reached

Hm, seltsam... Eigentlich hat man mit einer anderen Antwort gerechnet. Der gleiche Befehl am heimischen PC oder über eine andere Internetverbindung ausgeführt liefert hingegen das erwartete Ergebnis:

# host 2.0.0.127.zen.spamhaus.org d.gns.spamhaus.org
Using domain server:
Name: d.gns.spamhaus.org
Address: 194.68.44.148#53
Aliases: 

2.0.0.127.zen.spamhaus.org has address 127.0.0.2
2.0.0.127.zen.spamhaus.org has address 127.0.0.10
2.0.0.127.zen.spamhaus.org has address 127.0.0.4

Jetzt wird es seltsam. Also mal das Internet nach Rat gefragt 😉

Ursachensuche

Das war nach kurzer Suche rasch erledigt. Spamhaus sperrt komplette Internetbereiche vorm Zugriff auf Ihre Listen wenn Sie der Meinung sind, dass Server in diesem Segment "böse Dinge" tun. Ich lasse an der Stelle die Links die ich dazu gefunden habe mal weg - denke die haben in dem Artikel nichts zu suchen da unterm Strich jeder Serverhoster von diese Problem betroffen sein könnte. Es sollten sich genügend Erfahrungen von anderen Benutzern vom Internet zu diesem Thema finden lassen. Oder man macht den obigen Schnelltest und überzeugt sich selbst 😉

Erschwerte Rahmenbedingungen

Naja, was wird man wohl tun können bzw. müssen? Also mal der Reihe nach alles durch probiert:

  • host 2.0.0.127.zen.spamhaus.org liefert einen Timeout. Wenn das gleich bei einem neu aufgesetzten Server passiert steht in der resolv.conf wohl noch der bzw. die DNS-Server vom Hoster drin. Dann stehen diese wohl in einem Netzwerksegment das von Spamhaus gesperrt wurde.
  • host 2.0.0.127.zen.spamhaus.org d.gns.spamhaus.org funktioniert ebenfalls nicht? Dann ist von der Sperre auch noch die Adresse des eigenen Rechners betroffen.
  • Naja, man kann ja schnell einen anderen Nameserver benutzen. Gibt ja z.B. die beiden frei erreichbaren von dem großen Suchmaschinenanbieter mit dem großen "G" im Anfang vom Namen: host 2.0.0.127.zen.spamhaus.org 8.8.8.8. Hm, ebenfalls timeout? Die etwa auch gesperrt? Ja, das mag prinzipiell schon sein. Auf der anderen Seite sperren einige Betreiber von DNS-Servern auch den Zugriff auf RBLs über ihre Systeme. So oder so, unterm Strich war das schon wieder nichts. Und auf der anderen Seite: Bei dem Betreiber dieser DNS-Systeme weiß man ja, dass der sein Geld damit verdient, dass er Besucherprofile von einem über die gestellten DNS-Anfragen kreiert. Zusätzlich bleibt hier die spannende Frage ob man das überhaupt so will.

Annäherung an die Lösung

Also muss irgendein DNS-Server her der frei verfügbar ist und idealerweise nichts oder nur kaum etwas protokolliert. Und ideaerweise keine Profile oder sonst was erzeugt. Auch hier sollten sich im Internet Server finden lassen wie z.B. die von DigitalCourage oder OpenDNS. Es gibt mehr davon wie man zunächst vielleicht denken mag mit vielen verschiedenen Beweggründen. Mir soll es reicht sein, ich habe eine Alternative gefunden:

# host 2.0.0.127.zen.spamhaus.org 208.67.222.220
Using domain server:
Name: 208.67.222.220
Address: 208.67.222.220#53
Aliases: 

2.0.0.127.zen.spamhaus.org has address 127.0.0.2
2.0.0.127.zen.spamhaus.org has address 127.0.0.4
2.0.0.127.zen.spamhaus.org has address 127.0.0.10

Und siehe da: Es funktioniert! Ok, jetzt könnte ich diese Server in der resolv.conf meines Linuxservers kurz eintragen. Doch halt, das würde alle DNS-Anfragen über diese Server leiten. Eigentlich schon wieder nicht das was ich haben wollte. Also nochmals anders.

Ein eigener DNS-Server

Genau, das ist doch die Lösung: Ein eigener DNS-Server. Im Caching-Modus. Also übers Internet nicht erreichbar, nur via localhost und macht für mich meine DNS-Anfragen. Löst diese direkt ohne irgendwelche Abhängigkeiten auf, legt das alles noch im Cache ab. Und, damit Spamhaus funktioniert, eine Forwarding-Zone für zen.spamhaus.org. eingerichtet.

Das kann man mit so gut wie jedem DNS-Server machen. An der Stelle mag ich selbst unbound: Der ist klein, schlank, in allen gängigen Distributionen bereits enthalten und richtig fix konfiguriert. Ok, ggf. muss man sich kurz schlau machen wie man den bei seiner eigenen Distribution letztendlich auch verwendet. Bei einigen wird es reichen die resolv.conf anzupassen, bei ein paar anderen wird man ggf. systemd-resolve vorher noch deaktivieren müssen. Das sollte sich aber im Handbuch bzw. der Paketbeschreibung zu unbound in der jeweiligen Distribution rasch ermitteln lassen.

Nachdem das erledigt ist und erste Testauflösungen via unbound funktionieren wird noch rasch dessen Konfig um diese Zeilen erweitert (die DNS-Server ggf. sinngemäß anpassen):

# Spamhaus
forward-zone:
  name: "zen.spamhaus.org."
  forward-addr: 46.182.19.48	# DigitalCourage
  forward-addr: 208.67.222.220	# OpenDNS
  forward-addr: 208.67.222.222	# OpenDNS

Unbound neugestartet und schon, oh wunder, ist sogar Spamhaus vom eigenen Server aus erreichbar 🙂 Angenehmer Seiteneffekt dieser Lösung: Über die DNS-Server von Dritten laufen nur Teilmengen der eigentlichen Anfrageflut. Für den größten Teil bleibe ich, dank eigenem caching-Proxy, mein eigener Herr.