Datenbestände auf Veränderungen prüfen

Aus LinuxUser 05/2019

Datenbestände auf Veränderungen prüfen

© Mike Flippo, 123RF

Revision

Mit minimalem Aufwand prüfen Sie auf der Kommandozeile, ob Ihr Datenbestand unverändert geblieben ist beziehungsweise wann und wie er sich verändert hat.

Es gibt diverse Möglichkeiten, um Veränderungen in einem archivierten Datenbestand auf die Spur zu kommen. Dabei genügt es jedoch nicht, lediglich den einzelnen Eintrag und dessen Dateigröße zu überprüfen. Beides greift deutlich zu kurz, um auch subtilere Modifikationen zu erkennen.

Bereits in LU 09/2016 widmeten wir diesem Thema einen ausführlichen Beitrag [1]. Damals lag der Fokus auf dem Einbinden von Dateisystemen ohne Schreibrecht, der effektiven Benutzung von Rsync, Diff/Sdiff sowie dem Verifizieren der Inhalte bereits installierter Software-Pakete mittels Dpkg. Den Abschluss bildete die Vorstellung des Host Intrusion Detection Systems (HIDS) Integrit [2] samt seiner Kollegen.

Auch diesmal werfen wir zuerst einen Blick auf die Systemwerkzeuge; diesmal steht Find im Fokus. Das kombinieren wir anschließend mit dem Versionsverwaltungssystem Git [3] sowie den darauf aufsetzenden Werkzeugen Gitwatch [4] und Flashbake [5].

Bordmittel ausnutzen

In der Werkzeugkiste jedes Linux-Systems lagert das Kommando find. Es sucht anhand der von Ihnen beim Aufruf benannten Kriterien nach passenden Einträgen im Dateisystem, beispielsweise nach Dateien, Verzeichnissen, Links oder Sockets. Es lässt sich auch dazu nutzen, festzustellen, ob ein Eintrag im Dateisystem verändert wurde.

Zum Stöbern nach regulären Dateien nutzen Sie -type f (“file”, siehe Tabelle “Find-Schalter für Dateisystemeinträge”). Mithilfe des Schalters -newermt (“newer modification time”) grenzen Sie die Ergebnisse nach dem Zeitpunkt der Veränderung ein. Im Beispiel aus Listing 1 befinden sich im betrachteten Verzeichnis zwei Dateien: file1.txt wurde am 3. März 2019 um 12 Uhr geändert, file2.txt am 11. März 2019 um 16:53 Uhr. Der Find-Aufruf im Listing sucht Dateien mit Änderungen ab dem 3. März 2019, 13 Uhr. Konsequenterweise erhalten Sie als Ausgabe von Find lediglich den Eintrag für file2.txt.

Typ des Eintrags

Schalter

Datei

-type f

Verzeichnis

-type d

Soft/Hardlink

-type l

Socket

-type s

Gerät (gepuffert)

-type b

Zeichendatei (ungepuffert)

-type c

benannte Pipe (FIFO)

-type p

Listing 1

$ ls -l
insgesamt 16
-rw-r--r--  1 frank frank    3 Mär  3 12:00 file1.txt
-rw-r--r--  1 frank frank   11 Mär  4 16:53 file2.txt
$ find . -type f -newermt "2019-03-03 13:00:00"
./file2.txt

Um einen Zeitrahmen zu setzen, fehlt noch eine Obergrenze. Dazu geben Sie Find im Aufruf einen weiteren Wert als Parameter mit, dem ein Ausrufezeichen vorhergeht. Dabei muss zwischen diesem und dem nächsten Schalter ein Leerzeichen stehen. Mit dieser Angabe negiert Find die nachfolgende Zeitangabe und benutzt sie als Obergrenze, sprich: “keine Dateien, die später als zum angegebenen Zeitpunkt geändert wurden”. In Listing 2 umfasst der Zeitrahmen alle Änderungen vom 11. März 2019 zwischen 13 und 18 Uhr.

Listing 2

$ find . -type f -newermt "2019-03-11 13:00:00" ! -newermt "2019-03-11 18:00:00"
./file2.txt

Damit wissen Sie aber lediglich, dass der Dateieintrag ein geändertes Modifikationsdatum aufweist. Um zu sehen, ob sich der Inhalt auch tatsächlich verändert hat, benötigen Sie zwei weitere Dinge: den vorhergehenden Inhalt und ein Vergleichsverfahren. Hier hilft ein Hash-Wert über den Dateiinhalt weiter, den Sie mit sha1sum, sha512sum, md5deep und hashdeep [6], hashalot [7] oder hashrat [8] berechnen. Dabei gibt sha1sum zwei Spalten aus – den berechneten SHA1-Hash-Wert und daneben den Dateinamen (Listing 3).

Listing 3

$ sha1sum file*
56ac1c08fa5479fd57c4a5c65861c4ed3ed93ff8  file1.txt
56ac1c08fa5479fd57c4a5c65861c4ed3ed93ff8  file2.txt

