.htaccess Ultimativer Guide – mod_rewrite, 7G Firewall und WordPress Konfiguration erklärt von Adrian Thommes, SEO Experte Saarland

Grundlagen: Wie Apache die .htaccess verarbeitet

Bevor man die ersten Regeln schreibt, lohnt es sich zu verstehen, was Apache intern mit der .htaccess macht – denn das verhindert die häufigsten Fehler von Anfang an. Der Apache HTTP Server liest bei jedem einzelnen Request sämtliche Verzeichnisebenen vom Root bis zum Zielverzeichnis durch und prüft, ob eine .htaccess vorhanden ist. Gefundene Direktiven werden kumuliert und in der Reihenfolge ihres Auftreffens angewendet.

Das bedeutet: Eine .htaccess im Root-Verzeichnis gilt automatisch für alle Unterordner – es sei denn, ein Unterordner hat eine eigene Datei, die bestimmte Direktiven überschreibt. Diese Vererbungslogik ist wichtig beim Einsatz mehrerer .htaccess-Dateien in Subordnern.

Performance-Hinweis: Weil Apache die Datei bei jedem Request neu liest, ist die .htaccess langsamer als die zentrale httpd.conf. Für dauerhaft genutzte Direktiven auf dedizierten Servern sollte man Einstellungen in die httpd.conf verlagern. Auf Shared-Hosting ohne Shell-Zugang ist die .htaccess jedoch die einzige Option – und ihr Performance-Einfluss ist bei moderner Hardware vernachlässigbar.

AllowOverride – wann die .htaccess überhaupt wirkt

Damit .htaccess-Direktiven wirken, muss der Server-Administrator AllowOverride All (oder zumindest AllowOverride FileInfo AuthConfig Limit) in der httpd.conf für das entsprechende Verzeichnis konfiguriert haben. Bei den meisten Shared-Hostern ist das Standard, auf eigenen Servern und in Docker-Umgebungen muss man es explizit aktivieren. Wenn deine .htaccess-Regeln schlicht ignoriert werden, ist das die erste Stelle zum Prüfen.

Wer die eigenen .htaccess und Sicherheits-Header schnell überprüfen möchte, bevor er tiefer einsteigt, kann dafür den kostenlosen .htaccess Checker nutzen – er analysiert die Konfiguration direkt im Browser, ohne Datei-Upload.

mod_rewrite meistern – RewriteRule, RewriteCond & Flags

mod_rewrite ist das mächtigste Werkzeug der .htaccess. Es erlaubt, eingehende URLs auf der Serverseite zu analysieren, zu verändern und weiterzuleiten – bevor der Browser etwas davon erfährt. Das Fundament besteht aus drei Elementen: RewriteEngine, RewriteCond und RewriteRule.

# mod_rewrite aktivieren (einmalig pro .htaccess nötig)
RewriteEngine On

# Optionale Basis – wichtig bei WordPress und Unterverzeichnissen
RewriteBase /

RewriteRule – Syntax verstehen

Die Grundsyntax lautet: RewriteRule MUSTER ZIEL [FLAGS]

Das Muster ist ein regulärer Ausdruck (PCRE), der gegen den Pfadteil der angeforderten URL geprüft wird – ohne Hostname und ohne Query-String. Das Ziel ist entweder ein interner Pfad (kein Browser-Redirect) oder eine vollständige URL (mit Redirect). Flags in eckigen Klammern steuern das Verhalten:

[L]
Last – nach dieser Regel keine weiteren Regeln mehr ausführen
[R=301]
Redirect – Browser-Weiterleitung mit HTTP-Statuscode (301 = permanent, 302 = temporär)
[NC]
No Case – Groß-/Kleinschreibung beim Muster ignorieren
[F]
Forbidden – sendet HTTP 403, Zugriff verweigert
[S=n]
Skip – überspringt die nächsten n Regeln
[QSA]
Query String Append – hängt vorhandene Query-Parameter ans Ziel an
[END]
End – stoppt alle weiteren Rewrites, auch in anderen .htaccess-Dateien
[OR]
Verknüpft zwei RewriteCond mit ODER statt mit UND

