How Can We Help?
Eine saubere Webserver-Konfiguration ist die Basis jeder sicheren WordPress-Installation. Viele Härtungsmassnahmen lassen sich direkt auf dem Webserver umsetzen. Das ist effizienter als per Plugin, weil Anfragen gar nicht erst PHP erreichen.
Nginx: Grundkonfiguration
server {
server_name example.ch;
root /var/www/example/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm-example.sock;
}
# Keine PHP-Ausführung in Uploads
location ~* /wp-content/uploads/.*\.php$ { deny all; }
# Sensible Dateien sperren
location ~* /(wp-config\.php|readme\.html|license\.txt|\.git|\.env|debug\.log) { deny all; }
location = /xmlrpc.php { deny all; }
# Statische Assets lange cachen
location ~* \.(css|js|woff2|svg|png|jpg|jpeg|webp|avif)$ {
expires 1y; add_header Cache-Control "public, immutable"; access_log off;
}
}
Apache: .htaccess-Ergänzungen
# Sensible Dateien sperren
<FilesMatch "^(wp-config\.php|readme\.html|license\.txt|debug\.log|xmlrpc\.php)$">
Require all denied
</FilesMatch>
# Verzeichnislisting aus
Options -Indexes
In wp-content/uploads/.htaccess:
<FilesMatch "\.(php|phtml|phar)$">
Require all denied
</FilesMatch>
Bei Apache ist eine Konfiguration im VirtualHost performanter als .htaccess, weil die Dateien sonst bei jedem Request gelesen werden (AllowOverride None, wenn möglich).
Rate Limiting für Login
Nginx:
limit_req_zone $binary_remote_addr zone=wplogin:10m rate=5r/m;
location = /wp-login.php {
limit_req zone=wplogin burst=5 nodelay;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm-example.sock;
}
TLS und HTTP/2/3
- Nur TLS 1.2 und 1.3, moderne Cipher (z. B. Mozilla SSL Configuration Generator, Profil „Intermediate“).
- HTTP/2 aktivieren, HTTP/3 (QUIC) wo verfügbar.
- HSTS erst setzen, wenn HTTPS überall sicher funktioniert (siehe Sicherheits-Header).
Tipp
Nach jeder Änderung testen: nginx -t bzw. apachectl configtest, danach mit curl -I https://example.ch/xmlrpc.php prüfen, ob die Sperre greift (erwartet: 403).
Weiterführende Artikel
- Brute-Force- und Credential-Stuffing-Schutz für wp-login.php und XML-RPC
- Sicherheits-Header (CSP, HSTS & Co.) für WordPress
- Dateiberechtigungen und Eigentümer richtig setzen