Um die Zustände von Dateien abgleichen zu können, kommen regelmäßige Schnappschüsse des Zustands zum Einsatz. Die speichern Sie in Textdateien mit dem Namensschema snapshot-Datum ab, beispielsweise als snapshot-20190303 für den 3. März 2019. Ein Beispiel dazu finden Sie in Listing 4. Die Formatangabe im Date-Kommando erzeugt eine Zeichenkette, bestehend aus Jahr, Monat und Tag ohne weitere Trennzeichen. Der Inhalt eines Schnappschusses folgt der in Listing 3 gezeigten Struktur.

Listing 4

$ sha1sum * > snapshot-$(date +"%Y%m%d")

Die Unterschiede zwischen einem vorhergehenden Schnappschuss und dem aktuellen Zustand stellen Sie wieder mithilfe von Sha1sum fest. Das Tool kennt dafür den Schalter -c (--check), gefolgt vom Dateinamen eines Schnappschusses. Es vergleicht dann die darin erfassten Dateien mit gleichnamigen Exemplaren im aktuellen Verzeichnis (Listing 5).

Listing 5

$ sha1sum -c snapshot-20190303
file1.txt: OK
file2.txt: FEHLSCHLAG
sha1sum: WARNUNG: die 1 berechnete Prüfsumme passte NICHT

Einen entsprechenden Aufruf verpacken Sie ohne viel Aufwand in ein Shell-Skript, das Sie über einen Cronjob regelmäßig ausführen. Je mehr Dateien es zu überprüfen gilt, desto unübersichtlicher gerät jedoch die Ausgabe. Außerdem möchten Sie sicher auch wissen, welche Änderungen es generell am Dateibestand gab, sprich: ob auch Dateien hinzukamen oder gelöscht wurden. Es ist daher an der Zeit, auch andere Lösungen in Betracht zu ziehen.

Versionskontrollsystem

Bislang können Sie nur die Frage beantworten, ob und wann sich etwas an Dateien geändert hat. Sie wissen allerdings nicht, worin die Änderung konkret bestand: Die bestehenden Daten wurden überschrieben, und Sie erfuhren erst im Nachhinein von der Veränderung.

Genauere Informationen liefern entweder der Abgleich mit einem externen Backup oder die Versionierung der Daten. Letzteres gelingt mithilfe eines Versionskontrollsystems wie etwa Git [3], Mercurial [9] oder Apache Subversion (SVN [10]): Diese Werkzeuge liefern eine komplette Änderungshistorie. Listing 6 zeigt die Änderungen in einem Git-Repository.

Listing 6

$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   dataset1.txt
#
no changes added to commit (use "git add" and/or "git commit -a")

Der Nachteil der Lösung: Sie erfordert einen zusätzlichen, manuellen Schritt, den Commit, sobald sich Änderungen im Bestand ergeben. Git und Subversion erledigen das nicht automatisch von sich aus. Einen etwas brachialen Lösungsweg für Git zeigt Listing 7: Der Befehl aus der ersten Zeile erfasst alle Änderungen im Git-Repository, der aus der zweiten Zeile aktualisiert den Inhalt des Repositorys.

Listing 7

$ git add --all
$ git commit -a -m "Änderungen im Dateibestand"

Damit versionieren Sie auch alle temporären Dateien, was selten sinnvoll ist. Um das zu unterbinden, erstellen Sie eine Datei namens .gitignore im Repository, die über Dateinamensmuster bestimmte Einträge von der Versionierung ausschließt. Listing 8 zeigt, mit welchen Einträgen in .gitignore Sie beispielsweise temporäre Dateien herausfiltern, die Vim für geöffnete Dateien erzeugt.

Listing 8

*~
*.sw?

Für einzelne Dateien oder eine Gruppe gleichartiger Dateien, die Sie überwachen wollen, kommen Werkzeuge wie Find, Xargs, Incron [11], Fswatch [12], Iwatch oder Inotify [13] ins Spiel. Listing 9 zeigt einen Aufruf von Inotifywait, der einen Git-Commit erzeugt, sobald Änderungen in der Datei file.txt auf das Speichermedium geschrieben werden. Inotifywait kennt zudem den Schalter -r, über den Sie die Wirkung des Aufrufs auch auf ganze Verzeichnisse erweitern.

Listing 9

$ inotifywait -q -m -e CLOSE_WRITE --format="git commit -m 'autocommit on change' %w" file.txt | sh

Listing 10 kombiniert den Find-Aufruf aus Listing 2 mit Xargs [14] und Git. Es prüft stündlich, welche Dateien innerhalb der letzten Stunde verändert wurden, und checkt diese in ein lokales Git-Repository ein. Rufen Sie das Skript auf, teilt es Ihnen auch mit, was es macht (Listing 11). Abbildung 1 zeigt Ihnen anhand von Gitk die automatisiert erfolgten Änderungen im Git-Repo.

Listing 10