RewriteCond – Bedingungen kombinieren

Eine RewriteRule greift nur, wenn alle vorangestellten RewriteCond-Bedingungen erfüllt sind. Mehrere Bedingungen werden standardmäßig mit UND verknüpft – mit dem [OR]-Flag auch mit ODER. Die wichtigsten Servervariablen für Bedingungen:

# Beispiel: Nur weiterleiten wenn kein HTTPS UND kein API-Aufruf
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} !^/api/
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Häufig verwendete Servervariablen
# %{HTTP_HOST}      – z.B. www.example.de
# %{REQUEST_URI}    – z.B. /blog/artikel.html
# %{QUERY_STRING}   – z.B. id=42&lang=de
# %{HTTPS}          – "on" wenn SSL aktiv
# %{HTTP_REFERER}   – die verweisende Seite
# %{HTTP_USER_AGENT} – Browser/Bot-Kennung
# %{REMOTE_ADDR}    – IP-Adresse des Besuchers

Capture Groups – Teile der URL wiederverwenden

Runde Klammern im Muster definieren Capture Groups. Deren Inhalt kann im Ziel mit $1, $2 usw. referenziert werden – analog funktioniert %1, %2 für Capture Groups aus RewriteCond.

# www auf non-www umleiten, URL dabei erhalten
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

# %1 = Domain ohne www (aus RewriteCond)
# $1 = gesamter URL-Pfad (aus RewriteRule)

Saubere URLs mit PHP und URL-Rewriting

Moderne Webprojekte erzeugen URLs wie /index.php?sektion=leistungen&id=42 – unlesbar, schlecht für SEO und kaum teilbar. Mit drei Zeilen in der .htaccess und etwas PHP lassen sich daraus sprechende Pfade wie /leistungen/42/ machen.

Schritt 1: Alle Anfragen auf index.php leiten

RewriteEngine On

# Anfragen auf existierende Dateien/Ordner NICHT umschreiben
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# Alle anderen Anfragen an index.php übergeben
RewriteRule .* /index.php [L]

Die Bedingungen !-f und !-d stellen sicher, dass tatsächlich existierende Dateien (Bilder, CSS, PDFs) und Verzeichnisse nicht umgeschrieben werden – sie werden direkt ausgeliefert. Nur Anfragen auf nicht-existente Pfade landen in der index.php.

Schritt 2: URL in PHP auslesen

In der index.php lässt sich der angeforderte Pfad über $_SERVER['REQUEST_URI'] auslesen und weiterverarbeiten:

 include 'pages/leistungen.php',
    'blog'       => include 'pages/blog.php',
    'kontakt'    => include 'pages/kontakt.php',
    default      => include 'pages/404.php'
};
?>

Parameter direkt per RewriteRule übergeben

Alternativ kann die .htaccess die Variablen bereits aufgelöst an PHP übergeben – ohne dass die PHP-Datei selbst parsen muss:

RewriteRule ^([a-z0-9-]+)/?([a-z0-9-]*)/?$ /index.php?sektion=$1&seite=$2 [L,QSA]

# In PHP dann einfach:
# $sektion = $_GET['sektion'];
# $seite   = $_GET['seite'];

SEO-Vorteil sprechender URLs: Google empfiehlt kurze, beschreibende URLs ohne unnötige Parameter. Sprechende Pfade werden besser geklickt, häufiger verlinkt und von Nutzern leichter erinnert – drei Faktoren, die das Ranking langfristig verbessern.

Die 7G Firewall – Apache-Schutz auf höchstem Niveau

