Datenschutz ist das Thema, bei dem Admins reflexartig den Anwalt empfehlen. Aber die Hälfte der DSGVO-Compliance ist Technik — und die andere Hälfte ist Dokumentation dieser Technik. Wer beides selbst macht, spart sich das teure Beratungsgespräch für die wirklich schwierigen Fälle auf.
Dieser Artikel zeigt konkrete Configs für nginx und Apache, wie Matomo ohne Cookies läuft und warum du für Logs eine Rotationsstrategie brauchst. Alles, was ich auf bitcalc.net selbst einsetze.
IP-Anonymisierung: Der einfachste Hebel
Die IP-Adresse ist ein personenbezogenes Datum. Das letzte Oktett zu maskieren macht sie unkritisch — und das geht in einer Zeile:
# nginx: Letztes Oktett der Client-IP anonymisieren
map $remote_addr $anonymized_ip {
~(?P<ip>\d+\.\d+\.\d+)\.\d+ $ip.0;
default 0.0.0.0;
}
access_log /var/log/nginx/access.log combined if=$anonymized_ip;
# Apache (mod_remoteip + custom LogFormat)
LogFormat "%{ANONYMIZED_IP}e %l %u %t \"%r\" %>s %b" anonymized
Für Matomo reicht ein Parameter: In der Tracking-Config _paq.push(['setRequestMethod', 'POST']) und in den Matomo-Einstellungen „IP-Adressen anonymisieren" auf 2 Bytes setzen. Dann wird aus 203.0.113.42 → 203.0.0.0. Statistisch nutzbar, personenbezogen wertlos.
Matomo cookieless: Analytics ohne Consent-Banner
Der Trick: Matomo ohne Cookies zu betreiben. Dann brauchst du kein Consent-Banner für Analytics — weil keine personenbeziehbaren Daten im Browser gespeichert werden. So sieht die Config aus:
// Matomo cookieless tracking
var _paq = window._paq = window._paq || [];
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
_paq.push(['disableCookies']); // ← Das ist die Zeile
(function() {
var u="//your-matomo.example/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '1']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
Log-Rotation und Löschfristen
Die DSGVO verlangt, dass du personenbezogene Daten nicht länger als nötig speicherst. Für Server-Logs heißt das: Rotation + automatische Löschung. Mit logrotate:
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
rotate 14 # 14 Tage aufheben
compress
delaycompress
missingok
notifempty
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}
Die 14 Tage sind kein willkürlicher Wert. Sie decken den Zeitraum ab, in dem du Logs für Fehleranalyse brauchst („letzte Woche war die Seite langsam"). Für Security-Incidents kannst du Ausnahmen definieren — aber die musst du dokumentieren.
Cookie-Consent: Nur sammeln, was du brauchst
Der Consent-Banner muss technisch korrekt sein: Keine Cookies setzen bevor der Nutzer zugestimmt hat. Scripte erst nach Consent laden. Opt-out genauso einfach wie Opt-in.
// AdSense erst nach Consent laden
if (localStorage.getItem('cookie_consent') === 'accepted') {
var s = document.createElement('script');
s.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
s.setAttribute('data-ad-client', 'ca-pub-XXXXX');
s.async = true;
document.head.appendChild(s);
}
bitcalc setzt genau einen technischen Cookie: bitcalc_lang für die Sprachauswahl. Das ist ein berechtigtes Interesse nach Art. 6 Abs. 1 lit. f DSGVO — keine Einwilligung nötig. Alles andere (AdSense, Matomo mit Cookies) läuft nur mit Opt-in.
Auftragsverarbeitung: Hosting, CDN, Fonts
Jeder externe Dienst, der personenbezogene Daten verarbeitet, braucht einen AVV-Vertrag. Das betrifft:
- Hosting-Provider (all-inkl.com im Fall von bitcalc) — AVV ist meist in den AGB integriert
- CDN — IPs der Besucher gehen an den CDN-Provider
- Fonts — Google Fonts vom eigenen Server laden, nicht von fonts.googleapis.com
bitcalc hostet alle Assets selbst: Inter und JetBrains Mono liegen als TTF-Dateien im Verzeichnis, kein externer Font-Download. Das eliminiert einen ganzen AVV-Sachverhalt.