%

Goaccess / OpenBSD

Article publié, le et modifié le
11 minutes de lecture

Cet article contient 2221 mots.
Source brute de l'article :
Commit version : 36e3c52

Description

Goaccess est un logiciel libre, réputé pour être léger, rapide, afin d’analyser en temps réel ou non l’activité sur un serveur web, soit directement au sein d’un terminal Unix, soit sur le protocol HTTPS.

Il est capable de produire des statitisques au format HTML, JSON, voire CSV.


⇒ Environnement :

  • OpenBSD : 6.9 → 7.1

Installation

Classique : # pkg_add goaccess

Configuration

  • Le fichier de configuration principal est : /etc/goaccess/goaccess.conf.

⇒ Il est possible sans aucun soucis d’utiliser goaccess avec son fichier de configuration sans rien modifier. Cela nécessite de passer toutes les options nécessaires dans la ligne de commande, hors certaines options sont clairement communes et peuvent être “figées” dans la configuration commune.

⇒ Il est aussi possible de créer plusieurs fichiers de configuration, chacun spécifique à un domaine web et de paramètrer selon le domaine. Dans ce cas-là, il faudra cibler tel fichier de configuration.

Dans la suite de cet article, j’utilise un seul fichier de configuration, et je cible quelques options dans la ligne de commande.

Voyons les principales options de configuration :

Time, Date format

Le formatage de l’heure !

⇒ Si vous utilisez le service httpd, il faudra faire attention à paramètrer correctement le style de log dans son propre fichier de configuration, et de le répercuter dans le fichier de configuration de goaccess dans la section Time Format Options.

⇒ Pour nginx, il suffira de décommenter les options suivantes :

  • time-format %H:%M:%S
  • date-format %d/%b/%Y - ce dernier étant dans la section Date Format Options

Log format

  • log-format : préférez le format COMBINED - sauf si concernant httpd, vous en restez au format common, dans ce cas choisissez l’équivalent.

Si vous utilisez nginx, il est impératif d’enregistrer tous les statuts, de ne pas filter les statuts 2xx et 3xx - si vous aviez créer une directive map en ce sens, il vous faudra à minima la commenter puis relancer le service web.

File Options

Si vous n’avez qu’un seul domaine web sur votre serveur à analyser, il est utile de paramètrer l’option log-file vers le chemin absolu du fichier access.log relatif.

Parse Options

  • exclude-ip : n’hésitez pas à utiliser cette option pour exclure de l’analyse soit des adresses IP, soit des segments réseaux, tel votre réseau personnel, si votre serveur est par exemple à domicile.

  • 444-as-404 : l’erreur 444 est spécifique au serveur Nginx. À vous de voir, si vous voulez que ces erreurs soient considérées comme étant des entrées d’erreur 404. Si oui, changez la en true.

  • ignore-crawlers : afin d’ignorer les robots ; changez la à true

  • ignore-panel est un ensemble de panneau qui peut être désactivé (voire activé) ; pour des histoires de RGPD, mieux vaut désactiver le panneau REMOTE_USER

  • anonymize-ip : changez-la à true - en ces temps de RGPD, il vaut mieux !

Persistence Options

  • db-path : le chemin /absolu vers la base de données de goaccess - à ne configurer que s’il y a un seul domaine.
  • persist : permet d’enregistrer les données analysées
  • restore : charge les données à visualiser depuis les données enregistrées.

⇒ Activer les deux dernières options en positionnant sur true, si vous voulez garder les enregistrements de l’analyse dans la base de donnée de goaccess.


Alors, bien sûr, comme vous le verrez, il existe beaucoup d’autres options. À vous de voir…

Ensuite il suffit d’utiliser basiquement le binaire goaccess.


Maintenant, poussons un peu plus la configuration :

Utilisateur dédié

Personnellement je préfère créer et utiliser un utilisateur système dédié. Parmi les avantages, citons la recherche dans les log messages, voire cron.

# useradd -s /sbin/nologin -d /var/db/goaccess _goaccess

⇒ la recherche dans les logs se faisant ainsi :

$ grep goaccess /var/log/messages ou $ doas grep _goaccess /var/cron/log

doas

⇒ J’ai préféré ajouter l’autorisation d’utiliser le binaire goaccess à l’utilisateur _goaccess.

Ajoutez à votre fichier /etc/doas.conf :