Die 7G Firewall von Jeff Starr (Perishable Press) ist die leistungsstärkste frei verfügbare Apache-Firewall, die per .htaccess aktiviert wird. Sie analysiert jeden eingehenden Request in fünf Dimensionen und blockiert Angriffsmuster, bevor sie die Anwendung auch nur erreichen:

  • Query String – SQL-Injection, XSS, Base64-Exploits, Remote File Inclusion
  • Request URI – Pfad-Traversal, Shell-Uploads, bekannte Exploit-Endpunkte
  • User Agent – Scraper, Exploit-Bots, gefährliche Crawler (Ahrefs, MJ12 etc.)
  • Remote Host – bekannte Angreifer-Netzwerke und Datacenter-Blöcke
  • HTTP Referrer – Spam-Referrer und Manipulationsversuche über Referer-Header

Die 7G blockiert dabei keine legitimen Besucher oder Suchmaschinen-Crawler wie Googlebot. Sie ist auch im produktiven Einsatz mit WordPress, TYPO3 und statischen Websites erprobt und gilt in der WordPress-Security-Community als de-facto-Standard für .htaccess-basierte Firewall-Lösungen.

7G Firewall einbinden

Die Integration erfolgt durch Einfügen des vollständigen 7G-Codes am Anfang der .htaccess, direkt nach optionalen globalen Einstellungen wie ServerSignature Off. Die aktuellste Version (1.6 zum Zeitpunkt dieses Guides) ist kostenlos auf der Perishable Press Website verfügbar. Den Code nicht kürzen – jede Zeile deckt spezifische Angriffsvektoren ab.

# 7G:[CORE] – immer an erster Stelle
ServerSignature Off
Options -Indexes
RewriteEngine On
RewriteBase /

# 7G:[QUERY STRING]
<IfModule mod_rewrite.c>
  RewriteCond %{QUERY_STRING} ([a-z0-9]{2000,}) [NC,OR]
  RewriteCond %{QUERY_STRING} (union)(.*)(select)(.*)(\(|%28)) [NC,OR]
  RewriteCond %{QUERY_STRING} (concat|eval)(.*)(\(|%28)) [NC]
  RewriteRule .* - [F,L]
</IfModule>

# (vollständiger 7G-Code: perishablepress.com/7g-firewall/)

Wichtig: Kopiere immer die vollständige aktuelle Version von der offiziellen Perishable Press Website. Kürzte oder veraltete Versionen bieten lückenhaften Schutz. Nach dem Einfügen die Website sofort testen – sollten eigene Formulare oder AJAX-Aufrufe geblockt werden, liegt das meist an zu aggressiven Query-String-Regeln, die du dann gezielt auskommentieren kannst.

7G Logging für die Fehleranalyse

In der Standard-Konfiguration blockiert die 7G still. Zur Fehleranalyse enthält der Code auskommentierte Log-Direktiven, die Blockierungen in eine separate PHP-Datei schreiben. Das ist hilfreich während der Einrichtungsphase, sollte aber im Live-Betrieb wieder deaktiviert werden, um Performanz und Festplattenplatz zu schonen.

WordPress .htaccess – das vollständige Setup

WordPress generiert seine .htaccess automatisch, wenn du unter Einstellungen → Permalinks auf Speichern klickst. Diese automatische Version ist jedoch auf ein Minimum reduziert. Für eine wirklich gehärtete WordPress-Installation braucht es mehr – schichtweise aufgebaut, damit einzelne Teile leicht angepasst werden können.

WordPress Basis – mod_rewrite für Permalinks

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Kritische Dateien absichern

Die wp-config.php enthält Datenbankzugangsdaten, Sicherheits-Salts und den Debug-Modus. Kein Besucher sollte diese Datei jemals anfordern können – und der Server sollte auf solche Anfragen mit einem harten 403 antworten, nicht mit einem harmlosen 404:

# wp-config.php vor Direktzugriff schützen
<Files wp-config.php>
  Order deny,allow
  Deny from all
</Files>

# .htaccess selbst schützen
<FilesMatch "^\.htaccess">
  Order deny,allow
  Deny from all
</FilesMatch>

