---
title: "WordPress-Logs auswerten: Zugriffe, Fehler und Angriffe erkennen"
date: 2026-09-30T22:45:01+02:00
modified: 2026-11-08T22:36:51+01:00
category: wordpress
type: how_to
author: Marcel Schönfelder
canonical: https://s-edv.com/anleitungen/wordpress-logs-auswerten-zugriffe-fehler-angriffe
keywords:
  - WordPress
  - Logs
  - Sicherheit
  - Fehlersuche
  - Apache
  - nginx
reading_time: 10
---

# WordPress-Logs auswerten: Zugriffe, Fehler und Angriffe erkennen

Wenn eine WordPress-Website langsam wird, eine weiße Seite zeigt oder nachts tausende Anmeldeversuche abbekommt, steht die Antwort fast immer in einer Protokolldatei. Die Protokolle liegen aber an verschiedenen Stellen, und selten schaut jemand hinein. Diese Anleitung zeigt, wie Sie die Protokolle an einem festen Ort zusammenführen, sie mit wenigen Standardbefehlen lesen und daraus einen kurzen Bericht machen, der Zugriffe, Fehler und Angriffsmuster auf einen Blick zeigt.

**Kurzfassung:** Legen Sie das WordPress-Fehlerprotokoll per `WP_DEBUG_LOG` außerhalb des Webverzeichnisses ab, damit es niemand aus dem Internet abrufen kann. Das Zugriffsprotokoll des Webservers verrät Ihnen Statuscodes, IP-Adressen und angefragte Pfade. Fehlgeschlagene Anmeldungen erkennen Sie daran, dass ein POST auf `wp-login.php` mit Status 200 beantwortet wird, erfolgreiche mit 302. Ein kleines Shell-Skript fasst beide Quellen zu einem Tagesbericht zusammen. Rotation und eine begrenzte Aufbewahrung halten die Dateien klein und entsprechen dem Datenschutz.

## Voraussetzungen

Die Befehle setzen einen Server voraus, auf dem Sie selbst Dateien lesen dürfen.

- [ ] **WordPress:** eine aktuelle Version.
- [ ] **PHP:** 7.4 oder neuer, empfohlen 8.3 oder 8.4.
- [ ] **Webserver:** Apache oder nginx unter Linux mit dem üblichen Protokollformat „combined“.
- [ ] **Zugriff:** SSH mit Leserechten auf die Logverzeichnisse, dazu Schreibzugriff auf die `wp-config.php` per SSH oder SFTP.
- [ ] **Rolle:** Administrator der WordPress-Installation und Verantwortung für den Server.
- [ ] **Backup:** eine aktuelle Sicherung der `wp-config.php`. Ein Tippfehler in dieser Datei legt die Website sofort lahm.

## Schritt 1: Wissen, welches Protokoll was enthält

Jede Quelle beantwortet eine andere Frage:

| Protokoll | Typischer Ort | Beantwortet |
| --- | --- | --- |
| Zugriffsprotokoll | `/var/log/apache2/access.log` bzw. `/var/log/nginx/access.log` | Wer hat wann welche Adresse aufgerufen, mit welchem Ergebnis? |
| Fehlerprotokoll Webserver | `error.log` im selben Ordner | Probleme des Webservers selbst |
| WordPress-Fehlerprotokoll | `wp-content/debug.log` oder eigener Pfad | PHP-Warnungen und schwere Fehler aus Core, Plugins und Themes |
| Aktivitätsprotokoll | Datenbank, per Plugin | Welcher Benutzer hat im Backend was geändert? |

Die Pfade gelten für Debian und Ubuntu. Anderswo verraten die Direktiven `CustomLog` (Apache) bzw. `access_log` (nginx) den Ort. Im offiziellen Docker-Image schreibt Apache auf die Standardausgabe, dort lesen Sie mit `docker compose logs`.