permit nopass _goaccess cmd /usr/local/bin/goaccess

(J’avoue, je ne suis pas sûr que ce soit réellement nécessaire car le binaire goaccess semble s’exécuter sans droit particulier).

Répertoire de la base de données

⇒ Création du répertoire principal pour la base de données de goaccess :

# mkdir -p /var/db/goaccess
# chown _goaccess:daemon /var/db/goaccess

(personnellement, j’ai préféré un autre chemin absolu).

Pensez à ajouter ce répertoire dans vos sauvegardes !


Ensuite si comme moi, vous avez plusieurs domaines web sur votre serveur, créez autant de sous-répertoire portant le nom du domaine web, tel que :

$ domain=
$ doas -u _goaccess mkdir "/var/db/goaccess/${domain}"

Ainsi, les futures statistiques seront vraiment dédiés à un domaine…

crontab

⇒ Il ne reste plus qu’à ajouter autant de règles cron que nécessaire, tel que :

$ doas -u _goaccess crontab -e 

(Il est possible d’appeler la crontab utilisateur, tel que : doas crontab -u _goaccess -e).

Pour ajouter :

*/15 * * * * -ns goaccess -a --db-path "/var/db/goaccess/domain/" -f /var/www/logs/domain/access.log -o /var/www/goaccess/domain/stats.html

Petites explications :

  • une tâche cron programmée pour être exécutée tous les quarts d’heure. Gardez à l’esprit que c’est un exemple.
  • remplacez la chaine ‘domain’ par le nom de domaine web…

Authentification requise

À vous de voir si vous désirez une authentification web avant la consultation des pages HTML ; d’aucuns estiment qu’il le faut, d’autres non ; personnellement je préfère.

Après l’utilisation du binaire htpasswd, elle se configure au-niveau du fichier de configuration de votre serveur web.

  • pour httpd, c’est la directive authenticate qui servira.
  • pour nginx, ce sont les directives auth_basic et auth_basic_user_file qui répondront au besoin.

Configuration httpd

De manière basique :

server "domain.tld" {

(…)

	root "/htdocs/domain.tld/www"
	
	location "/stats" {
		authenticate with "/file_htpwd"
		directory auto index
	}

(…)

}

Ne pas oubliez que le chemin du fichier htpasswd est relatif au chroot web !

Configuration nginx

Idem, basiquement :

(…)

location /stats/ {
    auth_basic "Auth Area";
    auth_basic_user_file /file_htpwd;    
    autoindex on;
}

(…)

Voilà pour la partie “configuration” !


Utilisation

Utilisation basique

Basiquement le binaire s’exécute ainsi :

$ goaccess -o /var/www/htdocs/domain.tld/stats/index.html

Par l’utilisateur dédié

⇒ Une fois configuré, goaccess s’utilise ainsi :

Par exemple, une première fois, en précisant une date de mois-année :

$ domain=
$ date="$(date +'%Y-%m')"
$ doas -u _goaccess goaccess -a --db-path "/var/db/goaccess/${domain}/" -f "/var/www/logs/${domain}/access.log" -o "/var/db/goaccess/${domain}/stats-${domain}-${date}.html"

Je me suis créé un script shell pour me faciliter la vie - nommé goaccess.sh :

#!/bin/sh

###
#
# générer les stats du domain
#
##

date="$(date +'%m-%Y')"
dir_db="/var/db/goaccess"
domain="$1"

if [ -z "${domain}" ]; then 
	printf '%s %s\n' "KO" "No domain. Script stops!"
	logger "$0: no domain found as option; script stops!"
	exit 1
fi

if [ ! -d "${dir_db}/${domain}/" ]; then
	printf '%s %s\n' "KO" "The destination directory '${dir_db}/${domain}/' seems not exist!"
	logger "$0: The destination directory for goaccess not exists; script stops!"
	exit 2
fi

goaccess -a --db-path "${dir_db}/${domain}/" -f "/var/www/logs/${domain}/access.log" -o "${dir_db}/${domain}/stats-${domain}-${date}.html"

Puis modifié la crontab de l’utilisateur _goaccess :

*/15 * * * * -ns /repertoire/goaccess.sh domain-x.tld
0    * * * * -ns /repertoire/goaccess.sh domain-y.tld
0    0 * * * -ns /repertoire/goaccess.sh domain-z.tld

(chacun à des moments différents).