# Kein Zugriff auf WordPress-interne PHP-Dateien
<IfModule mod_rewrite.c>
  RewriteRule ^wp-admin/includes/ - [F,L]
  RewriteRule !^wp-includes/ - [S=3]
  RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
  RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
  RewriteRule ^wp-includes/theme-compat/ - [F,L]
</IfModule>

XML-RPC deaktivieren

Die xmlrpc.php von WordPress ist ein beliebtes Angriffsziel für DDoS-Amplifikation und Brute-Force-Angriffe – weil eine einzige Anfrage dort hunderte von Login-Versuchen auslösen kann. Wer die WordPress-App oder Pingbacks nicht nutzt, sollte die Schnittstelle komplett abschalten:

# XML-RPC vollständig deaktivieren
<Files xmlrpc.php>
  Order Deny,Allow
  Deny from all
</Files>

wp-content Ordner mit separater .htaccess schützen

Der wp-content-Ordner ist das primäre Angriffsziel – er enthält Themes, Plugins und Uploads. Eine eigene .htaccess dort erlaubt nur harmlose Dateitypen und blockiert alle anderen:

# Diese .htaccess in /wp-content/ ablegen
Order deny,allow
Deny from all
<Files ~ "\.(xml|css|jpe?g|png|gif|webp|js|woff2?)$">
  Allow from all
</Files>

Mehr zu Sicherheitsmaßnahmen auf WordPress-Ebene – Zwei-Faktor-Authentifizierung, Datenbank-Präfixe, Backup-Strategien – findest du im weiterführenden Guide zur WordPress Sicherheit erhöhen. Die .htaccess ist die erste Verteidigungslinie, aber nicht die einzige.

PHP-Fehlerausgaben absichern

PHP-Fehlermeldungen sind für Entwickler unverzichtbar – für Produktivumgebungen aber ein echtes Sicherheitsrisiko. Ein Stacktrace enthüllt absolute Serverpfade, Klassen- und Funktionsnamen und gibt Angreifern wertvolle Hinweise auf Schwachstellen in der Architektur. Das erschreckende: Es reicht oft, eine einzelne PHP-Datei direkt aufzurufen, um solche Fehler zu provozieren.

# PHP-Fehleranzeige für Besucher deaktivieren
php_flag display_errors Off
php_flag display_startup_errors Off

# Fehler trotzdem ins Server-Log schreiben (für Diagnose)
php_flag log_errors On
php_value error_log /var/log/php_errors.log

Tipp: Umgebungsabhängige Fehlerausgabe

In lokalen Entwicklungsumgebungen willst du Fehler sehen – auf dem Live-Server nicht. Die sauberste Lösung: nutze eine Umgebungsvariable (APP_ENV=production) und steuere display_errors über die php.ini oder den PHP-Code selbst, nicht nur über die .htaccess. Die .htaccess-Direktive ist eine zusätzliche Sicherheitsnetz, kein Ersatz für durchdachtes Error-Handling.

PHP-Version und Servervariablen verschleiern

Apache sendet standardmäßig die exakte Serverversion und installierte Module im HTTP-Header Server. PHP fügt per Standard den X-Powered-By-Header mit der PHP-Version hinzu. Beides hilft Angreifern, gezielt nach bekannten Schwachstellen dieser exakten Version zu suchen. Beides lässt sich abschalten:

# Serverinformationen in HTTP-Headern verstecken
ServerTokens Prod
ServerSignature Off

# X-Powered-By Header entfernen
<IfModule mod_headers.c>
  Header unset X-Powered-By
</IfModule>

# Alternative über php.ini (falls php_flag verfügbar)
php_flag expose_php Off

Komprimierung mit mod_deflate & Brotli

Textbasierte Inhalte – HTML, CSS, JavaScript, SVG, JSON – lassen sich mit mod_deflate (Gzip) oder dem moderneren mod_brotli (Brotli) deutlich komprimieren. Der Effekt ist erheblich: Typische HTML-Seiten schrumpfen auf 20–30 % ihrer Originalgröße. Das beschleunigt den Seitenaufbau und verbessert den Google PageSpeed Score messbar.

