MonD: Monitoring for Dummies

Wichtiger Hinweis: MonD ist noch in einer frühen Beta-Phase. Es funktioniert (und wie!), aber ich bin noch weit von einem ersten echten Release entfernt.

Diese Anleitung ist inzwischen sicher veraltet. Wer es nicht hinkriegt, sorry, ich kann wahrscheinlich nicht helfen, denn sonst wäre hier ja etwas vernünftiges zu lesen! Also in den Source gucken und die Krise krigen. Weinen hilft zwar nicht weiter, aber ist wenigstens gut für die Nerven.

Setup von MonD

Der Setup-Vorgang ist prinzipiell im README.html beschrieben das am Verzeichnis hinten dranhängt. Bis auf folgende Dinge:

  • Der Zugriff auf die CVSROOT ist derzeit nicht möglich da ich das ganze nicht als releasefähig ansehe. Hin und wieder, wenn mich jemand anspricht, werde ich ein TAR der aktuellen CVSROOT ins Verzeichnis stellen. Man muss dann selber entscheiden, wie man es macht.

  • Das setup.php ist alleandere als selbsterklärend. Deshalb werde ich hier im weiteren einige Punkte dazu sagen.

  • setup.php tut noch nicht alles, es erkennt noch keine leere Datenbank und legt das Schema noch nicht an.
Immer bedenken:

Zu 99% funktioniert MonD wie hier beschrieben. Aber es gibt Fälle, da klappt es nicht. Z. B. wenn die Datenbank überrannt wird (Locks), dann ist es möglich, dass der Zugriffsschutz nicht greift. Das ist ein grundlegender Fehler im Design der in der PHP-Version nicht mehr beseitigt wird. Irgendwann einmal werde ich den Kern vielleicht in Python neu schreiben, dabei wird das interne Design entsprechend korrigiert und erweitert, dann lassen sich solche Problemchen viel leichter und nachhaltiger korrigieren.

setup.php

Das Setup ist eine LOV, siehe auch, was ich zum Thema LOV geschrieben habe. Leider ist es dadurch alles andere als intuitiv zu verwenden, weshalb ich es hier etwas zu erklären versuche.

Warum eine LOV?

Warum nicht? Im Prinzip kann man in dieser alles abbilden was notwendig ist, um MonD zu konfigururieren. Und das enthebt mich der Notwendigkeit, für all die verschiedenen Fälle einen eigenen Wizard zu schreiben.

Leider ist es dadurch zu kompliziert. Idealerweise sollte für den Betrieb von MonD nur das Niveau eines Hilfs-Abschmeckers vom Klärwerk ausreichend sein, so dass man es ohne Nachdenken einfach nur einsetzen kann, mit einer automatischen steilen Lernkurve für all die Kleinigkeiten die dann kommen. Aber das setup.php durchbricht diesen Teil leider, weshalb es auch erklärungsbedürftig ist.

Safe Mode

Dieses Beispiel hier ist ohne "Safe-Mode". Hat man Safe-Mode von PHP eingeschaltet, muss man evtl. den Scripten entsprechend den Benutzer des Webservers zuweisen (bzw. man muss der Gruppe des Webservers Zugriff auf die Datenbank geben), da PHP den Zugriff auf die Datenbank sonst verweigert. Das wird hier aber nicht beschrieben. Wer Safe-Mode einsetzt muss selber zusehen, wie er mit diesem Mist klarkommt, denn eine allgemeinverständliche und allgemeingültige Erklärung ist dann nicht mehr möglich da die Benutzernamen und Gruppen von System zu System abweichen werden.

Grundlegendes

Eigentlich sollte setup.php vom Rest des Codes eigenständig sein. Leider habe ich das mal wieder in dieser frühen Form vergeigt. Wer also rumprobieren will muss sich folgende drei Dateien in ein eigenes Web-Verzeichnis kopieren:
  • setup.php
  • setup.sql
  • mond.php
    Dann kann man es - über den Webserver - aufrufen um damit rumzuexperimentieren. Wenn man sich sicher fühlt kann man es in Ruhe im eigentlichen Monitoring-Verzeichnis aufrufen.
