Matomo vs uBlock Origin
After Ackee got an update and stopped working I wanted to search for an alternative to get some stats on my statically rendered site. As no server is used, I need some 3rd party service.
I don’t want to spy on people, nor set cookies and annoy people with consent banners if they only want to read a damn blog post. The goal is just get a feel for the traffic on the site.
This is important to mention as the next steps could sound a bit nefarious otherwise.
Data collected on this site is 100% anonymous and GDPR compliant.
Since Matomo is the de facto way to go, I spun up the Matomo server with my trusted docker-traefik setup and was up and running in no time.
( I’ll share the config files if anyone is interested at the bottom. )
Then I quickly copied the JS tracker code in my main html template and thought that was it. Wrong.
The problem defaults.
So turns out that Matomo, being widely used is of course included in many Ad-Blocker lists and therefore my stats did not work. Lets see why:
Basically all ad blockers work with lists. Those lists include pattern that if matched will be filtered out. Let’s take a look at the default Matomo tracking code:
We can see that my stats server is
stats.nicco.io. And we also can see that the tracking script is loaded by
matomo.js, which then sends the details to
matomo.php. Well that is of course incredibly easy to block, and it is as you can see below:
That won’t work, and since most of the people that visit this site are probably developers which probably have some kind of ad blocker installed.
Luckily Apache has the famous Rewrite module, which will solve all our problems. I bet most of you already know where this is headed.
We can create a
.htaccess file in the root of our Matomo installation folder, to cloak our requests.
# .htaccess RewriteEngine On RewriteRule ^unicorn matomo.js RewriteRule ^rainbow matomo.php
Now if we request
https://stats.nicco.io/unicorn we actually get the response for
https://stats.nicco.io/matomo.js and the same for
// Replace in the client _paq.push(['setTrackerUrl', u+'matomo.php']); // Before _paq.push(['setTrackerUrl', u+'rainbow']); // After g.src = u + 'matomo.js' // Before g.src = u + 'unicorn' // After
I had to create a minuscule
Dockerfile as the
Rewrite module is not enabled per default in the standard Matomo docker image.
# Dockerfile FROM matomo RUN a2enmod rewrite
Now as you can see it’s incredibly easy to mask tracking stuff, and I bet there are a lot of people doing this in the wild. It is important to respect the privacy of your users and you should never store more data than you need and in the best case don’t store data at all.
Anonymize as much as possible! Matomo makes this easy. You can effortlessly delete 2 bytes of each ip address (half of the info), enforce strict no cookie tracking and automatically delete data after
x days. Please do ❤️
Dockerfile and the
.htaccess files are shown above.
# docker-compose.yml version: "3.7" networks: traefik: external: true services: db: image: mariadb command: --max-allowed-packet=64MB restart: unless-stopped volumes: - ./data/db:/var/lib/mysql env_file: .env app: build: . restart: unless-stopped links: - db volumes: - ./data/matomo:/var/www/html - ./.htaccess:/var/www/html/.htaccess env_file: .env labels: - traefik.enable=true - traefik.docker.network=traefik - traefik.port=80 - traefik.backend=matomo - "traefik.frontend.rule=Host:stats.nicco.io;" networks: - traefik - default
# .env MYSQL_DATABASE=matomo MYSQL_USER=matomo MYSQL_PASSWORD=<random bytes> MYSQL_RANDOM_ROOT_PASSWORD=yes MATOMO_DATABASE_HOST=db MATOMO_DATABASE_ADAPTER=mysql MATOMO_DATABASE_DBNAME=matomo MATOMO_DATABASE_USERNAME=matomo MATOMO_DATABASE_PASSWORD=<random bytes>
See the code for this website.