# Gzip-Komprimierung mit mod_deflate
<IfModule mod_deflate.c>

  AddOutputFilterByType DEFLATE text/plain
  AddOutputFilterByType DEFLATE text/html
  AddOutputFilterByType DEFLATE text/xml
  AddOutputFilterByType DEFLATE text/css
  AddOutputFilterByType DEFLATE application/javascript
  AddOutputFilterByType DEFLATE application/x-javascript
  AddOutputFilterByType DEFLATE application/json
  AddOutputFilterByType DEFLATE application/ld+json
  AddOutputFilterByType DEFLATE image/svg+xml
  AddOutputFilterByType DEFLATE font/woff2

  # Binärdateien NICHT komprimieren (bereits komprimiert)
  SetEnvIfNoCase REQUEST_URI \.(gif|jpg|jpeg|png|webp|avif)$ no-gzip dont-vary

  # Vary-Header für korrekte Cache-Auslieferung
  <IfModule mod_headers.c>
    Header append Vary Accept-Encoding env=!dont-vary
  </IfModule>

</IfModule>

# Brotli (falls auf dem Server verfügbar – Hetzner unterstützt es)
<IfModule mod_brotli.c>
  AddOutputFilterByType BROTLI_COMPRESS text/html text/css application/javascript application/json
</IfModule>
.htaccess kostenlos analysieren Prüfe deine Konfiguration auf Fehler, Security-Header und Komprimierung – direkt im Browser, ohne Upload.

Testen, debuggen und häufige Fallen

Die .htaccess ist fehlerintolerant. Ein einzelner Syntaxfehler, ein falsches Leerzeichen oder eine vergessene schließende Klammer genügen für einen sofortigen 500 Internal Server Error auf dem gesamten betroffenen Verzeichnis. Damit das nicht passiert, gibt es bewährte Strategien.

Das Backup-Prinzip – non-negotiable

Bevor du die .htaccess veränderst, lade die aktuelle Version herunter und lege sie lokal als htaccess.bak ab. Bei einem Fehler kannst du per FTP die originale Version in Sekunden wiederherstellen. Klingt selbstverständlich – und wird trotzdem regelmäßig vergessen.

Schrittweise testen

Füge Änderungen einzeln hinzu und prüfe nach jeder Anpassung, ob die Website noch erreichbar ist. Browser-Cache beim Testen leeren – gerade bei Redirect-Änderungen cachet der Browser die alte Weiterleitung und zeigt vermeintlich falsches Verhalten, obwohl die neue Regel korrekt wäre.

Online-Tester für RewriteRules

Tools wie htaccess.madewithlove.com erlauben das Testen von RewriteRule-Logik ohne Serverkontakt: URL eingeben, Regeln einfügen, testen. Das Tool zeigt, welche Regel greift, welche Bedingungen erfüllt sind und was die finale URL ist. Besonders wertvoll bei komplexen Redirect-Ketten und beim Debugging von mod_rewrite-Problemen.

Die 7 häufigsten .htaccess-Fehler

  • Syntaxfehler – fehlendes Leerzeichen, falsche Anführungszeichen oder ein Tippfehler im Direktiven-Namen → immer mit Online-Tester prüfen
  • mod_rewrite nicht aktiviertAllowOverride None in der httpd.conf verhindert, dass die .htaccess überhaupt ausgeführt wird → Hoster kontaktieren oder selbst in der Serverkonfiguration aktivieren
  • Redirect-Loop – Weiterleitung von HTTP auf HTTPS, aber Bedingung schließt bereits-HTTPS-Anfragen nicht aus → immer mit RewriteCond %{HTTPS} off absichern
  • Relativer Pfad bei AuthUserFile.htpasswd muss mit absolutem Pfad angegeben werden, nicht relativ → den absoluten Pfad beim Hoster nachfragen
  • HSTS zu früh mit langer Laufzeit – max-age=31536000 ist schwer rückgängig zu machen; mit max-age=300 testen, erst bei Erfolg hochsetzen
  • 7G Firewall blockiert eigene Anfragen – AJAX-Calls mit langen Query Strings oder bestimmten Zeichenketten können fälschlich geblockt werden → Log aktivieren und die spezifische Regel auskommentieren
  • .htaccess wirkt in Subordnern nicht – eigene .htaccess in Unterordnern überschreiben Direktiven aus dem Root nicht immer vollständig; RewriteBase prüfen und ggf. anpassen