Das Aktivitätsprotokoll behandelt die Anleitung [Aktivitätsprotokoll in WordPress einrichten](https://s-edv.com/anleitungen/wordpress-aktivitaetsprotokoll-simple-history-einrichten).

> **Prüfen:** Führen Sie `ls -la /var/log/apache2/` (bzw. `/var/log/nginx/`) aus. Sie sollten `access.log` und `error.log` sehen, dazu ältere, rotierte Dateien wie `access.log.1` und `access.log.2.gz`.

## Schritt 2: WordPress-Fehler in eine sichere Datei schreiben

Mit den Standardeinstellungen protokolliert WordPress keine eigenen Fehler. Die Konstante `WP_DEBUG_LOG` schaltet das ein, setzt aber `WP_DEBUG` voraus. Mit `true` landet es in `wp-content/debug.log`. Diese Datei ist über den Browser erreichbar: Der Aufruf von `/wp-content/debug.log` liefert ohne weitere Maßnahmen in der Regel den Status 200 und den vollständigen Inhalt mit Dateipfaden des Servers. Laut WordPress-Dokumentation dürfen Sie statt `true` einen eigenen Dateipfad angeben. Nutzen Sie das und legen Sie die Datei außerhalb des Webverzeichnisses ab.

Ordner anlegen und dem PHP-Benutzer übergeben (auf Debian `www-data`):

```bash
$ sudo mkdir -p /var/log/wordpress
$ sudo chown www-data:www-data /var/log/wordpress
$ sudo chmod 750 /var/log/wordpress
```

Tragen Sie dann in die `wp-config.php` oberhalb der Zeile `/* That's all, stop editing! */` ein:

```php
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', '/var/log/wordpress/debug.log' );
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );
```

`WP_DEBUG_DISPLAY` auf `false` ist auf einer Live-Website Pflicht. Sonst sehen Besucher Warnungen mitten im Seiteninhalt. Dauerhaft eingeschaltet protokolliert `WP_DEBUG` auch harmlose Hinweise, die Datei wächst schneller. Gezieltes Debuggen zeigt die Anleitung [WordPress Debug-Modus aktivieren und Error-Logs analysieren](https://s-edv.com/anleitungen/wordpress-debug-modus-error-logs-fehler-beheben).

Können Sie auf Ihrem Hosting keinen Ordner außerhalb des Webverzeichnisses anlegen, sperren Sie die Datei wenigstens. Unter Apache genügt eine `.htaccess` im Ordner `wp-content`, sofern der Hoster `AllowOverride` erlaubt:

```plaintext
<Files "debug.log">
  Require all denied
</Files>
```

Unter nginx gehört eine entsprechende Regel in den Server-Block:

```nginx
location = /wp-content/debug.log {
    deny all;
}
```

> **Prüfen:** Rufen Sie eine Seite der Website auf und prüfen Sie mit `sudo ls -la /var/log/wordpress/`, ob die Datei nach der ersten Meldung entsteht. Mit `curl -I https://ihre-domain.de/wp-content/debug.log` sollten Sie keinen Status 200 mehr erhalten. Die Sperre per `.htaccess` liefert den Status 403.

## Schritt 3: Das Zugriffsprotokoll lesen

Eine Zeile im Format „combined“ sieht so aus:

```plaintext
203.0.113.7 - - [30/Sep/2026:20:36:37 +0000] "POST /wp-login.php HTTP/1.1" 200 10053 "-" "curl/8.14.1"
```

Von links nach rechts stehen dort IP-Adresse, zwei meist leere Felder, Zeitpunkt, Anfrage mit Methode und Pfad, Statuscode, Antwortgröße in Bytes, die verweisende Seite und die Kennung des Browsers. An Leerzeichen getrennt liegt die IP-Adresse im ersten Feld, die Methode im sechsten, der Pfad im siebten und der Statuscode im neunten.

Wie viele Anfragen endeten mit welchem Status? Die Befehle für IP-Adressen und Serverfehler folgen demselben Muster und stehen im Skript in Schritt 6.

```bash
$ awk '{print $9}' /var/log/apache2/access.log | sort | uniq -c | sort -rn
```

Ältere, bereits komprimierte Dateien lesen Sie mit `zcat -f`, das unkomprimierte und gepackte Dateien gleichermaßen verarbeitet:

```bash
zcat -f /var/log/apache2/access.log* | grep -c "POST /wp-login.php"
```

Steht ein Reverse Proxy oder CDN davor, sehen oft alle Besucher gleich aus. Die echte Adresse übernehmen `mod_remoteip` (Apache) bzw. das realip-Modul (nginx), die nur eigenen Proxys vertrauen dürfen. Das Apache-Format „vhost_combined“ verschiebt alle Felder um eine Position. Prüfen Sie deshalb eine echte Zeile, bevor Sie Feldnummern übernehmen.

> **Prüfen:** Rufen Sie Ihre Startseite einmal im Browser auf und suchen Sie mit `grep "IHRE-IP" /var/log/apache2/access.log | tail -3` nach Ihrer eigenen Adresse. Die letzte Zeile sollte Ihren Aufruf mit Status 200 zeigen.

## Schritt 4: Angriffsmuster erkennen

Automatisierte Angriffe hinterlassen deutliche Spuren im Zugriffsprotokoll.

**Fehlgeschlagene Anmeldungen:** WordPress beantwortet eine falsche Anmeldung auf `wp-login.php` mit Status 200, weil es das Formular samt Fehlermeldung erneut ausliefert. Eine erfolgreiche Anmeldung leitet mit Status 302 ins Backend weiter. Viele POST-Anfragen mit Status 200 von derselben Adresse deuten daher auf einen Passwort-Angriff hin:

```bash
$ awk '$6 == "\"POST" && $7 ~ /^\/wp-login\.php/ && $9 == 200 {print $1}' /var/log/apache2/access.log | sort | uniq -c | sort -rn | head
```

**XML-RPC:** Die Schnittstelle `xmlrpc.php` antwortet auch bei falschen Zugangsdaten mit Status 200, weil der Fehler im Inhalt der Antwort steht. So kommt die Meldung „Der Benutzername oder das Passwort ist falsch.“ zurück. Nutzen Sie keine XML-RPC-Dienste wie die Jetpack-App, ist jede POST-Anfrage darauf verdächtig. Der Tagesbericht zählt sie.

**Suche nach vergessenen Dateien:** Scanner fragen nach Pfaden wie `/.env`, `/wp-config.php.bak`, `/phpmyadmin/` oder `/wp-content/debug.log`:

```bash
$ grep -E '\.env|\.bak|\.sql|phpmyadmin|debug\.log' /var/log/apache2/access.log | awk '{print $1, $7, $9}'
```

Verlassen Sie sich dabei nicht allein auf den Statuscode. WordPress antwortet auf nicht vorhandene Pfade mit Weiterleitung (301) oder sogar mit 200 und der Startseite. Entspricht die Antwortgröße Ihrer Startseite, hat der Scanner nichts bekommen.

**Benutzernamen ausspähen:** Anfragen wie `/?author=1` oder `/wp-json/wp/v2/users` sammeln Anmeldenamen.

Wiederkehrende Angreifer sperren Sie automatisch, wie die Anleitung [fail2ban für wp-login und XML-RPC](https://s-edv.com/anleitungen/wordpress-fail2ban-wp-login-xmlrpc-serverebene-sperren) zeigt.

> **Prüfen:** Melden Sie sich einmal absichtlich mit einem falschen Passwort an. Der Befehl für fehlgeschlagene Anmeldungen sollte Ihre IP-Adresse mit mindestens einem Treffer zeigen.

## Schritt 5: PHP-Fehler bündeln und einordnen

Dieselbe Meldung steht oft hunderte Male im Protokoll. Ohne Zeitstempel gezählt, sehen Sie sofort den Hauptverursacher:

```bash
$ grep -E 'PHP (Fatal error|Warning|Parse error)' /var/log/wordpress/debug.log | sed -E 's/^\[[^]]+\] //' | sort | uniq -c | sort -rn | head
```

Eine typische Ausgabe sieht so aus:

```plaintext
      1 PHP Fatal error:  Uncaught Error: Call to undefined function nicht_vorhanden() in /var/www/html/wp-content/mu-plugins/logtest2.php:1
      1 PHP Warning:  Undefined variable $undefiniert in /var/www/html/wp-content/mu-plugins/logtest.php on line 1
```

Der Pfad hinter „in“ verrät den Verursacher. Liegt er unter `wp-content/plugins/NAME/`, ist es das Plugin NAME, unter `wp-content/themes/` das Theme. Ein „Fatal error“ bricht die Seite ab, im Zugriffsprotokoll steht zur selben Minute ein Status 500. So ordnen Sie die Meldung „Es gab einen kritischen Fehler auf dieser Website“ einer Ursache zu. Warnungen und „Deprecated“-Hinweise stören meist nicht, kündigen aber Probleme beim nächsten PHP-Update an.

> **Prüfen:** Der Befehl sollte eine nach Häufigkeit sortierte Liste liefern. Bleibt sie trotz Fehlern leer, siehe „Typische Fehler“.

## Schritt 6: Einen Tagesbericht erzeugen

Fassen Sie die Befehle in `/usr/local/bin/wp-logbericht` zusammen:

```bash
#!/bin/sh
# wp-logbericht: Kurzbericht aus Apache-Zugriffslog und WordPress-debug.log
ACCESS=${ACCESS:-/var/log/apache2/access.log}
DEBUG=${DEBUG:-/var/log/wordpress/debug.log}

echo "== Anfragen je Statuscode"
awk '{print $9}' "$ACCESS" | sort | uniq -c | sort -rn

echo "== Top 10 IP-Adressen"
awk '{print $1}' "$ACCESS" | sort | uniq -c | sort -rn | head -10

echo "== Fehlgeschlagene Anmeldungen (POST wp-login.php mit Status 200)"
awk '$6 == "\"POST" && $7 ~ /^\/wp-login\.php/ && $9 == 200 {print $1}' "$ACCESS" | sort | uniq -c | sort -rn | head -10

echo "== POST auf xmlrpc.php"
grep -c 'POST /xmlrpc.php' "$ACCESS"

echo "== Serverfehler (5xx)"
awk '$9 ~ /^5/ {print $4, $7}' "$ACCESS" | tail -10

echo "== Häufigste PHP-Meldungen"
grep -E 'PHP (Fatal error|Warning|Parse error)' "$DEBUG" | sed -E 's/^\[[^]]+\] //' | sort | uniq -c | sort -rn | head -10
```

Ausführbar machen und testen, bei nginx mit anderem Pfad:

```bash
$ sudo chmod +x /usr/local/bin/wp-logbericht
$ sudo wp-logbericht
$ sudo ACCESS=/var/log/nginx/access.log wp-logbericht
```

Täglich per Cron in `/etc/cron.d/wp-logbericht`:

```plaintext
55 23 * * * root /usr/local/bin/wp-logbericht > /var/log/wordpress/bericht-$(date +\%F).txt 2>&1
```

Das Prozentzeichen muss in Cron maskiert sein, sonst bricht die Zeile ab. Wer diese Durchsicht zusammen mit Updates und Sicherungen nicht selbst im Kalender halten möchte, kann die laufende Pflege abgeben: Die [WordPress-Wartung von wordpressupdate.de](https://wordpressupdate.de/?utm_source=s-edv.com&utm_medium=artikel&utm_campaign=111) spielt Updates von WordPress, Plugins und Themes mit Kompatibilitätsprüfung ein, sichert die Website wöchentlich auf externen Speicher und richtet eine Firewall ein, die viele der hier sichtbaren Angriffe abfängt.

> **Prüfen:** `sudo wp-logbericht` sollte alle sechs Abschnitte ausgeben. Am Tag nach dem Eintrag in Cron liegt eine Datei `bericht-JJJJ-MM-TT.txt` in `/var/log/wordpress/`.

## Schritt 7: Rotation und Aufbewahrung festlegen

Die Webserver-Pakete von Debian und Ubuntu bringen bereits eine Regel für logrotate mit. In der Regel rotiert die Apache-Vorlage täglich, bewahrt 14 Dateien auf und komprimiert ältere Stände. Das eigene `debug.log` kennt logrotate dagegen nicht, es wächst ohne Grenze. Legen Sie dafür `/etc/logrotate.d/wordpress` an:

```plaintext
/var/log/wordpress/*.log {
    weekly
    rotate 4
    compress
    missingok
    notifempty
    copytruncate
}
```

`copytruncate` kopiert die Datei und leert das Original, statt sie zu verschieben. So schreibt PHP ohne Neustart weiter. Alte Berichte räumt `find /var/log/wordpress -name 'bericht-*.txt' -mtime +30 -delete` per Cron auf.

Die Aufbewahrungsdauer ist auch eine Datenschutzfrage. Dynamische IP-Adressen können laut EuGH (Urteil C-582/14 vom 19. Oktober 2016) personenbezogene Daten sein. Speichern Sie Zugriffsprotokolle nur so lange, wie Sie sie für Sicherheit und Fehlersuche brauchen, und nennen Sie diese Dauer in der Datenschutzerklärung. Mehr dazu in der Anleitung [DSGVO-Löschpflichten für Backups und Logfiles](https://s-edv.com/anleitungen/dsgvo-loeschpflichten-backups-logfiles-anleitung).

> **Prüfen:** `sudo logrotate -d /etc/logrotate.d/wordpress` führt einen Probelauf ohne Änderungen aus und zeigt, welche Dateien rotiert würden.

## Typische Fehler

**Die Datei `debug.log` entsteht nicht**

`WP_DEBUG` steht auf `false`, oder der PHP-Benutzer darf nicht in den Zielordner schreiben. Prüfen Sie mit `ls -ld /var/log/wordpress`, dass der Ordner `www-data` gehört.

**`debug.log` ist öffentlich abrufbar**

Das passiert bei `WP_DEBUG_LOG` auf `true` ohne Sperre. Eigenen Pfad außerhalb des Webverzeichnisses wählen oder die Sperre aus Schritt 2 setzen.

**Alle Zugriffe kommen von derselben IP-Adresse**

Ein Proxy oder CDN steht davor, und die echte Adresse wird nicht übernommen. `mod_remoteip` bzw. das realip-Modul von nginx einrichten.

**Protokoll im Docker-Container leer**

Im offiziellen Image zeigen die Dateien auf die Standardausgabe, lesen Sie mit `docker compose logs`.

**Permission denied beim Lesen**

Die Dateien gehören `root` und der Gruppe `adm`. Befehle mit `sudo` ausführen oder den eigenen Benutzer der Gruppe `adm` hinzufügen.

## Häufige Fragen

### Brauche ich dafür ein Log-Plugin in WordPress?

Nein. Die Protokolle des Webservers entstehen ohnehin, und WordPress schreibt Fehler mit einer Konstante in der `wp-config.php`. Plugins lohnen sich für das Aktivitätsprotokoll im Backend.

### Mein Hoster bietet keinen SSH-Zugang. Was nun?

Viele Hoster stellen die Zugriffs- und Fehlerprotokolle im Kundenmenü zum Download bereit. Die Befehle laufen dann auf Ihrem Rechner, unter Windows etwa im Windows-Subsystem für Linux.

### Wann brauche ich ein zentrales Log-System wie Graylog oder OpenObserve?

Sobald Sie mehrere Websites oder Server betreuen und Protokolle über Wochen durchsuchen wollen. Für eine einzelne Website reicht der Tagesbericht.

## Fazit

Mit einem geschützten Fehlerprotokoll, einer Handvoll Standardbefehlen und einem kurzen Tagesbericht wissen Sie, was auf Ihrer Website passiert, ohne zusätzliche Software zu installieren. Wichtig sind regelmäßige Durchsicht und kurze Aufbewahrung. Soll sich jemand anderes um Updates, Sicherungen und Firewall kümmern, übernimmt das die [WordPress-Wartung von Marcel Schönfelder](https://wordpressupdate.de/?utm_source=s-edv.com&utm_medium=fazit&utm_campaign=111).

## Weiterführende Anleitungen und Quellen

- [WordPress Debug-Modus aktivieren: Error-Logs analysieren und Fehler selbst beheben](https://s-edv.com/anleitungen/wordpress-debug-modus-error-logs-fehler-beheben)
- [WordPress-Firewall auf Serverebene: fail2ban für wp-login und XML-RPC](https://s-edv.com/anleitungen/wordpress-fail2ban-wp-login-xmlrpc-serverebene-sperren)
- [Aktivitätsprotokoll in WordPress: Änderungen von Benutzern nachvollziehen](https://s-edv.com/anleitungen/wordpress-aktivitaetsprotokoll-simple-history-einrichten)
- [DSGVO-Löschpflichten und Backups: Praxis-Leitfaden für Admins](https://s-edv.com/anleitungen/dsgvo-loeschpflichten-backups-logfiles-anleitung)
- [Linux-Server absichern mit UFW und Fail2ban](https://s-edv.com/anleitungen/linux-server-absichern-ufw-fail2ban)
- [WordPress Developer Resources: Debugging in WordPress](https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/)
- [Apache HTTP Server 2.4: Log Files](https://httpd.apache.org/docs/2.4/logs.html)
- [nginx: Module ngx_http_log_module](https://nginx.org/en/docs/http/ngx_http_log_module.html)