Ich gehe also davon aus, man hat setup.php unter einem URL aufrufbar gemacht. Dieses URL nenne ich im Weiteren hydra.geht.net/tt/setup.php

Außerdem werden die Shell-Kommandos immer aus dem Verzeichnis heraus aufgerufen, in dem sich das setup.php befindet.

Die Pfade muss man also ggf. den entsprechend eigenen Pfaden anpassen, das wird hier alles nicht erklärt.

Und wer hier Schritte weil sie überflüssig zu sein scheinen überspringt wird evtl. Probleme mit den Zugriffsrechten bekommen. In diesem Fall muss er sich selber weiterhelfen ODER mit einem vollkommen frischen Verzeichnis eben wieder bei 0 anfangen.

Anlegen der Pfade

Ruft man das URL das erste Mal auf, sieht man etwas wie:

Warning: sqlite_open() [function.sqlite-open]: unable to open database: /var/www/tt/log/mond.sqlite in /var/www/tt/mond.php on line 2

Warning: sqlite_busy_timeout() expects parameter 1 to be resource, boolean given in /var/www/tt/mond.php on line 3

Warning: fopen(log/mond.log) [function.fopen]: failed to open stream: No such file or directory in /var/www/tt/mond.php on line 4

Warning: sqlite_query() expects parameter 1 to be resource, string given in /var/www/tt/setup.php on line 54

Warning: sqlite_fetch_all() expects parameter 1 to be resource, null given in /var/www/tt/setup.php on line 54

Warning: Invalid argument supplied for foreach() in /var/www/tt/setup.php on line 56
 back

Lösung:

mkdir log
chmod 1777 log

Anlegen der Datenbank

Ruft man das URL dann nochmals auf, sieht man etwas wie:

Warning: sqlite_query() [function.sqlite-query]: no such table: t_lov in /var/www/tt/setup.php on line 54

Warning: sqlite_fetch_all() expects parameter 1 to be resource, boolean given in /var/www/tt/setup.php on line 54

Warning: Invalid argument supplied for foreach() in /var/www/tt/setup.php on line 56
 back

Lösung: Die Datenbank ist noch leer, das Schema muss rein:

sqlite log/mond.sqlite < setup.sql

Das soll natürlich setup.php irgendwann einmal selbermachen, aber so weit bin ich noch nicht.

Kontrolle

Wenn man das URL jetzt nochmals aufruft kommt nur noch die Eingabebox mit dem "EDIT"-Button und dem "back"-Link.

Man gibt nun ein Passwort ein und drückt "Edit". Es erscheint etwas wie:

Password not set!

To set the given text as the initial password, create file log/mond_pw.php with following contents: <?php $passmd5='77adbfbc5f40e311bd51c84fb08fe91f'; ?>


Then reload this page. 
If you have password trouble, create file log/mond_pw.php with contents: <?php $passdef=''; ?>

Das hier verwendete Passwort war übrigens "test".

Passwort-Datei anlegen

Just follow the yellow brick road:

cat <<'EOF' >log/mond_pw.php
<?php $passmd5='77adbfbc5f40e311bd51c84fb08fe91f'; ?>
EOF

Übrigens: Cut&Paste von diesem "cat" funktioniert nicht - Bamboo (mein CMS hier) fusselt beim EOF ein Blank hinein, das klappt dann nicht.

Und jetzt kommt das Setup endlich

Noch ist alles leer

Füllen vom Setup

Jetzt füllt man die Eingabezeilen vom Setup aus, mit folgenden Daten (und in der angegebenen Reihenfolge. Die Werte enthalten nie Leerzeichen, d. h. jedes Leerzeichen springt zum nächsten Feld):

Variables Variables * *str*
Variables Types * *str*
Types - Types *str*
Types - Variables -

Wer sich wundert: Nach jeder Zeile die man in die Eingabezeile eingegeben hat drückt man "Edit" um diese zu speichern.

Das ganze sieht dann in etwa so aus:

Noch sind einige Werte falsch

Man hakt die drei eingezeichneten Kästchen an und klickt - ermangels eines anderen Buttons - auf "Edit".

Korrigieren der Werte

Vorher war in der "Type"-Spalte noch kein Typ auswählbar, das hat sich jetzt auf leicht magische Weise geändert. Man kann die drei Typen jetzt auf "-" umstellen und auf "Save" klicken. Verantwortlich dafür sind die zwei "Types"-Zeilen die gerade hinzugefügt wurden.

