nox.im · All Posts · All in OpenBSD · All in Web
With Google Analytics, you allow Big Tech to monetize your visitors. Privacy and minimalism doesn’t mix well with tracking, privacy intrusions and bloated Javascript clients. Server side analytics utilize only log files for basic insights into visitors and hits. GoAccess is one such tool that does log file parsing and deals with the presentation of the data that we use in the following.
Unlike the name suggests, GoAccess isn’t written in Go, but C. The tradeoff with log parsing is that we don’t get nearly as much information as Google Analytics-style system. There’s no screen sizes, no time-on-page metrics, etc, but it doesn’t require any Javascript, no cookie or GDPR notice and is sufficient for most use cases.
The setup consists of an OpenBSD
httpd web server, a Tor
Onion
hidden service
and the Gemini protocol gmifs
server, from previous
articles. All of these produce logs which we can combine in a single, statically
generated HTML dashboard that we serve publicly under /stats/
. That’s right,
with everything else being open on this web log I do publish my web analytics
with anonymized IPs, except for crawlers, publicly.
Ensure you have set the log style to combined, an extension to Common Log Format with referrer and user-agent fields for our primary www server.
server "nox.im" {
...
log style combined
Log the hidden service access logs into a custom file, naturally we won’t get IP address or referrers from Tor.
server "noximhkcqevri46e2kuthman5o6emplfcevppx3hvsvu55qcygj5elyd.onion" {
...
log access onion.log
Gemini gmifs logs are under
/var/www/logs/gemini/access.log
. We don’t get http status codes but can ingest
hits for Gemini. For this I now log with a gemini.nox.im
prefix to get the
hostname right.
Install GoAccess
pkg_add goaccess
Edit /etc/goaccess/goaccess.conf
for global configuration. The primary www web
server has these settings:
# httpd(8) combined log format
date-format %d/%b/%Y
time-format %T %z
log-format %v %h %^ %^ [%d:%t] "%r" %s %b "%R" "%u"
# privacy for visitors identities
anonymize-ip true
# keep stats between runs
persist true
restore true
# ignore some panels I don't need
ignore-panel VISIT_TIMES
ignore-panel VIRTUAL_HOSTS
ignore-panel STATUS_CODES
I copy the file to /etc/goaccess/goaccess.gmi.conf
and
/etc/goaccess/goaccess.onion.conf
.
For the hidden service I’m using the same combined log format above. For
gmifs@1.0.2
I’m using the common log format and exclude the status code:
# httpd(8) common log format
date-format %d/%b/%Y
time-format %T %z
log-format %v %h %^ %^ [%d:%t] "%r" %^ %b
All other options will be set with command line arguments.
We will keep all stats under /var/db/goaccess/nox.im/
.
mkdir -p /var/db/goaccess/nox.im
chown daemon /var/db/goaccess/nox.im
I copy the following script to /usr/local/bin/goaccess-nox.im
. Note that I’m
excluding the IP of the box that runs this blog as well as localhost for the
hidden service hits. I’m also excluding my static exit IPs from my WireGuard
VPN, not listed here.
doas vi /usr/local/bin/goaccess-nox.im
doas chmod +x /usr/local/bin/goaccess-nox.im
#!/bin/sh
/usr/local/bin/goaccess $1 \
-p $2 \
-o /var/www/htdocs/nox.im/stats/index.html \
--exclude-ip 127.0.0.1 \
--exclude-ip 45.76.221.230 \
--db-path=/var/db/goaccess/nox.im \
--html-report-title="nox.im stats"
And run it with an @hourly
cron for the www, the hidden service and the gemini server:
# vi /var/cron/tabs/root
0 * * * * /usr/local/bin/goaccess-nox.im /var/www/logs/access.log /etc/goaccess/goaccess.conf > /dev/null 2>&1
0 * * * * /usr/local/bin/goaccess-nox.im /var/www/logs/onion.log /etc/goaccess/goaccess.onion.conf > /dev/null 2>&1
0 * * * * /usr/local/bin/goaccess-nox.im /var/www/logs/gemini/access.log /etc/goaccess/goaccess.gmi.conf > /dev/null 2>&1
In order to ensure we generate the report before log rotations executes, prefix the entries in /etc/newsyslog.conf
:
/var/www/logs/access.log 644 4 * $W0 Z "/usr/local/bin/goaccess-nox.im /var/www/logs/access.log /etc/goaccess/goaccess.conf && pkill -USR1 -u root -U root -x httpd"
/var/www/logs/gemini/access.log 644 4 * $W0 Z "/usr/local/bin/goaccess-nox.im /var/www/logs/gemini/access.log /etc/goaccess/goaccess.gmi.conf && pkill -USR1 -u root -U root -x gmifs"
Boom. We now get quite exhaustive web stats statically generated at /stats/
.