Fonctionnalités concernant les logs
Apache dispose d’un grand nombre d’options permettant de contrôler le format des fichiers logs. Pour suivre la philosophie actuelle, les anciennes directives ( RefererLog, AgentLog et CookieLog ) ont été remplacées par le module mod_log_config. Pour illustrer tout cela, nous avons pris .site.authent et l’avons copié dans .site.logging afin de pouvoir faire nos essais. Le fichier de configuration contient les lignes suivantes :
User webuser
Group webgroup
ServerName www.butterthlies.com
IdentityCheckon
NameVirtualHost 192.168.123.2
<VirtualHost www.butterthlies.com>
LogFormat "customers: host %h, logname %l, user %u, time %t,
request %r, status %s,bytes %b,"
CookieLog logs/cookies
ServerAdmin sales@butterthlies.com
DocumentRoot /usr/www/APACHE3/site.logging/htdocs/customers
ServerName www.butterthlies.com
ErrorLog /usr/www/APACHE3/site.logging/logs/customers/error_log
TransferLog /usr/www/APACHE3/site.logging/logs/customers/access_log
ScriptAlias /cgi_bin /usr/www/APACHE3/cgi_bin
</VirtualHost>
<VirtualHost sales.butterthlies.com>
LogFormat "sales: agent %{httpd_user_agent}i, cookie: %{http_Cookie}i,
referer: %{Referer}o, host %!200h, logname %!200l, user %u, time %t,
request %r, status %s,bytes %b,"
CookieLog logs/cookies
ServerAdmin sales_mgr@butterthlies.com
DocumentRoot /usr/www/APACHE3/site.logging/htdocs/salesmen
ServerName sales.butterthlies.com
ErrorLog /usr/www/APACHE3/site.logging/logs/salesmen/error_log
TransferLog /usr/www/APACHE3/site.logging/logs/salesmen/access_log
ScriptAlias /cgi_bin /usr/www/APACHE3/cgi_bin
<Directory /usr/www/APACHE3/site.logging/htdocs/salesmen>
AuthType Basic
AuthName darkness
AuthUserFile /usr/www/APACHE3/ok_users/sales
AuthGroupFile /usr/www/APACHE3/ok_users/groups
require valid-user
</Directory>
<Directory /usr/www/APACHE3/cgi_bin>
AuthType Basic
AuthName darkness
AuthUserFile /usr/www/APACHE3/ok_users/sales
AuthGroupFile /usr/www/APACHE3/ok_users/groups
#AuthDBMUserFile /usr/www/APACHE3/ok_dbm/sales
#AuthDBMGroupFile /usr/www/APACHE3/ok_dbm/groups
require valid-user
</Directory>
</VirtualHost>
Ce fichier de configuration utilise de nouvelles directives.
ErrorLog
ErrorLog fichier |syslog[: facility ]
Valeur par défaut : logs/error_log
Configuration du serveur, hôte virtuel.
Cette directive indique le nom du fichier dans lequel le serveur inscrira les erreurs qu’il rencontre. Si ce nom ne commence pas par une barre de fraction ( / ), il est supposé relatif à la racine du serveur.
Si ce nom de fichier commence par une barre droite ( | ), ce qui suit sera interprété comme une commande devant gérer le log des erreurs, envoyées sur son entrée standard.
Apache 1.3 et versions antérieures
L’utilisation du mot-clé syslog au lieu d’un nom de fichier active la gestion des logs par syslogd(8), si le système le permet. En ce cas, le comportement par défaut consiste à utiliser la facility local7 de syslog, mais vous pouvez modifier cela en utilisant la syntaxe syslog: facility, où facility peut être l’un des noms généralement documentés dans la page de manuel syslog(1). L’utilisation de syslog vous permet de centraliser les logs de plusieurs serveurs, ce qui peut être intéressant sur de grosses installations.
Si les répertoires contenant les fichiers logs peuvent être modifiés par un utilisateur différent de celui qui a lancé le serveur, votre sécurité peut être compromise.
TransferLog
TransferLog [ fichier | "| commande "]
Valeur par défaut : aucune
Configuration du serveur, hôte virtuel.
Cette directive précise le fichier dans lequel seront mémorisés les accès au site. En son absence, aucun log ne sera produit.
fichier
Nom de fichier relatif à la racine du serveur s’il ne débute pas par une barre de fraction, ou chemin absolu sinon.
commande
Notez le format : "| commande ". Les apostrophes doubles sont obligatoires. commande est un programme qui recevra les informations de log sur son entrée standard. Un nouveau programme ne sera pas lancé pour un hôte virtuel si celui-ci hérite de la directive TransferLog du serveur principal. Lorsqu’un programme est utilisé, il s’exécute avec les permissions de l’utilisateur qui a lancé Apache : comme il s’agit de root si c’est ce dernier qui a lancé le serveur, assurez-vous que ce programme ne contienne pas de faille de sécurité. rotatelogs, qui se trouve dans le sous-répertoire support de la distribution Apache, est un exemple de programme Unix utile dans ce contexte : il ferme le log a intervalles réguliers et en lance un nouveau, ce qui permet un archivage et le traitement des anciens logs (généralement, on effectue cette tâche en arrêtant Apache, et en déplaçant les logs ailleurs avant de le redémarrer, ce qui n’est évidemment pas amusant pour les clients connectés à ce moment là !).
AgentLog
AgentLog fichier
Valeur par défaut : logs/agent_log
Configuration du serveur, Hôte virtuel.
Cette directive n’existe pas dans Apache 2.
La directive AgentLog précise le nom du fichier dans lequel le serveur enregistrera l’en-tête User-Agent des requêtes qui lui parviennent. fichier peut avoir l’une des formes suivantes :
Un nom de fichier.
Un nom de fichier relatif à la racine du serveur, ServerRoot.
"| <commande>"
La troisième forme donne le nom d’un programme qui recevra les informations sur son entrée standard. Il n’y aura pas d’exécution d’un nouveau programme pour un hôte virtuel si celui-ci hérite de la directive AgentLog du serveur principal.
Si un programme est utilisé, il s’exécute sous les droits de l’utilisateur qui a lancé httpd. Il s’agira donc de root si c’est lui qui a lancé Apache : assurez-vous que ce programme ne contienne pas de faille de sécurité.
Consultez également le document sur la sécurité d’Apache, que nous présentons au chapitre 11 : vous y trouverez des détails sur les raisons pour lesquelles la sécurité peut être compromise, si le répertoire contenant les fichiers log est accessible en écriture par un autre utilisateur que celui ayant démarré le serveur.
Cette directive existe pour des raisons de compatibilité avec la version 1.4 du serveur NCSA.
LogLevel
LogLevel niveau
Valeur par défaut : error
Configuration du serveur, hôte virtuel.
LogLevel contrôle le volume des informations stockées dans le fichier log des erreurs. Les différents niveaux possibles sont :
emerg
Le système est inutilisable -- il s’arrête. Par exemple :
"Child cannot open lock file. Exiting"
alert
Une action immédiate est nécessaire. Par exemple :
"getpwuid: couldn’t determine user name from uid"
crit
Conditions critiques. Par exemple :
"socket: Failed to get a socket, exiting child"
error
Le client n’obtient pas un service correct. Par exemple :
"Premature end of script headers"
warn
Problèmes non critiques, mais qui peuvent mériter l’attention de l’administrateur. Par exemple :
"child process 1234 did not exit, sending another SIGHUP"
notice
Événements normaux, qui peuvent nécessiter une évaluation de la part de l’administrateur. Par exemple :
"httpd: caught SIGBUS, attempting to dump core in ..."
info
Informations générales, parfois utiles à l’administrateur. Par exemple :
"Server seems busy, (you may need to
increase StartServers,
or Min/MaxSpareServers)..."
debug
Événements normaux, mémorisés pour le débogage.
Chaque niveau signalera les erreurs qui auraient été signalées par les niveaux supérieurs. Utilisez debug pour la mise en place, puis passez à crit lors de la mise en production, par exemple. N’oubliez pas que si chaque accès à un site chargé entraîne l’inscription d’une ligne dans le fichier log des erreurs, le disque dur se remplira vite et bloquera tout le système.
LogFormat
LogFormat chaîne_format [nom]
Valeur par défaut : "%h %l %u %t \"%r\" %s %b"
Configuration du serveur, hôte virtuel.
LogFormat configure l’information à inclure dans le fichier log, ainsi que la façon de l’écrire. Le format par défaut est le CLF ( Common Log Format ), qui est attendu par les analyseurs de log comme wusage ( http://www.boutell.com/ ) ou ANALOG ; si vous comptez utiliser l’un d’entre eux, ne touchez pas à cette directive. Le format CLF est le suivant :
hôte ident utilisateur date requête code-état nb-octets
hôte
Le nom d’hôte ou l’adresse IP du client.
ident
Si la directive IdentityCheck a été activée et que la machine cliente fait fonctionner identd, il s’agit de l’identité signalée par le client (cela peut poser des problèmes de performances car le serveur lance des requêtes identd qui peuvent, ou non, obtenir une réponse).
utilisateur
Si la requête concernait un document protégé par mot de passe, il s’agit de l’ID de l’utilisateur.
date
La date et l’heure de la requête, au format suivant :
[ jour / mois / année:heure:minutes:secondes décalage_horaire ].
requête
La ligne de requête du client, entre apostrophes doubles.
code-état
Le code d’état sur trois chiffres renvoyé au client.
nb-octets
Le nombre d’octets renvoyés, sans compter les en-têtes.
Ce format peut être personnalisé à l’aide d’une chaîne_format contenant des commandes de la forme %[ condition ] lettre ; la condition est facultative, si elle est présente et qu’elle n’est pas vérifiée, le résultat est le caractère -. Les lettre s peuvent être :
%...a : Adresse IP distante.
%...A : Adresse IP locale.
%...B : Nombre d’octets envoyés, sans compter les en-têtes HTTP.
%...b : Nombre d’octets envoyés, sans compter les en-têtes HTTP,
au format CLF (si aucun octet n’est
envoyé, présence
d’un '-' à la place du 0).
%...{Truc}C : Contenu du cookie «Truc» dans la requête envoyée au serveur.
%...D : Temps mis pour honorer la requête, en micro-secondes.
%...{TRUC}e : Contenu de la variable d’environnement TRUC.
%...f : Nom de fichier.
%... h : Hôte distant.
%... H : Protocole de la requête.
%...{Truc}i : Contenu de l’entête Truc: dans la requête envoyée au serveur.
%...l : Utilisateur distant (fourni par identd, si disponible).
%...m : Méthode de la requête.
%...{Truc}n : Contenu de la note «Truc» d’un autre module.
%...{Truc}o : Contenu de l’en-tête Truc: de la réponse.
%...p : Port canonique du serveur honorant la requête.
%...P : ID du processus fils qui a traité la requête.
%...q : Chaîne de requête (précédée d’un
? s’il y en a une,
chaîne vide sinon).
%...r : Première ligne de la requête.
%...s : Statut. Dans le cas des requêtes redirigées en interne,
il s’agit du statut de la requête «initiale» ---
%...> s pour la dernière.
%...t : Heure, au format CLF (format anglais standard).
%...{format}t : Heure au format indiqué,
qui doit respecter le format décrit
dans strftime(3) (éventuellement localisé).
%...T : Temps mis pour honorer la requête, en secondes.
%... u : Utilisateur distant (fourni par les informations
d’authentification HTTP). Il peut être
erroné si le code
d’état (%s) vaut 401.
%...U : L’URL demandée, dont aura été
exclu une éventuelle chaîne
de requête.
%...v : Nom canonique du serveur honorant la requête.
%... V : Nom du serveur, en fonction de
la configuration
de UseCanonicalName.
%...X : État de la connexion à la fin de
la réponse. 'X' = connexion
interrompue avant la fin de la réponse. '+' = la connexion
pourra
être maintenue après l’envoi de la réponse. '-' = la
connexion
sera fermée après l’envoi de la réponse. Dans les
anciennes
versions d’Apache 1.3, cette directive s’appelait %...c,
mais cela entrait en conflit avec la syntaxe %...{var}c de SSL.
La chaîne de format peut contenir un texte ordinaire quelconque en plus des directives %.
Cette directive permet également de donner un nom à un format. Ce nom pourra ensuite être utilisé par des directives LogFormat ou CustomLog, ce qui évitera de devoir répéter la chaîne de format complète. Une directive LogFormat définissant un nom ne fait rien d’autre -- elle se contente de définir ce nom, elle n’applique pas le format et n’en fait pas le format par défaut. Par conséquent, elle n’affectera pas les directives TransferLog qui suivent.
Par exemple :
LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common
CustomLog
CustomLog fichier format | nom
Configuration du serveur, hôte virtuel.
Le premier paramètre de cette directive est le nom du fichier dans lequel s’incriront les messages de log. Il est utilisé exactement de la même façon que le paramètre de TransferLog : il s’agit donc d’un chemin absolu ou relatif à la racine du serveur, ou encore d’un renvoi vers un programme.
Le paramètre format indique le format des lignes du fichier log. Les possibilités sont exactement les mêmes que pour la directive LogFormat. Si ce format contient des espaces (ce qui est quasiment toujours le cas), il doit être entouré d’apostrophes doubles.
Au lieu d’utiliser une chaîne de format, vous pouvez également utiliser un nom de format défini préalablement par la directive LogFormat.
site.authent -- un autre exemple
site.authent est configuré avec deux hôtes virtuels : un pour les clients, l’autre pour les vendeurs et chacun d’eux a ses propres fichiers log, respectivement dans les répertoires ... /logs/customers et ... /logs/salesmen. Nous pouvons suivre ce schéma et appliquer un même LogFormat aux deux, ou faire en sorte que chacun ait un LogFormat différent en plaçant cette directive dans les conteneurs <VirtualHost>. Ces deux hôtes peuvent également partager certains fichiers log : pour ce faire, les directives ErrorLog et TransferLog ont été sorties des conteneurs <VirtualHost> (comme les formats de logs sont différents, les entrées pourront quand même être différenciées). Dans ce cas, les directives LogFormat seront de la forme :
<VirtualHost www.butterthlies.com>
LogFormat "Clients:..."
...
</VirtualHost>
<VirtualHost sales.butterthlies.com>
LogFormat "Vendeurs:..."
...
</VirtualHost>
Essayons un format pour les clients, en ne touchant pas au reste :
<VirtualHost www.butterthlies.com>
LogFormat "Clients: hôte %h, nom %l, utilisateur %u, date %t,
requête %r statut %s, nb-octets %b,"
...
Nous avons inséré les mots hôte, nom, etc. pour bien montrer qui fait quoi. En pratique, vous ferez sûrement en sorte de ne pas gonfler inutilement les fichiers log car vous les consulterez régulièrement et vous vous rappellerez le format de leurs entrées ou, ce qui est plus probable, vous traiterez ces fichiers à l’aide d’un programme qui en connaîtra le format. Une connexion à www.butterthlies.com et une visite du catalogue été produira ce fichier log :
Clients: hôte 192.168.123.1, nom unknown, utilisateur -, date [07/Nov/
1996:14:28:46 +0000], requête GET / HTTP/1.0, statut 200, nb-octets -
Clients: hôte 192.168.123.1, nom unknown, utilisateur -, date [07/Nov/
1996:14:28:49 +0000], requête GET /hen.jpg HTTP/1.0, statut 200,
nb-octets 12291,
Clients: hôte 192.168.123.1, nom unknown, utilisateur -, date [07/Nov /
1996:14:29:04 +0000], requête GET /tree.jpg HTTP/1.0, statut 200,
nb-octets 11532,
Clients: hôte 192.168.123.1, nom unknown, utilisateur -, date [07/Nov/
1996:14:29:19 +0000], requête GET /bath.jpg HTTP/1.0, statut 200,
nb-octets 5880,
Ce fichier n’est pas très difficile à lire. Vous remarquerez que, bien que le nom soit unknown, l’ utilisateur est -, ce qui correspond au résultat conventionnel indiquant une valeur inconnue. En effet, les clients n’ont pas besoin de produire un identifiant ; pour les vendeurs, qui doivent s’identifier, il y aurait une valeur ici.
Nous pouvons améliorer cela en insérant des listes de conditions utilisant les codes d’erreurs : elle seront placées entre le % et la lettre indiquant le format. Les codes d’erreur définis dans la spécification de HTTP 1.0 sont :
200 OK
302 Found
304 Not Modified
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not found
500 Server error
503 Out of resources
501 Not Implemented
502 Bad Gateway
Les codes d’erreurs de HTTP 1.1 sont les suivants :
100 Continue
101 Switching Protocols
200 OK
201 Created
202 Accepted
203 Non-Authoritative Information
204 No Content
205 Reset Content
206 Partial Content
300 Multiple Choices
301 Moved Permanently
302 Moved Temporarily
303 See Other
304 Not Modified
305 Use Proxy
400 Bad Request
401 Unauthorized
402 Payment Required
403 Forbidden
404 Not Found
405 Method Not Allowed
406 Not Acceptable
407 Proxy Authentication Required
408 Request Time-out
409 Conflict
410 Gone
411 Length Required
412 Precondition Failed
413 Request Entity Too Large
414 Request-URI Too Large
415 Unsupported Media Type
500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Time-out
505 HTTP Version not supported
Vous pouvez préfixer un code par ! pour signifier « si ce n’est pas ce code ». Ainsi, !200 signifie « inscrire cette opération si la réponse n’était pas OK. ». Utilisons ce mécanisme pour les vendeurs :
<VirtualHost sales.butterthlies.com>
LogFormat "Vendeurs: hôte %!200h, nom %!200l, utilisateur %u, date %t,
requête %r, statut %s, nb-octets %b,"
...
Une tentative de connexion sous le compte fred avec le mot de passe toto produira la ligne suivante :
Vendeurs: hôte 192.168.123.1, nom unknown, utilisateur fred, date [19/Aug/
1996:07:58:04 +0000], requête GET HTTP/1.0, status 401, nb-octets -
Cependant, si l’infâme bill s’était connecté avec le mot de passe voleur, nous aurions vu :
hôte -, nom -, utilisateur bill, ...
car nous avons demandé l’enregistrement de hôte et nom uniquement si la requête n’a pas renvoyé OK. Nous pouvons combiner plusieurs conditions ; par exemple, si nous ne souhaitons connaître que les problèmes de sécurité sur le site des vendeurs, nous pouvons n’enregistrer que les noms des utilisateurs n’ayant pas réussi à s’authentifier :
LogFormat "Vendeurs: utilisateur incorrect: %400,401,403u"
Nous pouvons également extraire des données des en-têtes HTTP dans les deux directions :
%[condition]{user-agent}i
Cela permet d’afficher l’agent utilisateur (c’est-à-dire le logiciel qu’emploie l’utilisateur) si condition est vérifiée. L’ancienne méthode consistait à utiliser AgentLog fichier et ReferLog fichier.