Korrektur der vorherigen Eingaben

Wenn man auf "Edit" klickt, gibt man nur ein Edit-Kommando, die Korrekturen werden dann nicht gespeichert! (Edit fügt nur hinzu oder zeigt die angehakten Zeilen an.)

Hinzufügen der restlichen Werte

Nun kommt ein kleiner Edit-Marathon:

(Ich glaube, einiges ist da noch nicht brauchbar oder wird gar nimmer gebraucht, aber das spiegelt den Stand wieder, den ich momentan habe.)

Variables Client * -
Variables Machine * -
Variables Password * -
Variables Setting * -
Types allow Add Client -
Types allow Add IP -
Types allow IP -
Types allow Machine -
Types deny Add Client -
Types deny Add IP -
Types deny IP -
Types deny Machine -
Types hash Password -
Types log Client -
Types log IP -
Types str * -
Types str Password -

Wie man sehen kann wird man vom setup.php dabei etwas unterstützt, da es die letzte Eingabe immer wiederholt, man also nur wenig abändern muss. Jetzt ist die gesamte Eingabe parametrisiert, das Gerippe steht also, nur das eigentliche Fleisch fehlt noch.

Erst jetzt geht es an die eigentliche Konfiguration

Festlegen des Passworts

Abgesehen vom Anlegen des Initialspassworts sollte es eigentlich es erst ab hier losgehen, d. h. setup.php sollte somit alles was oben steht selber automatisch durchführen. Momentan tut es das aber leider eben noch nicht.

Ändern / Anlegen des Login-Passworts

Das Login-Passwort legt man in zwei Schritten an:

  • Man legt einen beliebigen Wert fest, mit dem das Passwort verwürfelt wird. Dieser dient dazu, Precalculated-Dictionary-Attacken auf den Hash unmöglich werden zu lassen. Diesen Verwürfler kann man natürlich weglassen, aber wenn man ihn einträgt (oder ändert) werden automatisch alle alten Passworte unbrauchbar (da ihr hash nicht mehr mit dem Passwort übereinstimmt).
  • Man legt das eigentliche Passwort fest. Dieses wird dann anhand des Verwürflers zusätzlich verwürfelt, so dass ohne diesen Verwürfel-String der Hash vollkommen aussagelos bleibt.
(Nun ja, so viel Sicherheit braucht MonD eigentlich nicht, aber die LOV ist eine generelle Verfahrensweise die ich nicht nur bei MonD zum Einsatz kommen lassen will.)

Setting Password * str würfel
Password Default * str pw

So sieht das dann mit den beiden obigen Werten aus:

Anlegen des Passworts

Wie man sehen kann, die Klartextangabe "str" wird in "Passwort"-Feldern automatisch in "hash" umgerechnet und nur der Hash gespeichet. Das ist eigentlich der einzige echte "Hack" in setup.php, denn mir ist noch nicht eingefallen, wie man ein solches Verhalten generalisieren kann.

Löschen des Initial-Passworts

Das Initial-Passwort ist aber weiterhin aktiv. Deshalb muss man es erst löschen. So lange das Initial-Passwort aktiv ist erscheint eine entsprechende Warnung:

Warning! Initial password still active. To deactivate remove log/mond_pw.php.

Genau das tut man dann auch:

rm -f log/mond_pw.php

Und schwupps ist man draußen, da man ja - hoffendlich - ein anderes und sichereres Passwort als das für die Initialzündung genommen hat. Dies wird begleitet von dem Hinweis:

If you have password trouble, create file log/mond_pw.php with contents: <?php $passdef=''; ?>

Das bedeutet, man hat ein falsches Passwort eingegeben. Aber natürlich funktioniert es mit dem gerade neu angelegten Passwort!

Beispiel

Hier der Screenshot meines Gesamtsetups:

Alles mögliche konfiguriert

Wie man sieht sind einige Rechner mit variabler IP noch ohne Passwort. Das kann ich aber leicht ändern ;)

Das Setup enthält auch noch so tests wie z. B. "Password User tino". Das ist Müll und hat keine Funktion, stört aber auch nicht.

Mini-FAQ

F: Warum ist das Passwort-Feld (unten neben dem Edit-Knopf im Setup) im Klartext lesbar?
A: Warum nicht? Wer das nicht will kann ja das entsprechende Feld von "text" auf "password" ändern. Der Browser sieht es ja eh im Klartext, warum soll ich es dann nicht ebenfalls sehen?

F: Warum wird jedes Mal das Passwort-Feld übertragen?
A: Damit man gar nicht in die Versuchung gerät, nur http zu verwenden. Wer setup.php nicht via https aufruft ist eben selber schuld.

F: Wie lege ich Benutzer an die Rumeditieren können?
A: Geht (noch) nicht, wird die php-Version aber vermutlich auch niemals bekommen. Derzeit haben alle Admins also ein globales Passwort.

F: Wie lege ich Benutzer an die Lesen können?
A: Gar nicht, jedenfalls nicht in MonD. Lesen darf jeder der die Webseiten abrufen darf. .htaccess ist Dein Freund. Das muss als Zaunpfahl reichen.

F: Wie verhindere ich Fake-Updates, d. h. Updates von Maschinen die das nicht update dürfen?
A: "Machine HOSTNAME * deny", die Maschinen die dürfen werden als "Machine HOSTNAME IP allow" mit ihrer IP hinzugefügt. Die IP-Einträge erscheinen übrigens automatisch beim ersten Zugriff der Maschine per "Add Machine"-Eintrag.

F: Wie verhindere ich Fake-Updates bei Maschinen mit variabler IP?
A: "Machine HOSTNAME * allow" und zusätzlich "Password Machine HOSTNAME str PASSWORT". Das Passwort wird beim "post.php"-Request einfach als Query-String hinten drangehängt per ".../post.php?passwort". Beim ersten Request wird das Passwort - sofern vorhanden - automatisch als "Add Password" hinzugefügt.

F: Wie tracke ich Clients?
A: Man kann Clients einen Namen und ein Passwort zuweisen, um zu monitoren, ob diese monitoren. Diese erscheinen automatisch als "Add Client" wenn sie noch nicht konfiguriert sind. Name und Passwort werden einfach an das ok.php-URL angehängt, in der Form "../ok.php/CLIENT/PASSWORT?TEXT". Text muss befüllt sein und kann z. B. "ok" lauten. Die Idee ist, dass der Client in Zukunft evtl. seinen Status dranhängt etc.

F: Der Client "" wird immer rot!
A: Der ajax-Client meldet sich ohne Namen, so wie alle Aufrufe zum Script "ok.php" ohne User/Passwort ebenfalls. Unterbleiben diese Aufrufe, wird es selbstverständlich rot, da ein Monitoring ohne jemanden der zuguckt irgendwie sinnfrei wäre. Wen das stört kann diesen Eintrag ja abschalten. Einfach im roten Zustand markieren und auf "1" setzen.

F: Wie sehe ich fehlerhafte Zugriffe?
A: Beim Passwort erscheint ein "Denied"-Eintrag in der LOV. Bei IPs erscheint nix, wenn man das braucht kann man den "deny"-Eintrag auf "log" umstellen, dann erscheinen "Log"-Einträge - der Zugriff wird dann aber gewährt. Natürlich gibt es auch das http-log.

F: Die Passworte erscheinen im http_access.log.
A: Die Passworte von Maschinen oder Clients erscheinen tatsächlich dort, nicht aber die Passworte vom setup etc. Wenn das ein Problem ist empfehle ich, das access_log abzuschalten. Das access_log ist in Europa aufgrund der Datenschutzbestimmungen eh nur in Ausnahmefällen zulässig da es ohne Zustimmung des Betroffenen personenbezogene Daten speichert (die IP bzw. das Verhalten, also worauf zugegriffen wurde). Wer sich also an geltendes Recht hält kennt solche Probleme nicht. (Das ist eine Meinung, keine Rechtsberatung.)

F: Proxys können die Passworte mitlesen da sie im URL sind!
A: Proxys können alles mitlesen das nicht HTTPS-verschlüsselt ist. Das ist also auch kein Argument, Passworte nicht ins URL zu verbasteln.

-Tino, 2008-02-26