![]() |
Die Apache-Konfigurationsdatei:
|
|
| |
Zu den Grundlagen der Unix-Philosophie gehört, daß jedem Prozeß drei Standardkanäle zugeordnet werden (können). Es gibt grundsätzlich einen voreingestellten Eingabekanal STDIN - standard input -, einen voreingestellten Ausgabekanal STDOUT - standard output - und einen voreingestellten Kanal für Fehlermeldungen STDERR - standard error. STDIN ist normalerweise mit der Tastatur verbunden oder aber mit einem anderen Gerät, beispielsweise einer Netzwerkschnittstelle, STDOUT und STDERR mit dem Terminal, also beispielsweise dem Monitor. Solange man nur etwas hineinschreibt oder daraus liest, verhalten sich diese Standardkanäle wie normale Dateien. Der große Vorteil besteht darin, daß die von ihnen übermittelten oder gespeicherten Daten umgelenkt werden können, so daß, wie das der Apache auch tut, die Ausgabe von STDOUT auf dem Bildschirm erscheinen und der Inhalt von STDERR gleichzeitig in eine Protokolldatei (log) geschrieben werden kann.
Für Windows-Maschinen gilt diese Zuordnung von Standardkanälen nur bedingt. Es gibt ja auch kein Systemprotokoll (syslog). Im wesentlichen hängt es vom Entwickler eines Windows-Programms ab, ob und wie beispielsweise STDERR-Ausgaben gespeichert werden. Der Apache gehört zu diesen Programmen, die Fehlermeldungen ausgeben.
Neben dem Zugriffs- und dem Fehlerprotokoll sind noch
andere Protokolldateien möglich, auf die aber an dieser Stelle nicht weiter eingegangen werden soll.
Es gibt eine Vielzahl an "Ereignissen", die den Apache veranlassen können, mit einer Fehlermeldung zu reagieren. Das auffälligste dieser Ereignisse ist zum Beispiel der Versuch, eine URL anzufordern, die es nicht gibt, also der bekannte Fehler 404, der ja auch im anfordernden Client eine besondere Anzeige bewirkt. Ebenso bekannt dürfte bei einem fehlerhaften Zugriff auf ein cgi-bin-Verzeichnis die "Verboten"-Anzeige im Client sein (Fehler 403). Diese Fehlermeldungen sehen im error_log (bzw. error.log unter Windows) ungefähr so aus:
[error] [client 10.0.0.1] File does not exist: /srv/virthost/test [error] [client 192.168.0.1] attempt to invoke directory as script: /srv/virthost/cgi-bin/ [error] [client 192.168.0.1] Directory index forbidden by rule: /, referer: http://www.virthost.test/
Die Form der Protokolleinträge selbst kann nicht beeinflußt bzw. verändert werden - es sei denn, man schreibt sich vor dem Kompilieren die Quelldateien entsprechend neu. Jeder Protokolleintrag besteht aus vier Teilen:
1. Datum, zum Beispiel: [Thu Aug 05 20:25:33 2004]
2. Schweregrad des Fehlers (LogLevel), zum Beispiel: [error]
3. Verursacher des mißlichen Ereignisses, zum Beispiel: [client 192.168.0.2]
4. Fehlerbeschreibung, zum Beispiel: script not found or unable to stat: /srv/virthost/env.pl
Es gibt Möglichkeiten, die Anzahl der error_log-Meldungen innerhalb der Konfigurationsdatei unter Zuhilfenahme der Anweisung LogLevel zu beeinflussen. Die httpd.conf-Kommentare sagen dazu aus:
# "LogLevel": Legt die Art und Menge der Eintragungen fest, die in der # Protokolldatei abgelegt werden sollen. Mögliche Werte sind: # debug, info, notice, warn, error, crit, alert, emerg.
Diese "Level" bezeichnen die unterschiedliche Wichtigkeit von Meldungen bzw. den Schweregrad des aufgetretenen Fehlers. Das heißt, debug verzeichnet alles, während bei emerg nur dann etwas protokolliert wird, wenn es einen Notfall gibt. Außerdem werden auch immer die Ausgaben der höheren Level miterzeugt. so daß bei error auch alles protokolliert wird, was von crit, alert und emerg zu protokollieren ist. Die Bedeutung der möglichen LogLevel-Werte faßt die folgende Tabelle zusammen.
| LogLevel | Aufgabengebiet |
|---|---|
debug |
Es wird alles protokolliert, gleichgültig, ob es sich um etwas Wichtiges oder etwas Unwichtiges handelt. Beispiel: "[debug] Opening config file ...". Das kann die Protokolldatei allerdings enorm vergrößern, weil unter anderem jeder Start eines Prozesses verzeichnet wird. Da in der Regel gleich zu Beginn 250 Threads wegen der Anweisung ThreadsPerChild 250 gestartet werden, ergeben sich bereits daraus 250 Zeilen mit den Prozeßnummern. |
info |
Es werden zusätzliche kommentierende Informationen zu Serverprozessen protokolliert. Beispiel: "[info] No ExecCGI or Open verb found for files of type '.cgi'..." Ursache: Der Client hat ein cgi-Script in einem Verzeichnis ausführen lassen, für das in der httpd.conf keine Anweisung Options +ExecCGI vorgesehen ist. Das Script ist auch ausgeführt worden und der Client hat nichts davon bemerkt, daß der Server dabei ein leichtes Unwohlsein verspürt hat. |
notice |
Der normale Betriebszustand wird protokolliert. Beispiel: "[notice] Apache/2.0.50 (Gentoo/Linux) PHP/5.0.0 configured -- resuming normal operations ..." Ursache: Das Einschalten des Servers muß kein wirklicher Fehler sein ;-) Und einen anfragenden Client geht das überhaupt nichts an. |
warn |
Alle Fehlermeldungen, auch die unkritischen, über die ein anfragender Client nicht informiert wird, werden protokolliert. Beispiel: "[warn] Init: Session Cache is not configured [hint: SSLSessionCache] ..." Ursache: Der Server ist zwar für den Einsatz von SSL (sichere Bedingungen) konfiguriert, aber es existiert kein Cache dafür. |
error |
Es wird ein Protokolleintrag erzeugt, wenn der Fehler auch im anfragenden Client zu einer unerwarteten Meldung führt. Beispiel 1: "[error] [client 192.168.0.2] File does not exist: /srv/www/favicon.ico ..." Ursache: Der Client hat eine Datei angefordert, die im entsprechenden Serververzeichnis nicht vorhanden ist und wird darüber mit einer entsprechenden Fehlermeldung informiert. Beispiel 2: "[error] [client 192.168.0.1] user schnauss: authentication failure for "/": Password Mismatch" Ursache: Die Eintragung für das Paßwort ist in .htaccess nicht korrekt vorgenommen worden, da nutzt es dem Client nichts, das richtige Paßwort zu übermitteln. |
crit |
kritische Fälle, die zu einem Prozeßabbruch führen, werden aufgezeichnet. Beispiel: "[crit] Failed to get a socket, exiting child ..." Ursache: Es konnte keine Verbindung aufgebaut werden, der Childprozeß wird beendet. |
alert |
Es werden Fehler verzeichnet, die den gesamten Serverbetrieb einschränken oder abbrechen lassen können. Beispiel 1: "[alert] (2)No such file or directory: getpwuid: couldn't determine user name from uid 4294967295, you probably need to modify the User directive ..." Ursache: Der username, der in der "main server configuration" der httpd.conf eingetragen werden muß, gehört nicht zu einer Gruppe, die für den Server Zugriffsberechtigungen besitzt (ein solcher Fehler kann nur auf einer Linux-Maschine auftreten). Alle Serverprozesse werden gestoppt. Beispiel 2: "[alert] [client 192.168.0.1] /srv/www/.htaccess: Invalid command 'AuthUserFile', perhaps mis-spelled or defined by a module not included in the server configuration Ursache: Ein Client versucht, auf einen mit .htacces geschützten Teil zuzugreifen. Das Modul, das für die Authentifizierung zuständig ist (mod_auth), ist jedoch nicht in der Modulliste des Servers aktivert. |
emerg |
Protokolleintrag der höchsten Sicherheitsstufe, falls das System nicht benutzbar ist. Beispiel: "[emerg] Child cannot open lock file. Exiting ..." Ursache: Es gibt einen Konflikt in Zusammenhang mit LockFile oder AcceptMutex, der Server kann nicht benutzt werden. Dieser Protokolleintrag kann nur auf Linux-Maschinen erscheinen, da die Anweisungen LockFile und AcceptMutex für die unter Windows einsetzbaren Module nicht zur Verfügung stehen. |
Der Name des Fehlerprotokolls ist mit Hilfe der Anweisung ErrorLog frei wählbar. Es muß nicht unbedingt error_log heißen, genausogut wäre beispielsweise ein Name wie serverfehler.txt möglich. Wird keine Angabe gemacht, schreibt Apache die Fehlermeldungen nach logs/error_log, das unterhalb des ServerRoot liegt. Jeder VirtualHost kann seine eigene Protokolldatei erhalten, die aber leider nicht über .htaccess eingestellt werden kann. Die Formulierungen, die in der error_log aufgezeichnet werden, müssen dabei nicht immer dem entsprechen, was ein Browser eventuell darstellt.
In error_log können noch andere Einträge zu finden sein, die nicht unmittelbar von Apache stammen (müssen). Es gibt auch dann Protokolleinträge, wenn beispielsweise ein fehlerhaftes CGI-Script aufgerufen wird. Eine der bekanntesten Fehlermeldungen, deren Erklärung auch im
SELFHTML-Forum häufiger angefragt und diskutiert wird, ist:
[Thu Aug 05 20:13:19 2004] [error] [client 192.168.0.2]\ Premature end of script headers: quiz.pl, referer: http://www.perl.test/cgi-bin/quiz.pl
Das "unerwartete Ende der Script-Header" bedeutet häufig, daß die "shebang" nicht korrekt formuliert wurde, so daß der PERL-Interpreter nicht angesprochen werden kann oder daß irgendein anderer Pfad nicht korrekt angegeben wurde, so daß das Script nicht vollständig abgearbeitet werden konnte - es sind aber auch andere Gründe möglich. Treten Fehler an einer beliebigen Stelle eines CGI-Scripts auf, erhält man mit dem Protokolleintrag auch die Zeile, in der der Fehler vermutlich steckt und kann dort nachsehen:
[Thu Aug 05 21:18:34 2004] [error] [client 192.168.0.1]\ '#$par' is not a valid variable name at /srv/perltest/cgi-bin/quiz.pl line 24,\ referer: http://www.perl.test/cgi-bin/quiz.pl [Thu Aug 05 21:18:35 2004] [error] [client 192.168.0.1]\ BEGIN failed--compilation aborted at /srv/perltest/cgi-bin/quiz.pl line 31,\ referer: http://www.perl.test/cgi-bin/quiz.pl
Solche von CGI-Scripts stammende Fehlermeldungen würden sich auch in eine andere Protokolldatei umleiten lassen. Sie sind genau die Fehlermeldungen, die jeder, der ein PERL-Script testet, dringend benötigt, um sein Script fehlerfrei gestalten zu können.
Im Gegensatz zu PERL liefert PHP keine solche Protokolleinträge, falls ein Script Fehler enthält. Wenn man solche Fehler ebenfalls in der error_log verzeichnet finden möchte, muß dafür die php.ini entsprechend angepaßt werden.
Die Fehleranzeigen, die ein Browser eventuell darstellt, müssen nicht unbedingt wörtlich mit den Eintragungen in error_log übereinstimmen. Sie sehen auch im "Normalzustand" sehr nüchtern aus. Und es wird bei weitem nicht alles, was in die Protokolldatei geschrieben wird, ebenfalls dem anfragenden Client zur Darstellung übermittelt.
Im Gegensatz zu den in error_log aufgezeichneten Meldungen läßt sich aber das, was ein anfragender Client optisch darstellt, (fast) alles individuell gestalten. Strenggenommen handelt es sich dabei gar nicht um Fehler, die der Apache selbst erzeugt - zum Beispiel aufgrund einer fehlerhaften Konfiguration - , sondern um die tatsächlich eine fehlerhafte Übermittlung von IP-Paketen anzeigende "Statusanzeigen" des benutzten Protokolls, also HTTP. Die Liste der möglichen Statuscodes kann in
http://www.w3.org/Protocols/rfc2616/rfc2616.txt nachgelesen werden. Die wichtigsten und am häufigsten anzutreffenden Statusmeldungen sind wahrscheinlich:
| Nummer | Bedeutung | zugehöriges Ereignis |
|---|---|---|
200 |
OK |
Die angeforderte URL war korrekt, die gewünschte Datei bzw. die angeforderten Daten wurde(n) ausgeliefert. |
401 |
nicht autorisierter Zugriff |
Der Aufruf der angeforderten Ressource ist nur nach korrekter Autorisierung (Benutzername/Paßwort) gestattet. mögliche Ursache: es wurde eine Adresse aufgerufen, die mit einem Zugriffsschutz (z. B. .htaccess) versehen ist, und die Eingabe von Benutzername und/oder Kennwort war nicht korrekt. |
403 |
Zugriff verboten |
Der Aufruf der angeforderten Ressource ist nicht gestattet. mögliche Ursache: es wurde eine URL angefordert, die dem Server zwar bekannt ist, aber auf die aufgrund der Serverkonfiguration kein Zugriff erlaubt werden kann. So etwas kann vorkommen, wenn ohne Angabe eines Scriptnamens auf ein cgi-bin-Verzeichnis zugegriffen werden soll oder auf ein Verzeichnis, in dem keine Index-Datei liegt und für das ein "Directory-Listing" nicht gestattet ist. |
404 |
Nicht gefunden |
Die angeforderte Ressource ist dem Server nicht bekannt. mögliche Ursache: Bei der Eingabe der URL in der Adreßzeile des anfordernden Browsers ist ein Tippfehler unterlaufen. |
500 |
Interner Serverfehler |
Der Server kann die gestellte Aufgabe nicht erfüllen. mögliche Ursache: Diese Anzeige erscheint vor allem dann, wenn ein fehlerhaftes Script angefordert wurde. |
Es ist zu sehen, daß diese Statuscodices keineswegs nur echte Fehler bezeichnen müssen. Nur die Statusmeldungen 4xx und 5xx beschreiben Konflikte bei der Anforderung von Daten oder der Datenübertragung. Und für solche Fälle sieht die Apache-Konfiguration vor, daß die Browseranzeige mit Hilfe der Anweisung ErrorDocument xxx individuell gestaltet werden kann, xxx steht hier für den gewünschten HTTP-Statuscode. Diese Möglichkeit hat man sowohl mit dem älteren Apache 1.3.x wie auch mit einem aktuellen Apache 2.0.x.
Wird auf eigene Vorgaben für ErrorDocument verzichtet, so erscheinen die hartkodierten, zum core-Modul des Apache gehörenden englischsprachigen Fehlermeldungen. Zur Abwandlung dieser Anzeigen gibt es drei Wege:
1. hartkodierte Meldungen
Das bedeutet, daß die Meldung direkt vom Apache erzeugt wird. Der Wortlaut muß also auch in der httpd.conf vorgegeben werden, was in folgender Form geschehen kann:
ErrorDocument 404 "<p> </p><p> </p><h1>Fehler 404<h1>\
<hr>\
<p>Die angeforderte URL kann nicht gefunden werden</p>"
Hinweis: HTML-tags sind in solchen Meldungstexten zulässig. Es muß entweder alles hintereinander in einer Zeile geschrieben werden, oder es findet hier ausnahmsweise der Backslash als Zeilentrenner Verwendung. Der Internet Explorer stellt solche servergenerierten Fehlermeldungen erst dar, wenn sie mehr als 512 Bytes belegen. Das hier notierte Beispiel erscheint daher nicht im Internet Explorer, wohl aber in anderen Browsern.
2. lokale Fehlerdokumente
Das bedeutet, daß ein lokales HTML-Dokument die gewünschte Anzeige enthält. In der httpd.conf wird dazu folgendes notiert:
ErrorDocument 404 fehler404.htm
Es kann auch noch ein Alias für das Verzeichnis mit individuellen Fehlerseiten eingesetzt werden, womit die gesamte Anweisung dann die Form
ErrorDocument 404 /error/fehler404.htm
erhält. Die Apache Software Foundation hält diesen Vorschlag für den geeigneten und bietet ihn in der "default"-Konfigurationsdatei auch an, mit dem Zusatz, daß die vorgeschlagenen Fehlerseiten die zusätzliche Erweiterung "var" erhalten und aus SSI zusammengestzt werden.
Auch hier gilt, daß eine solche lokale Fehlerseite erst dann vom Internet Explorer dargestellt werden kann, wenn sie größer als 512 Bytes ist.
3. externe Fehlerdokumente
Das bedeutet, daß die gewünschte Fehlerseite über eine externe URL angesprochen wird. Der Eintrag in der httpd.conf erhält dann folgendes Aussehen:
ErrorDocument 404 http://domainname.tld/fehler404.htm
Mit dieser Weiterleitung auf ein externes Dokument wird aber ein Redirect ausgelöst, was zu eventuell nicht erwünschten Nebeneffekten führen kann. Näheres dazu kann in der
Apache-Dokumentation nachgelesen werden.
Wer einen Webserver einsetzt, möchte meist nicht nur unterrichtet werden, falls es irgendeinen Fehler bzw. eine Störung im Betriebsablauf gibt. Sehr wichtig sind Statistiken, die Aufschluß darüber geben, wer wann welche Ressource angefordert oder anders auf den Webserver zugegriffen hat. Der Apache soll also in möglichst kurzer Form über alle seine Reaktionen auf Anfragen Protokolleinträge erzeugen, unabhängig davon, wie auf eine Anfrage reagiert wurde.
Anders als für das Fehlerprotokoll gilt aber für das Zugriffsprotokoll, daß sein Inhalt vollständig vom Administrator bestimmt sowie festgelegt werden kann, ob es ein solches Protokoll (oder mehrere) überhaupt geben soll. Zuständig dafür sind die Anweisungen CustomLog und LogFormat, die von dem DSO-Modul mod_log_config bereitgestellt werden. Soll ein Zugriffsprotokoll erstellt werden, muß also dieses Modul auch in der Modulliste der Apache-Konfiguration enthalten sein. In der httpd.conf wird in der Regel zunächst folgender Vorschlag zur Konfiguration des Zugriffsprotokolls zu finden sein:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
CustomLog logs/access.log common
Die ersten vier Zeilen bestimmen unterschiedliche Einstellungsweisen dafür, was in acces_log stehen soll, die fünfte bestimmt den Namen und den Ablageort des Zugriffsprotokolls sowie die Einstellung. Die Angaben "combined", "common", "referer" und "agent" sind so etwas Ähnliches wie Aliasnamen für die davor in Anführungszeichen zusammengafaßte Konfiguration. Diese Namen sind frei wählbar, so daß diese Zeilen besipielsweise auch so aussehen können:
LogFormat "%t %h %u \"%r\" %>s" schnauss CustomLog logs/access_log schnauss
Da sich auf diese Weise der Inhalt des Zugriffsprotokolls in jeder Hinsicht gestalten läßt, ist es auch möglich, unterschiedliche Protokolldateien für jeweils spezifische Zwecke zusammenstellen zu lassen:
LogFormat "%t %h %u \"%r\" %>s" schnauss
LogFormat "%{User-agent}i" agent
CustomLog logs/access_log schnauss
CustomLog logs/agents_log agent
In einem solchen Fall gibt es zwei unterschiedlich konfigurierte Protokolldateien. Die ausführlichere enthält die den Umgebungsvariablen entsprechenden Daten des Server-Zugriffs, und die kürzere enthält lediglich eine Liste der unterschiedlichen Browserkennungen (user-agents), beide Protokolldateien unterscheiden sich auch in ihrem Namen. Eine solche Festlegung kann beispielsweise nützlich sein, wenn man Wert darauf legt, eine gesonderte Statistik der user-agents aufstellen zu können, aus der die Prozentzahlen für die unterschiedlichen anfragenden Browser ersichtlich wird. Mit dem Ergebnis muß man vorsichtig umgehen, da sich bei modernen Clients (Browsern) die user-agent-Daten manipulieren lassen (Opera gibt sich z. B. "default" nicht als Opera zu erkennen).
Die im Beispiel angegebene Zeichenkette "%t %h %u \"%r\" %>s" erzeugt in access_log folgende Eintragung:
[08/Aug/2004:16:11:25 +0200] www.virthost.test schnauss "GET / HTTP/1.1" 200 [08/Aug/2004:16:11:28 +0200] www.virthost.test schnauss "GET /index.htm HTTP/1.1" 200
Das heißt, das Protokoll enthält der Reihe nach das Datum, die Domain des anfragenden Clients, den Benutzernamen (wenn eine .htaccess ein login vorschreibt), danach in Anführungszeichen die Übermittlungsmethode, die angeforderte Ressource und das verwendete Protokoll sowie ganz zuletzt die Nummer des HTTP-Statuscodes. Diese Statuscodices wurden oben bereits erwähnt. In einer access_log sollte auf sie nicht verzichtet werden. Eventuell auftretende Zugriffsfehler werden zeitgleich in error_log und access_log protokolliert, so daß man im Fehlerprotokoll die Beschreibung des Fehlers findet und im Zugriffsprotokoll nachvollziehen kann, wer den Fehler verursacht hat.
Ebenso wie das Fehlerprotokoll kann auch das Zugriffsprotokoll für jeden VirtualHost einzeln konfiguriert werden. Aber auch hier muß das der Serveradministrator selbst tun, die Einstellung von CustomLog in einer .htaccess ist nicht möglich. Aber wer weiß, vielleicht wird es in einer späteren Apache-Version auch das einmal geben ...
© 2007
Impressum, für diese Seite:
christoph.schnauss@berlin.de