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 httpd.conf(5)#style
⇒ 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.
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
- goaccess ne peut pas écrire dans le répertoire en question !
- Vérifiez que le répertoire cible existe…
- 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 scriptgoaccess.sh
.
Documentations
-
https://www.geeek.org/goaccess-analyser-access-log/ - où j’ai piqué la config de proxy nginx
-
https://hautefeuille.eu/post/goaccess-openbsd/ : un autre exemple de configuration pour httpd, juste pour de la consultation différée.
Wikipédia
Enjoy-ID! Enjoy-IT!