#!/bin/bash
while true; do
  # calculate time range
  currentSec=$(date +"%s")
  currentTime=$(date +"%Y%m%d %H:%M:%S")
  previousSec=$(echo "$currentSec-3600" | bc)
  previousTime=$(date +"%Y%m%d %H:%M:%S" --date="@$previousSec")
  echo "--- $previousTime - $currentTime ---"
  currentPath=$(pwd)
  workingPath="$1"
  cd "$workingPath"
  echo "now here: $workingPath"
  find . -type f -newermt "$previousTime" ! -newermt "$currentTime" -print | xargs git add -v
  git commit -v -m "changes from $previousTime - $currentTime"
  cd "$currentPath"
  echo "now here: $currentPath"
  # wait for 1 hour
  sleep 60m
done

Listing 11

$ ./find-changes.sh /home/frank/daten &
[...]
--- 20190315 14:06:29 - 20190315 15:06:29 ---
now here: .
add '.datenbestand.txt'
[master 65797bb] changes from 20190315 14:06:29 - 20190315 15:06:29
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 datenbestand.txt
now here: /home/frank/daten
[...]

Abbildung 1: Automatisch erzeugte Git-Commits.

Abbildung 1: Automatisch erzeugte Git-Commits.

In derselben Werkzeugkategorie finden sich auch Gitwatch und Flashbake. Bei Ersterem handelt es sich quasi um eine umfangreichere Variante von Listing 10, die auf der Inotify-Schnittstelle aufsetzt, ähnlich wie Listing 9. Verwenden Sie eine Distribution, für die Gitwatch bislang noch nicht paketiert wurde, wie etwa Debian oder Ubuntu, dann beziehen Sie das Skript von der Projektwebseite auf Github. Sie rufen es mit dem Namen des zu überwachenden Verzeichnisses beziehungsweise der Datei auf, für die Sie Veränderungen protokollieren möchten. Abbildung 2 zeigt die Ausgaben von Gitwatch für die Quelldatei dieses Artikels.

Abbildung 2: Gitwatch protokolliert die &Auml;nderungen im Hintergrund.

Abbildung 2: Gitwatch protokolliert die Änderungen im Hintergrund.

Flashbake existiert schon länger als Gitwatch und verbindet im Idealfall Git und Cron miteinander. Das in Python geschriebene Programm steht sowohl über die Projektwebseite, als auch als Debian-Paket zur Verfügung. Um Änderungen einzelner Dateien zu erfassen, benötigt Flashbake ein bestehendes Git-Repository und darin eine Datei namens .flashbake mit der Dateiliste (Listing 12).

Listing 12

$ cat .flashbake
# files to track
datenbestand.txt
gitk.png
gitwatch.png
iviewdb.png
find-changes.sh
ils.png
working-with-an-ids.txt

Nun legen Sie mittels crontab -e einen Eintrag an, der Cron anweist, Flashbake regelmäßig aufzurufen. Mit dem Eintrag in Listing 13 sorgen Sie dafür, dass das Tool alle 15 Minuten das Verzeichnis /home/frank/daten/ überprüft. Dabei erfassen Flashbake beziehungsweise Git alle Änderungen, die innerhalb der vergangenen 15 Minuten erfolgt sind. Fehlermeldungen auf STDOUT landen im digitalen Mülleimer /dev/null.

Listing 13

*/15 * * * * flashbake /home/frank/daten 15 > /dev/null

Um auch den Inhalt der Änderungen zu sehen, nutzen Sie entweder Gitk (wie in Abbildung 1) oder den Aufruf git diff (Abbildung 3). Bei einer unerwünschten Änderung im Datenbestand greifen Sie auf eine frühere Version zurück und bleiben so auf der sicheren Seite.

Abbildung 3: &Auml;nderungen zwischen zwei Versionen lassen sich mit Gitdiff sichtbar machen.

Abbildung 3: Änderungen zwischen zwei Versionen lassen sich mit Gitdiff sichtbar machen.

Fazit

Mit den hier vorgestellten Werkzeugen finden Sie heraus, ob, wann und insbesondere welche Änderungen in Ihrem Datenbestand stattgefunden haben. Greifen Sie auf Git zurück, lassen sich auch Zwischenstände wieder einspielen. Ratsam ist, diese zusätzlichen Daten in der Vorausschau für den erforderlichen Bedarf an Speicherplatz nicht zu vergessen: Das Backup muss ja irgendwo hin, idealerweise auf ein externes Medium. Um ungewollte Änderungen zu verhindern, bedarf es weiterer Absicherungen, insbesondere auf der Ebene der Zugriffsrechte und Systemdienste. Anregung dazu gibt beispielsweise eine lesenswerte Übersicht des bekannten Entwicklers Veit Schiele [15]

Der Autor

Frank Hofmann arbeitet von unterwegs aus, bevorzugt in Berlin, Genf und Kapstadt, als Entwickler, LPI-zertifizierter Trainer und Autor.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDF
LinuxUser 05/2019 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben