Les journaux

Luc Didry, à partir des cours de Sébastien Jean. Licence CC-BY-SA
Did I mention? It also travels in time.
Le neuvième docteur

Télécharger le PDF

L’état et la configuration du serveur web sont des éléments importants, mais ne sont cependant pas suffisants lors de l’administration au quotidien d’un serveur web. Il est aussi nécessaire de conserver une trace de l’historique de l’activité du serveur, ainsi que de tous les problèmes rencontrés.

Il existe deux types de journaux importants :

  • les journaux de requêtes, qui contiennent les informations concernant les requêtes traitées, ainsi que les logiciels clients : le journal d’accès contient ainsi une ligne pour chaque requête traitée par le serveur ;
  • le journal d’erreurs, qui trace les anomalies observées pendant le fonctionnement.

1 Apache

1.1 Journal de requêtes

La journalisation des requêtes est assurée par le module mod_log_config1.

La directive fournie par ce module permettant d’activer l’écriture du journal est TransferLog suivie par un nom de fichier. Cette directive simple peut être avantageusement remplacée par l’utilisation combinée de LogFormat et de CustomLog.

Le format par défaut des journaux est le CLF (Common Log Format), défini de la manière suivante : hôte_distant identd utilisateur [date] "URL demandée" état taille_en_octets

Détails concernant différents champs :

hôte_distant

Adresse IP du client qui a émis la requête

identd

Nom d’utilisateur dans le cas de l’utilisation du protocole identd -- inactif habituellement, un tiret est inscrit dans ce cas

utilisateur

Nom de l’utilisateur dans le cas d’une identification HTTP -- un tiret sinon

état

code d’état HTTP à 3 chiffres

La directive LogFormat2 permet de définir le format de chaque ligne inscrite dans un journal. La directive se décompose en deux parties : une chaîne décrivant le format, et un nom (optionnel) servant à la désigner (voir la documentation3 pour la syntaxe de description du format).

LogFormat "%h %l %u %t \"%r\" %>s %b" common

La directive CustomLog4 indique le nom et l’emplacement d’un fichier journal, en permettant de spécifier éventuellement un nom de format défini auparavant. Si aucun nom de format n’est indiqué, le format utilisé est le dernier format sans nom défini, ou, à défaut, le CLF.

CustomLog /var/log/apache2/logs/access.log common

Écriture conditionnelle dans un journal Un format conditionnel existe, permettant de consigner une requête en fonction de la présence ou de l’absence d’une variable d’environnement. Ici on souhaite par exemple consigner les évènements concernant les documents flash dans un journal différent.

SetEnvIf Request_URI \.swf$ flash
CustomLog /var/log/apache2/flash.log common env=flash
CustomLog /var/log/apache2/access.log common env=!flash

Pour aller plus loin :

  • Journaux pour les hôtes virtuels : il est possible de définir un journal pour chaque hôte en redéfinissant les directives LogFormat (pas obligatoire si défini dans la configuration générale) et CustomLog dans le conteneur de l’hôte virtuel. Cette solution amène une multiplication des fichiers de journaux (ce qui peut être pratique : un site = un log, ou ennuyeux, selon ses goûts personnels). La spécification de format %v permet d’indiquer le serveur (c’est-à-dire l’hôte virtuel) qui traite la requête.
  • Suivi des sessions utilisateur : l’adresse IP est de moins en moins suffisante pour identifier un utilisateur (pare-feux, proxys, NAT…). Le module mod_usertrack lui attribue un identifiant unique au moyen de cookie. Il faut alors utiliser la directive CookieTracking positionnée à on pour suivre les utilisateurs.

1.2 Journal d’erreur

Le journal d’erreur a un fonctionnement beaucoup plus simple ques les journaux de requêtes. La directive ErrorLog5 permet de spécifier le fichier à utiliser, ou via le mot clé syslog d’appeler le démon syslogd du système. Une directive appelée LogLevel6 permet de faire varier la quantité d’informations consignées. Le niveau error est recommandé. D’autres utilisations peuvent nous amener à utiliser, du plus sélectif au plus verbeux : emerg, alert, crit, error, warn, notice, info, debug.

De même que LogFormat permet de spécifier le format des logs, il est possible de spécifier celui des logs d’erreur avec ErrorLogFormat7.

2 Nginx

2.1 Journal de requêtes

La directive log_format8 permettra, comme pour Apache, de spécifier un format de log particulier. Elle sera suivie du nom du format de log et de son formatage.

La configuration inclue toujours le format pré-défini combined qui contient les informations de l’exemble ci-dessous.

On définit un format de log ainsi :

log_format nom_format '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

Les variables utilisées dans le formatage pourront être les variables communes de Nginx9 et les variables n’existant qu’au moment de l’écriture d’un log (voir la doc de log_format).

On utilisera ensuite access_log10 pour utiliser ce format :

access_log /var/log/nginx/access_log nom_format;

Le premier argument peut correspondre au nom d’un fichier de log, de l’adresse d’un serveur syslog (avec la syntaxe syslog:server=address[,parameter=value]) ou juste off pour désactiver le logging des requêtes.

À noter qu’il n’est pas nécessaire d’indiquer le nom du format si on se contente du format combined.

Écriture conditionnelle dans un journal

On utilisera une map11 pour cela :

map $status $loggable {
    ~^[23]  0;
    default 1;
}
access_log /path/to/access.log if=$loggable;

Avec cette map, les requêtes avec un statut de réponse 2xx ou 3xx ne seront pas loguées.

Apparté : une map Nginx permet de définir une variable dont la valeur dépend de la valeur d’une ou plusieurs variables. Voyez ça comme une instruction switch en programmation12. Le premier argument d’une map est la ou les variables dont dépend la variable définie par la map (si l’on souhaite utiliser plusieurs variables, on les combinera par exemple comme ceci : "$status:$request"), et le deuxième argument est le nom de la variable à définir.

2.2 Journal d’erreur

On utilisera la directive error_log13. Le niveau de log sera passé en argument après la destination du log (fichier, serveur syslog ou un tampon mémoire) : debug, info, notice, warn, error, crit, alert, emerg. Le niveau de log par défaut est error.

error_log logs/error.log;

3 Exercices

3.1 Apache ET Nginx

Chaque question est donc à traiter deux fois.

  1. Activez les journaux : mettez en place un journal d’erreur et un journal de requêtes.
  2. Modifiez le journal de requêtes pour qu’il indique l’URL demandée ainsi que le numéro de processus fils la traitant.
  3. A l’aide d’un de vos camarades, tracez les requêtes venant d’une adresse IP particulière dans un fichier séparé (utilisé en cas d’analyses fines d’attaques) : la règle à utiliser pour Apache s’intitule Remote_Addr, pour Nginx, vous utiliserez une map.
  4. Remplissez vos journaux via l’utilisation d’un utilitaire de benchmarking comme siege, et analysez leur contenu à l’aide d’outils tel Webalizer14, AwStats15 ou tout autre outil du même type de votre choix (cherchez et proposez un comparatif des méthodes de quelques-uns de ces outils).

3.2 Apache uniquement

  1. Regardez le fonctionnement du module mod_usertrack.

https://asrall.fr