Et non ce n’est pas fini !

En effet, le fichier d’analyse HTML généré est écrit dans le répertoire de base de données dédié. L’utilisateur _goaccess n’a pas accès au(x) répertoire(s) web, et n’a pas avoir accès.

Par contre, il est possible de demander à l’utilisateur web www de copier le fichier de statistiques HTML pour le déposer dans le répertoire web correspondant.

Ainsi, j’utilise le script shell suivant, nommé cp_stats.sh :

#!/bin/sh

set -e
#set -x

###
#
# copier les stats d'un domaine pour les publier enligne
#
##

date="$(date +'%m-%Y')"
domain="$1"
dir_db="/var/db/goaccess"
dir_stats="/var/www/htdocs/${domain}/www/stats/"

if [ -z "${domain}" ]; then 
	printf '%s %s\n' "KO" "No domain. Script stops!"
	logger "$0: no domain found as option; script stops!"
	exit 1
fi

if [ ! -f "${dir_db}/${domain}/stats-${domain}-${date}.html" ]; then
	printf '%s %s\n' "KO" "The needed file '${dir_db}/${domain}/stats-${domain}-${date}.html' not exists. Script stops!"
	logger "$0: The needed file '${dir_db}/${domain}/stats-${domain}-${date}.html' not exists; script stops!"
	exit 2
fi

if [ ! -d "${dir_stats}" ]; then mkdir -p "${dir_stats}"; fi

cp "${dir_db}/${domain}/stats-${domain}-${date}.html" "${dir_stats}"
chown -R www "${dir_stats}"

Puis à modifier la crontab de l’utilisateur web :

$ doas -u www crontab -e

Tel que, pour l’exemple :

*/15 * * * * -ns /repertoire/cp_stats.sh domain-x.tld
5    * * * * -ns /repertoire/cp_stats.sh domain-y.tld
5    0 * * * -ns /repertoire/cp_stats.sh domain-z.tld

Utilisation temps réel

L’utilisation temps réel se fait de deux manières possibles.

Dans ces contextes, nous n’aurons pas besoin de l’utilisateur dédié _goaccess.

par terminal

⇒ À minima, faites :

$ goaccess -f /var/www/logs/${domain}/access.log

Profitez de l’esthétique vue basée sur les couleurs monokaï, par défaut.

par proxy web

Là, ça devient intéressant, mais un peu compliqué :

proxy httpd

Là, malheureusement, je n’ai pas trouvé de solution. Voire avec relayd!

proxy nginx

Modifions la configuration du serveur en ajoutant une directive location :

location /ws {
        proxy_pass http://localhost:7890;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
}
websocket

Maintenant il faut exécuter goaccess avec les droits de l’utilisateur www :

$ doas -u www goaccess -p /etc/goaccess/goaccess.realtime.conf -o /var/www/htdocs/huc.fr.eu.org/www/stats/realtime.html --ws-url=wss://huc.fr.eu.org:443/ws --port 7890
 [PARSING /var/www/logs/doc.huc.fr.eu.org/access.log] {0} @ {0/s}
WebSocket server ready to accept new client connections

Remarquez que pour ce test, j’ai :

  • créer un nouveau fichier de configuration pour goaccess nommé goaccess.realtime.conf
  • je lui demande de créer le fichier HTML
  • et d’écouter le serveur sur le websocket sécurisé

Du fait d’être obligé d’utiliser l’utilisateur web, nous pouvons en temps réel, surveillez dans une console SSH, l’activité de l’utilisateur, avec des binaires tels fstat, ps, par exemple :

$ fstat -u www -n
USER     CMD          PID   FD  DEV      INUM        MODE   R/W    SZ|DV
www  goaccess   76729   wd  4,15   725760        40755    r      512
www  goaccess   76729    0  4,0     78329        20620   rw    5,0  
www  goaccess   76729    1  4,0     78329        20620   rw    5,0  
www  goaccess   76729    2  4,0     78329        20620   rw    5,0  
www  goaccess   76729    3  4,3       175        10644   rw        0
www  goaccess   76729    4  4,3       176        10644   rw        0
www  goaccess   76729    5  4,3       175        10644    w        0
www  goaccess   76729    6  4,3       176        10644    w        0
www  goaccess   76729    7 pipe 0x0 state: 
www  goaccess   76729    8 pipe 0x0 state: 
www  goaccess   76729    9* internet stream tcp 0x0 *:7890
www  goaccess   76729   10 pipe 0x0 state: 
www  goaccess   76729   11 pipe 0x0 state: 
www  goaccess   76729   12* internet stream tcp 0x0 127.0.0.1:7890 <-- 127.0.0.1:6459