Häufige Fragen zur .htaccess

Was macht mod_rewrite in der .htaccess?
mod_rewrite ist das Apache-Modul für URL-Umschreibungen und Weiterleitungen. Es analysiert eingehende Anfragen anhand regulärer Ausdrücke, prüft optionale Bedingungen (RewriteCond) und transformiert oder leitet URLs dann intern oder per Browser-Redirect weiter. Fast alle modernen CMS setzen mod_rewrite für sprechende URLs voraus – WordPress, TYPO3, Magento ohne es funktionieren schlicht nicht.
Was ist die 7G Firewall und wie bindet man sie ein?
Die 7G Firewall von Jeff Starr (Perishable Press) ist eine quelloffene Apache-Firewall, die per .htaccess aktiviert wird. Sie blockiert schadhaften Traffic durch Mustererkennung in Query Strings, Request URIs, User Agents, Remote Hosts und HTTP Referrern – ohne legitime Nutzer zu stören. Einbindung: Den vollständigen aktuellen 7G-Code von perishablepress.com herunterladen und an den Anfang der .htaccess einfügen.
Warum sollte man PHP-Fehlermeldungen per .htaccess abschalten?
PHP-Fehlermeldungen enthalten absolute Serverpfade, Klassen- und Funktionsnamen – wertvolle Informationen für Angreifer. Mit php_flag display_errors Off in der .htaccess werden Fehler für Besucher unsichtbar gemacht. Gleichzeitig sollte log_errors On gesetzt sein, damit Fehler dennoch im Server-Log landen und du Probleme diagnostizieren kannst.
Wie funktioniert URL Rewriting mit PHP-Variablen?
Mit RewriteCond %{REQUEST_FILENAME} !-f, !-d und RewriteRule .* /index.php [L] werden alle Anfragen auf nicht-existente Dateien an eine zentrale PHP-Datei geleitet. Diese liest $_SERVER['REQUEST_URI'] aus, zerlegt den Pfad in Segmente und entscheidet, welche Inhalte ausgegeben werden. Das ist die Basis jedes Routing-Systems – von einfachen PHP-Projekten bis zu Laravel und Symfony.
Verbessert mod_deflate den Google PageSpeed Score?
Ja, direkt und messbar. Gzip-Komprimierung ist eine der Maßnahmen, die Google in den Core Web Vitals als „Textbasierte Ressourcen komprimieren" empfiehlt. HTML-Seiten schrumpfen auf 20–30 % ihrer ursprünglichen Größe, CSS und JavaScript um weitere 60–80 %. Das reduziert die Übertragungszeit und damit LCP und TTFB – zwei kritische PageSpeed-Faktoren.
Adrian Thommes – Marketing Experte & SEO Spezialist Saarland

Adrian Thommes

Die .htaccess ist eine dieser Dateien, die man als Webmaster entweder versteht oder sich ewig über unerklärliche 500-Fehler ärgert. Wer einmal begriffen hat, wie mod_rewrite denkt – sequenziell, musterbezogen, konditional – der sieht URL-Weiterleitungen und Zugriffsregeln plötzlich nicht mehr als Magie, sondern als handwerkliches Werkzeug. Die 7G Firewall an erster Stelle, WordPress-Härtung darunter, Komprimierung obendrauf: eine gut strukturierte .htaccess ist kein Hexenwerk – sie ist Architektur.