Ob Rsync, Integrit oder Aide – alle diese Werkzeuge beobachten den Verzeichnisbaum des Systems und schlagen Alarm, sobald sie dort unbefugte Veränderungen bemerken.
Der Datenbestand auf Speichermedien hält nicht ewig [1]. Es drohen Verluste durch natürliche Alterung, Defekte des Speichermediums, aber auch durch Fehler oder gar Einbrüche ins System. Daher zählt es zu den Aufgaben jedes verantwortungsvollen Systemadministrators, zu prüfen, ob das Speichermedium mit dem Datenbestand intakt ist und ob es darauf eine Änderung gab.
Um Schreibzugriffe auf ein Speichermedium oder Verzeichnis vollständig zu verhindern, nutzt man entweder ein Nur-Lese-Medium wie eine DVD oder aktiviert einen Schreibschutz, etwa bei einer SD-Speicherkarte. Versierte Benutzer binden das entsprechende Verzeichnis nur lesbar ein oder setzen für ausgewählte Dateien den Schreibschutz (siehe Kasten “Dateisysteme nur lesbar einbinden”).
Dateisysteme nur lesbar einbinden
Die Datei /etc/fstab listet alle Partitionen auf, die das System in den Verzeichnisbaum einbindet. In der vierten Spalte jeder Zeile lässt sich mit ro (“read-only”) oder rw (“read-write”) bestimmen, ob man auf der Partition nur lesen oder auch schreiben darf (Listing 1).
Als Alternative dazu bietet sich das Immutable-Flag an [15]. Dieses Flag gehört zu den erweiterten Attributen eines Verzeichniseintrags, die jedoch nur wenige Linux-Anwender kennen und auch in der Praxis nutzen. Kommen darüber hinaus File-based Access Control Lists (FACLs) ins Spiel, etwa im Zusammenhang mit SELinux [16] unter Red Hat, Fedora oder CentOS, dann lassen sich Zugriffsrechte noch genauer festlegen.
Bei gesetztem Immutable-Flag lässt sich der Eintrag im Verzeichnis nicht mehr verändern – die Datei oder das Verzeichnis ist dann schreibgeschützt. Jeden Versuch, die Daten zu ändern, weist das Betriebssystem ab. Nur der Benutzer root kann dieses Flag für einzelne Benutzer setzen und wieder aufheben. Ersteres gelingt mittels chattr +i Datei, Letzteres durch chattr -i Datei. Das i in der vierten Zeile von Listing 2 zeigt an, dass die Datei beispiel.txt das Immutable-Flag trägt.
Listing 1
$ grep daten /etc/fstab /dev/sdb1 /daten ext4 ro 0 0
Listing 2
# touch beispiel.txt # chattr +i beispiel.txt # lsattr beispiel.txt ----i--------e-- beispiel.txt # echo "# Kommentar" >> beispiel.txt bash: datei: Keine Berechtigung # chattr -i beispiel.txt
TIPP
Bei den BSD-Varianten und beim Mac heißt das Pendant zu Chattr chflags. Unter Solaris deckt das Kommando chmod die Funktion ab; Ähnliches gilt für lsattr, dessen Funktion bei Solaris eine Erweiterung des Ls-Kommandos abdeckt.
Eine Änderung des Datenbestands kann sowohl inhaltlich in Form von Ergänzungen und Löschungen erfolgen als auch die Zugriffsrechte und Freigaben umfassen. Das Hinzufügen, Umbenennen, Verschieben und Löschen von Dateien, Verzeichnissen und (symbolischen) Links gehört ebenfalls dazu. Ihr Anliegen als Systemadministrator besteht darin, nachzuvollziehen, zu welchem Zeitpunkt welche Änderungen erfolgten, welcher Benutzer das veranlasste und – bei Fehlern – wie Sie das wieder reparieren.
Das Erkennen von Veränderungen im Vorfeld samt einer passenden Reaktion auf einen solchen Vorfall würde den Rahmen dieses Beitrags sprengen. Im Folgenden steht daher im Fokus, wie Sie nachträglich solche Veränderungen feststellen. Exemplarisch zeigen wir das Vorgehen anhand von Rsync und Integrit.
Das Gezeigte lässt sich prinzipiell auf andere Werkzeuge übertragen, wie beispielsweise Tripwire, Aide und Iwatch, unterscheidet sich aber im Aufwand beim Erstellen der Konfiguration und beim Auswerten.
Rsync
Liegen Ihnen zwei Datenbestände vor – etwa ein Original und eine Datensicherung – hilft Ihnen bereits das Bordmittel Rsync [2], etwaige Unterschiede zwischen den beiden Datenbeständen festzustellen. Rsync dient eigentlich dem Synchronisieren zweier Verzeichnisse und gibt dabei im Terminal aus, welche Einträge sich unterscheiden.
Listing 3 demonstriert das anhand der zwei Verzeichnisse original/ und kopie/. Jedes davon enthält drei ursprünglich identische Dateien. Im Verzeichnis kopie/ haben wir jedoch Daten geändert. Dabei ließen wir intakt.txt unverändert, setzten bei irgendwas.txt ein Ausführungsbit für die Gruppe und ergänzten nochwas.txt um zusätzlichen Inhalt.
Listing 3
$ ls -la {original,kopie}
kopie:
insgesamt 16
drwxr-xr-x 2 frank frank 4096 Jun 1 14:28 .
drwxr-xr-x 4 frank frank 4096 Jun 1 14:25 ..
-rw-r-xr-- 1 frank frank 15 Jun 1 16:36 intakt.txt
-rw-r-xr-- 1 frank frank 10 Jun 1 14:28 irgendwas.txt
-rw-r--r-- 1 frank frank 24 Jun 1 14:30 nochwas.txt
original:
insgesamt 16
drwxr-xr-x 2 frank frank 4096 Jun 1 14:26 .
drwxr-xr-x 4 frank frank 4096 Jun 1 14:25 ..
-rw-r-xr-- 1 frank frank 15 Jun 1 16:36 intakt.txt
-rw-r--r-- 1 frank frank 10 Jun 1 14:26 irgendwas.txt
-rw-r--r-- 1 frank frank 10 Jun 1 14:26 nochwas.txt
$ rsync -anv --out-format="[%t]:%o:%f:Last Modified %M" kopie/* original
sending incremental file list
[2016/06/01 16:40:25]:send:kopie/intakt.txt:Last Modified 2016/06/01-16:36:14
[2016/06/01 16:40:25]:send:kopie/irgendwas.txt:Last Modified 2016/06/01-14:28:49
[2016/06/01 16:40:25]:send:kopie/nochwas.txt:Last Modified 2016/06/01-14:30:23
sent 137 bytes received 25 bytes 324.00 bytes/sec
total size is 34 speedup is 0.21 (DRY RUN)
Rsync ermöglicht über den Schalter -n (Langoption --dry-run) einen Trockendurchlauf. Diesen “Betriebsmodus” machen Sie sich hier zunutze, um die Veränderungen zu ermitteln, ohne tatsächlich eine Synchronisation zwischen den beiden Verzeichnissen auszulösen. Rsync vergleicht beide Ordner mittels -a (Langoption --archive) bezüglich der Namen der vorhandenen Einträge, deren Größe und der gesetzten Zugriffsrechte.
Ohne weitere Schalter gibt sich Rsync etwas schmallippig. Erst mithilfe von -v (Langoption --verbose) gibt es die Details der erfolgten Transaktionen preis. Die Option v lässt sich gegebenenfalls mehrfach setzen, um die Menge der Details zu steigern. Der zusätzliche Schalter --out-format legt fest, wie Rsync die Details zum Datentransfer kommentiert.
Dabei gibt %t den Zeitstempel des Transfers aus, %o die auszuführende Aktion (Senden oder Empfangen), %f den Dateinamen und %M den Zeitstempel der letzten Änderung (siehe Tabelle “Rsync-Formatkürzel” [3]). Weitere Hilfe zu Rsync bieten ein Grundlagenartikel aus LU 04/2006 [4] sowie die Rsync-Manpage.
Rsync-Formatkürzel
| Kürzel | Bedeutung |
|---|---|
%a |
IP-Adresse der Gegenstelle |
%b |
Anzahl tatsächlich übertragener Bytes |
%B |
Zugriffsrechte der Datei (etwa rwxrwxrwt) |
%c |
Gesamtgröße der Blockprüfsummen für Basisdatei (gesendet) |
%f |
Dateiname (lange Form auf dem Sender, kein “/” nach Verzeichnis) |
%G |
GID der Datei (dezimal) oder DEFAULT |
%h |
Hostname des Remote-Rechners |
%i |
Punkteliste der aktualisierten Dateieigenschaften |
%l |
Dateilänge in Byte |
%L |
Text -> SYMLINK, => HARDLINK oder leer |
%m |
Modulname |
%M |
Datum und Uhrzeit der letzten Dateiänderung |
%n |
Dateiname (Kurzform, “/” nach Verzeichnis) |
%o |
Operation (send, recv oder del) |
%p |
PID der Rsync-Sitzung |
%P |
Modulpfad |
%t |
Aktuelles Datum und Uhrzeit |
%u |
Benutzername (authentifiziert) oder leerer Text |
%U |
UID der Datei (dezimal) |
Da es ausschließlich um die modifizierten Einträge geht, hilft Ihnen auch die Kombination aus rsync -i (Langform --info) und dem Filterwerkzeug grep. Aus der detaillierten, aber immer noch kompakten Darstellung von Rsync filtern Sie damit nur diejenigen Informationen heraus, die Änderungen beinhalten; alle anderen Zeilen entfallen.
Die Ausgabe umfasst eine Zeile pro Datei, die jeweils ein > einleitet. Die darauf folgenden zehn Zeichen repräsentieren die Eigenschaften, anhand derer Rsync die beiden Einträge miteinander vergleicht. Steht dort jeweils ein Punkt, liegt kein Unterschied der betreffenden Eigenschaft vor, bei Buchstaben gab es jedoch eine Veränderung. Dabei steht c beispielsweise für “checksum” (Prüfsumme oder Hash-Wert), s für “size” (Größe) und <p für “permissions” (Zugriffsrechte).
Als Nächstes filtern Sie mittels grep und eines passenden regulären Ausdrucks [5] die relevanten Zeilen aus der Ausgabe. Der in Listing 4 genutzte Ausdruck passt auf Zeichenfolgen, die mit einem f beginnen, gefolgt von einem beliebigen Zeichen, auf das entweder ein Punkt und tp, st sowie ein Punkt oder drei Punkte folgen. Die beiden letzten Zeilen enthalten die erzielten Treffer.
Listing 4
$ rsync -acniv kopie/* original | grep --color -E "f.(\.tp|st\.|\.\.\.)" >f..tp..... irgendwas.txt >fcst...... nochwas.txt
Mit dem im Rsync-Aufruf verwendeten Schalter -c hat es eine besondere Bewandtnis: Er veranlasst das Programm, die Dateien nicht nur anhand ihrer Größe zu vergleichen, sondern zusätzlich aus dem Dateiinhalt eine Prüfsumme in Form eines Hash-Werts zu errechnen (siehe Kasten “Hash-Wert”). Somit kommen Sie auch Modifikationen am Inhalt auf die Spur, bei denen die Größe beibehalten und zudem nachträglich der Zeitstempel auf den Ursprungswert zurückgesetzt wurde.
Hash-Wert
Hash-Funktionen zählen zu den kryptografischen Verfahren. Sie dienen unter anderem dazu, Prüfsummen zu berechnen. Unter Linux stehen Ihnen dazu beispielsweise die Werkzeuge md5sum (MD5 mit 128 Bit), sha1sum (SHA1 mit 160 Bit), sha224sum (SHA2 mit 224 Bit), sha256sum (SHA2 mit 256 Bit), sha384sum (SHA2 mit 384 Bit) und sha512sum (SHA2 mit 512 Bit) zur Verfügung. Die Ziffernfolge bezeichnet üblicherweise die Länge des resultierenden Hash-Werts in Bits, wobei MD5 und SHA1 eine Ausnahme darstellen. Verfügt Ihr System über keines der genannten Programme, greifen Sie stattdessen auf opensslc zurück, das ebenfalls Hashwerte berechnet.
Inhaltliche Gleichheit
Um schnell herauszufinden, ob zwei Dateien inhaltlich übereinstimmen, helfen Ihnen die Linux-Werkzeuge cmp, comm, diff und sdiff nur bedingt weiter. Sie arbeiten zeilen-, byte- oder blockweise und arbeiten mitunter recht langsam. Stattdessen nutzt das Shell-Skript aus Listing 5 in den Zeilen 3 und 4 das Verfahren SHA256 – MD5 und SHA1 gelten als nicht mehr wirklich sicher.
Listing 5
#! /bin/bash
# Hash-Werte erzeugen
hashValue1=$(sha256sum $1 | awk '{ print $1 }')
hashValue2=$(sha256sum $2 | awk '{ print $1 }')
# Hash-Werte vergleichen
if [ $(echo -e "$hashValue1\n$hashValue2" | uniq | wc -l) == 1 ]; then
echo "$1 und $2 sind identisch."
exit 0
fi
echo "$1 und $2 sind nicht identisch."
exit 1
Das kompaktere Listing 6 löst das Problem mit weniger Rechenaufwand, bedarf aber eines tieferen Verständnisses der Shell-Programmierung. Sie rufen es mit zwei Dateien als Parameter auf. Entsprechend den Unix-Gepflogenheiten dienen als Rückgabewert in Zeile 3 der Wert 0 für Gleichheit und in Zeile 5 der Wert 1 für Ungleichheit.
Listing 6
#! /bin/bash
if [ "$(sha256sum $1 | awk '{ print $1 }')" == "$(sha256sum $2 | awk '{ print $1 }')" ]; then
echo "$1 und $2 sind identisch."; exit 0
fi
echo "$1 und $2 sind nicht identisch."
exit 1
Von Rsync zum HIDS
Die Veränderungen zwischen Verzeichnissen mittels Rsync für große Datenmengen zu prüfen, empfiehlt sich eher nicht: Es verursacht einerseits einen recht hohen Aufwand, andererseits birgt es die Gefahr der Unvollständigkeit. Findige Entwickler bauten daher Kombinationswerkzeuge, mit denen sich dieser Schritt stärker automatisieren lässt. Solche Tools dienen grundsätzlich zur lokalen Einbruchserkennung auf einem System und lassen sich unter dem Begriff hostbasierte Einbruchserkennungssysteme (“host-based intrusion detection systems”, HIDS) zusammenfassen [6].
Die einzelnen HIDS fallen in Sachen Funktionsumfang sehr unterschiedlich aus. Sie verfügen über Routinen zum Erkennen von Dateiveränderungen, zum Aufspüren von Rootkits, zur Detektion und Analyse verdächtiger Netzwerkpakete und -schnittstellen sowie von “mysteriösen” Prozessen. Einige davon lassen sich nur auf dem lokalen System nutzen, andere auch für das Überwachen entfernter Systeme. Die Tabelle “HIDS” gibt einen groben Überblick zu den Werkzeugen und deren Funktionsumfang.
HIDS
| Werkzeug | Dateiveränderungen | Rootkits | Netzwerk | Prozesse | Remote |
|---|---|---|---|---|---|
dpkg |
x | – | – | – | – |
rpm |
x | – | – | – | – |
integrit |
x | – | – | – | – |
tripwire |
x | – | – | – | – |
tiger |
x | x | x | x | – |
rkhunter |
x | x | – | – | – |
samhain |
x | – | – | – | x |
debsums |
x | – | – | – | – |
chkrootkit |
– | x | – | x | – |
aide |
x | x | – | – | – |
fcheck |
x | – | – | – | – |
stealth(1) |
x | x | – | – | – |
ossec |
x | x | x | – | x |
unhide |
– | – | – | x | – |
suricata |
– | – | x | – | – |
inotify |
x | – | – | – | – |
| (1) Ssh-based Trust Enforcement Acquired through a Locally Trusted Host | |||||
Bitte beachten Sie, dass Inotify ausschließlich in dem Moment eine Information ausgibt, in dem es eine Veränderung feststellt. Alle anderen Programme teilen das erst nachträglich mit. Bei Dpkg, Dlocate und Debsums handelt es sich um Werkzeuge zur Paketverwaltung, die es nur bei Debian und seinen Derivaten gibt. Sie entsprechen im engeren Sinne nicht einem HIDS und prüfen nur, ob die installierten Dateien aus einem Paket noch unverändert vorliegen (Listing 7). Gleiches gilt für Rpm aus Fedora und OpenSuse.
Listing 7
$ dpkg -V openssh-server ??5?????? /usr/lib/tmpfiles.d/sshd.conf
Veränderungen
Für die verzeichnisbasierte Analyse auf Veränderungen im Dateisystem hat sich ein mehrstufiges Schema herausgebildet. Diesem Schema folgen unter anderem Integrit, Tripwire, Samhain und Aide. Nach einer Bestandsaufnahme fungiert das jeweilige Werkzeug quasi als digitale Petze für die später entdeckten Unterschiede.
In einem ersten Schritt analysiert das Programm das von Ihnen vorab spezifizierte Verzeichnis. Dazu erzeugt es eine Art Schnappschuss für den aktuellen Zustand. Für jeden Eintrag im Verzeichnis legt es einen Eintrag in seiner internen Datenbank an und merkt sich unter anderem den Dateinamen, das Erstell- und Änderungsdatum, die Zugriffs- und Benutzerrechte sowie den Inhalt.
Letzteren speichert es nicht jedoch vollständig als Kopie, sondern berechnet nur einen Hash-Wert über den Inhalt. Das ist mit einer sehr hohen Wahrscheinlichkeit eindeutig und zudem mit einem überschaubaren Zeit- und Rechenaufwand verbunden. Bei der Berechnung des Hashes kommt derzeit vielfach noch MD5 oder eine Variante des Secure Hash Algorithms (SHA) zum Einsatz.
Der zweite Schritt folgt später und beinhaltet den Abgleich des aktuellen Verzeichniszustands mit dem im ersten Schritt erzeugten Schnappschuss. Das System registriert alle Änderungen zwischen den beiden Zuständen und teilt sie Ihnen mit. Das kann über die Standardausgabe geschehen, aber auch via E-Mail, Jabber (XMPP) oder als Eintrag in einer Protokolldatei.
Auf eine entsprechende Warnung sollten Sie unverzüglich angemessen reagieren, etwa mit dem Rückspielen einer vorhergehenden Datensicherung. Beide Schritte verursachen nennenswerte I/O-Last auf dem Speichermedium – führen Sie sie also nicht unbedingt in Hochlastphasen durch.
Integrit
Integrit beziehen Sie entweder über die Paketverwaltung des Systems (etwa unter Debian, Ubuntu, Linux Mint und Raspbian) oder direkt von der Projektseite [7]. Nach der Installation läuft Integrit nicht ständig als Daemon im Hintergrund, was wertvolle Ressourcen belegen würde, sondern Sie rufen es jeweils explizit für eine Analyse mit administrativen Rechten auf.
Damit das Programm auch weiß, worauf es einen Blick werfen soll, spezifizieren Sie einen konkreten Arbeitsauftrag in einer Konfigurationsdatei. Deren Namen wählen Sie frei – in unserem Beispiel verwenden wir integrit.conf (Listing 8). Speichern Sie die Datei am besten im Verzeichnis /root/integrit/ oder /etc/integrit/^, und setzen Sie die Zugriffsrechte so, dass nicht jeder neugierige Benutzer daran herumpfuschen darf.
Drei Zeilen benötigt Integrit in der Konfigurationsdatei – den Pfad zur Bestandsdatenbank (Zeile 1), den Pfad zur Datenbank mit dem aktuellen Zustand (Zeile 2) und das zu überwachende Verzeichnis (Zeile 3). Für den Pfad und Namen der Datenbanken gilt dasselbe wie für die Konfigurationsdatei – Name und Pfad bestimmen Sie selbst und passen sie an die lokalen Gegebenheiten an.
Listing 8
known=/root/integrit/known.cdb current=/root/integrit/current.cdb root=/usr/bin
Im nächsten Schritt initialisieren Sie die Bestandsdatenbank. Dazu rufen Sie Integrit mit den drei Schaltern -u für “update”, -v für “verbose” und -C Konfiguration auf (Listing 9).
Listing 9
# integrit -uv -C integrit.conf integrit: ---- integrit, version 4.1 ----------------- integrit: output : human-readable integrit: conf file : integrit.conf integrit: known db : /root/integrit/known.cdb integrit: current db : /root/integrit/current.cdb integrit: root : /daten/original integrit: do check : no integrit: do update : yes integrit: current-state db RMD160 -------------- integrit: a6fb12c69b773038f03987b7130ae07c0846fe02 /root/integrit/current.cdb
Wie in der Konfigurationsdatei zuvor festgelegt, hat sich Integrit den aktuellen Zustand in der Datei current.cdb gemerkt. Diesen Zustand kopieren Sie jetzt mittels cp current.cdb known.cdb als Bestand in die Datei known.cdb. Diese Datei benutzt Integrit jetzt als Referenz, um Veränderungen zu erkennen.
Als Nächstes nehmen Sie an den Einträgen im beobachteten Verzeichnis Änderungen vor. Im vorliegenden Beispiel haben wir Inhalte ergänzt und die Benutzerrechte erweitert. Im nächsten Schritt lassen wir Integrit den Zustand des Verzeichnisses mit dem zuvor registrierten Bestand vergleichen. Dazu rufen wir es mit dem Schalter -c für “changes” auf sowie wiederum mit -C, gefolgt vom Namen der Konfigurationsdatei (Listing 10).
Listing 10
# integrit -c -C integrit.conf integrit: ---- integrit, version 4.1 ----------------- integrit: output : human-readable integrit: conf file : integrit.conf integrit: known db : /root/integrit/known.cdb integrit: current db : /root/integrit/current.cdb integrit: root : /daten/original integrit: do check : yes integrit: do update : no changed: /daten/original/datei2 s(9c1185a5c5e9fc54612808977ee8f548b2258d31:b17ae69f081657c9f0b5e810affbce44b1f7593f) changed: /daten/original/datei2 p(0644:0654) m(20160602-175113:20160606-194552) c(20160602-175113:20160606-194610) integrit: not doing update, so no check for missing files
Das Ergebnis des Vergleichs fördert mehrere Veränderungen zutage. Im letzten Block von Zeile 10 markiert das “s” (“size”) zunächst eine Größenänderung der Datei /daten/original/datei2, die auch die beiden unterschiedlichen Hash-Werte in Klammern daneben verdeutlichen. Zusätzlich dazu steht im letzten Block von Zeile 11 ein “p” (“permissions”), da wir die Benutzerrechte von 0644 auf 0654 geändert haben. Der Buchstabe “m” (“modification date”) markiert den Zeitpunkt der Änderung, den 6. Juni 2016 um 19:45 Uhr.
In der letzten Zeile lässt Integrit Sie noch wissen, dass es die Bestandsdatenbank nicht im selben Zug aktualisiert, sondern nur auf Änderungen prüft. Möchten Sie die Änderungen auch in den Bestand übernehmen, benutzen Sie im Aufruf den Schalter -u (“update”).
Lastvergleich
Jedes Werkzeug generiert eine bestimmte Last, um seine Aufgabe zu erfüllen. Auf produktiv genutzten Rechnern darf der Integritätscheck keinesfalls das System überlasten. Daher mussten sich Rsync und Integrit in einem Test unter normalen Alltagsbedingungen beweisen und einen auf einer internen SSD gespeicherten Datenbestand von 16 GByte erfassen und analysieren.
Dabei ließ sich beobachten, dass Rsync für eine Prüfung auf Gleichheit (wie in Listing 3 beschrieben) im Durchschnitt etwa ein bis zwei Sekunden benötigt. Soll Rsync beim Check derselben Daten auch noch die Prüfsummen beachten (siehe Listing 4), dann vergeht etwa eine Minute. Setzen Sie andere Datenträger ein, die beispielsweise über USB oder Netzwerk angebunden sind, müssen Sie mehr Zeit einplanen. Gleiches gilt für SATA-Festplatten, Speicherkarten und CDs/DVDs.
Integrit hingegen benötigt zum Initialisieren der Datenbank (siehe Listing 9) etwa 150 Sekunden und schreibt dabei 24 MByte Daten. Das Prüfen auf Veränderungen wie in Listing 10 dauert im Durchschnitt ähnlich lang. Für das zusätzliche Aktualisieren der Datenbank müssen Sie fünf bis zehn Prozent mehr Zeit einplanen.
Verwandte Werkzeuge
Dateisysteme wie ZFS [8] und Btrfs [9] verfügen über automatische Integritätsprüfungen. Liest das System Inhalte von einem Speichermedium aus, berechnet es dabei automatisch eine Prüfsumme für den Inhalt des Datenblocks.
ZFS vergleicht diese mit der Prüfsumme des identischen Datenblocks auf einer Spiegelung (“Clone”). Stimmen die Prüfsummen nicht überein, geht ZFS davon aus, dass der Inhalt des Originaldatenblocks beschädigt wurde, und meldet einen Lesefehler. Sofern das System das Problem nicht automatisch reparieren soll, entscheiden Sie danach manuell, ob es diesen Datenblock durch den Inhalt der Spiegelung ersetzt [10].
Btrfs errechnet für eine zyklische Redundanzprüfung zu jedem Block eine Prüfsumme (CRC32). So erkennt das System Bitfehler und korrigiert diese in Kombination mit einem RAID automatisch, sofern der Spiegel intakt ist. Setzen Sie als Dateisystem Ext3 oder Ext4 ein, helfen die Smartmon-Tools [11] und das Programm Badblocks (aus dem Paket e2fsprogs). Wie Sie diese beiden Programme einsetzen, erklärt ein Artikel aus LU 08/2010 [12].
Gefahren lauern jedoch nicht nur im Dateisystem, sondern auch in Prozessen und Datenströmen. An dieser Stelle kommen zum Beispiel Unhide [13] und Suricata [14] ins Spiel: Mit ihnen überwachen Sie Prozesse und Netzwerkpakete auf bösartiges Verhalten. Unhide beobachtet die laufenden Prozesse und versucht diejenigen zu finden, die sich vor der Ausgabe des Kommandos Ps verstecken. Dazu vergleicht es unter anderem die Einträge im Proc-Filesystem mit den laufenden Prozessen.
Ausblick
Keines der hier vorgestellten Werkzeuge vermag Veränderungen in Dateisystemen zu verhindern. Sie helfen Ihnen aber, solche Veränderungen sicher zu erkennen. So haben Sie die Chance, auf verdächtige Modifikationen zu reagieren und das System wieder in den korrekten Zustand zu versetzen. Binden Sie die Programme als Daemon im Hintergrund oder als Cron-Job ein, entfällt mitunter eine Menge mühevoller Handarbeit.
Das Auswerten der Alarme erfordert jedoch etwas Geschick: Bedenken Sie, dass die Systeme häufig “false positives” melden. Ein recht typischer Fall wäre etwa die Überwachung der Verzeichnisse /bin/ und /usr/bin/. Installieren Sie Software nach oder aktualisieren diese, ändert sich mit hoher Wahrscheinlichkeit deren Inhalt – auch das bekommen die HIDS mit und schlagen an. Ein genauerer Blick auf die Reports bleibt Ihnen also nicht erspart.
Der Autor
Frank Hofmann (http://www.efho.de) arbeitet in Berlin im Büro 2.0 als Dienstleister mit Spezialisierung auf Druck und Satz. Seit 2008 koordiniert er das Regionaltreffen der LUGs der Region Berlin-Brandenburg. Er ist zudem Koautor des Debian-Paketmanagement-Buchs (http://www.dpmb.org).
Infos
[1] Ratgeber Langzeitarchivierung: http://www.tecchannel.de/a/ratgeber-langzeitarchivierung-dateiformate-und-speichermedien,2039663,6
[2] Rsync: https://rsync.samba.org
[3] Howto zu Rsync: https://www.ostc.de/howtos/rsync-HOWTO.html
[4] Dateiabgleich mit Rsync: Heike Jurzik, “Synchroner Datenstrom”, LU 04/2006, S. 92, https://www.linux-community.de/9850
[5] Regular Expressions: Frank Hofmann, “Schnipseljagd”, LU 09/2011, S. 84, https://www.linux-community.de/24091
[6] HIDS: https://en.wikipedia.org/wiki/Host-based_intrusion_detection_system
[7] Integrit: https://github.com/integrit/integrit
[8] ZFS on Linux: http://zfsonlinux.org
[9] Btrfs: https://btrfs.wiki.kernel.org
[10] “Using the ZFS scrub feature to verify the integrity of your storage”: http://prefetch.net/blog/index.php/2011/10/15/using-the-zfs-scrub-feature-to-verify-the-integrity-of-your-storage
[11] Smartmon-Tools: http://smartmontools.sourceforge.net
[12] Integrität gespeicherter Daten sicherstellen: Klaus Schmidt, Thomas Leichtenstern, “Schau genau!”, LU 08/2010, S. 74, https://www.linux-community.de/21374
[13] Unhide: http://www.unhide-forensics.info
[14] Suricata: https://oisf.net/suricata
[15] “Linux Password Trick With Immutable Bit Using chattr Command”: http://www.cyberciti.biz/tips/linux-password-trick.html
[16] SELinux: https://selinuxproject.org