$ ps aux -U www
USER       PID %CPU %MEM   VSZ   RSS TT  STAT   STARTED       TIME COMMAND
www   4071  0.0  0.1  1572  3488 ??  S      10:12AM    0:00.88 sshd: www@notty (sshd)
www  76729  0.0  0.3 10096 12752 p0  S+      7:56PM    0:01.49 goaccess -p /etc/goaccess/goaccess.realtime.conf -o /var/www/htdocs/huc.fr.eu.org/www/stats/realtime.html /var/www/logs/do

Il ne reste plus qu’à pointer un navigateur web le chemin du fichier realtime.html.

dashboard goaccess real time
dashboard goaccess real time

Remarquez le petit point vert sous l’icône en forme de roue crantée, en haut à gauche de l’écran.

Il semble nécessaire de rafraîchir soit même la page ; au bout de temps d’un certain temps, elle perd le connecteur. Un petit coup de F5


Pour finir, on peut s’amuser à exécuter goaccess en tant que service, soit en utilisant l’option –daemonize, soit en configurant le fichier de configuration dédiée.

$ doas -u www goaccess --daemonize -p /etc/goaccess/goaccess.realtime.conf -o /var/www/htdocs/huc.fr.eu.org/www/stats/realtime.html --ws-url=wss://huc.fr.eu.org:443/ws --port 7890
Daemonized GoAccess: 48646

Cette option ne fonctionne qu’avec l’option de temps réel active.

De même, il est impératif que l’utilisateur web est accès au chemin qui enregistrera le fichier de processus PID - autrement vous serez en échec ! Il faut donc paramètrer l’option pid-file dans le fichier de configuratin.

Sous OpenBSD, pour rappel, du fait du chroot web, c’est le répertoire /var/www/run par défaut - préférez un sous-répertoire dédié à l’utilisateur www.


Bien-sûr, tout cela, c’est pour le FUN, et l’exemple ! :D


Voilà !

(C’est mon expérience… et la vôtre !?)

Dépannages

Voici quelques erreurs rencontrées :

Permission denied

  • Couldn't open file /var/db/goaccess/xxx/I32_DATES.db: Permission denied
  • Unable to open the specified pid file. Permission denied
  • Unable to open the specified pid file. Permission denied
  1. goaccess ne peut pas écrire dans le répertoire en question !
  2. Vérifiez que le répertoire cible existe…
  3. Vérifiez les droits utilisateurs ; ils doivent impérativement correspondre à celui de l’utilisateur qui exécute goaccess : _goaccess:daemon

Ce problème est identique lors de la génération des fichiers HTML. Si les droits ne sont pas attribués à l’utilisateur _goaccess, vous ne pourrez pas les générer.

Exemple de message d’erreur :

GoAccess - version 1.5.1 - Sep 26 2021 14:08:19
Config file: /etc/goaccess/goaccess.conf

Fatal error has occurred
Error occurred at: src/output.c - output_html - 1183
Unable to open HTML file: Permission denied.

Error opening the specified MaxMind DB file

GoAccess - version 1.5.5 - Apr  8 2022 09:03:43
Config file: /etc/goaccess/goaccess.conf

Fatal error has occurred
Error occurred at: src/geoip2.c - init_geoip - 89
Unable to open GeoIP2 database /var/db/GeoIP/GeoLite2-Country.mmdb: Error opening the specified MaxMind DB file

Vous avez activé certainement l’option geoip-database.

Mais avez-vous téléchargé les fichiers nécessaires et installés dans le répertoire /var/db/GeoIP/ ?

No home directory

  • Assurez-vous que le home directory déclaré pour l’utilisateur dédié existe bel et bien !

Puis vérifier l’existence du chemin dans votre système de fichiers, sans oublier que les droits utilisateurs correspondent bien à l’utilisateur dédié !

  • Accessoirement, assurez-vous de la correspondance entre le home directory de l’utilisateur dédié ET la variable dir_db du script goaccess.sh.

Documentations

Wikipédia


Enjoy-ID! Enjoy-IT!