Das Apache-Modul mod_rewrite ermöglicht die Umschreibung von URLs auf Serverebene. Es ist essentiell für SEO-freundliche URLs und flexible Weiterleitungen.
mod_rewrite aktivieren
Modul laden
# Debian/Ubuntu
a2enmod rewrite
systemctl restart apache2
# CentOS/RHEL
# In /etc/httpd/conf/httpd.conf
LoadModule rewrite_module modules/mod_rewrite.so
systemctl restart httpdAllowOverride aktivieren
# /etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/html
<Directory /var/www/html>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>Grundlagen
Syntax
RewriteEngine On
RewriteRule Pattern Substitution [Flags]
RewriteCond TestString CondPattern [Flags]Einfache Beispiele
# .htaccess
RewriteEngine On
# Einfache Weiterleitung
RewriteRule ^alte-seite\.html$ /neue-seite.html [R=301,L]
# Dateiendung entfernen
RewriteRule ^([^/]+)$ $1.html [L]
# Query String umwandeln
# /artikel?id=123 → /artikel/123
RewriteRule ^artikel/([0-9]+)$ /artikel.php?id=$1 [L,QSA]RewriteRule Flags
| Flag | Bedeutung | |------|-----------| | L | Last - letzte Regel | | R=301 | Redirect permanent | | R=302 | Redirect temporär | | NC | NoCase - case-insensitive | | QSA | Query String Append | | F | Forbidden (403) | | G | Gone (410) | | NE | NoEscape | | PT | PassThrough | | S=n | Skip n Regeln | | E=var:val | Environment Variable |
Flag-Beispiele
RewriteEngine On
# Permanent Redirect mit L Flag
RewriteRule ^old/(.*)$ /new/$1 [R=301,L]
# Case-insensitive Match
RewriteRule ^contact$ /kontakt [NC,R=301,L]
# Query String erhalten
RewriteRule ^suche/(.*)$ /search.php?q=$1 [QSA,L]
# 403 Forbidden
RewriteRule ^private/ - [F,L]RewriteCond (Bedingungen)
Syntax
RewriteCond TestString CondPattern [Flags]Server-Variablen
| Variable | Beschreibung | |----------|--------------| | %{HTTP_HOST} | Domain-Name | | %{REQUEST_URI} | Angefragter Pfad | | %{QUERY_STRING} | Query Parameter | | %{REQUEST_METHOD} | GET, POST, etc. | | %{HTTP_USER_AGENT} | Browser/Bot | | %{HTTP_REFERER} | Herkunftsseite | | %{HTTPS} | on oder off | | %{REMOTE_ADDR} | Client-IP | | %{REQUEST_FILENAME} | Dateipfad |
Bedingungsflags
| Flag | Bedeutung | |------|-----------| | NC | NoCase | | OR | Oder-Verknüpfung | | NV | No Vary |
Beispiele mit Bedingungen
RewriteEngine On
# Nur wenn HTTPS nicht aktiv
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
# Nur für bestimmte Domain
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
# Nur wenn Datei nicht existiert
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [QSA,L]SEO-freundliche URLs
Dynamische zu statischen URLs
# Vorher: /produkt.php?id=123&name=laptop
# Nachher: /produkt/123/laptop
RewriteEngine On
RewriteRule ^produkt/([0-9]+)/([a-z-]+)$ /produkt.php?id=$1&name=$2 [L,QSA]Blog-URLs
# /blog/2026/01/artikel-titel → /blog.php?year=2026&month=01&slug=artikel-titel
RewriteEngine On
RewriteRule ^blog/([0-9]{4})/([0-9]{2})/([a-z0-9-]+)$ /blog.php?year=$1&month=$2&slug=$3 [L]Kategorien und Produkte
# /kategorie/elektronik → /kategorie.php?name=elektronik
# /produkt/laptop-abc → /produkt.php?slug=laptop-abc
RewriteEngine On
RewriteRule ^kategorie/([a-z0-9-]+)$ /kategorie.php?name=$1 [L]
RewriteRule ^produkt/([a-z0-9-]+)$ /produkt.php?slug=$1 [L]Weiterleitungen
Domain-Weiterleitungen
RewriteEngine On
# www zu non-www
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
# non-www zu www
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
# Alte Domain zur neuen
RewriteCond %{HTTP_HOST} ^alte-domain\.de$ [NC,OR]
RewriteCond %{HTTP_HOST} ^www\.alte-domain\.de$ [NC]
RewriteRule ^(.*)$ https://neue-domain.de/$1 [R=301,L]HTTP zu HTTPS
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]Trailing Slash
# Slash entfernen
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ /$1 [R=301,L]
# Slash hinzufügen
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^.]+[^/])$ /$1/ [R=301,L]Front Controller Pattern
Alle Anfragen an index.php
RewriteEngine On
# Statische Dateien direkt ausliefern
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Alles andere an index.php
RewriteRule ^(.*)$ /index.php [L,QSA]Mit Ausnahmen
RewriteEngine On
# Bestimmte Pfade ausschließen
RewriteCond %{REQUEST_URI} !^/api/
RewriteCond %{REQUEST_URI} !^/assets/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php [L]Sicherheit
Verzeichnisse schützen
# Zugriff auf sensible Verzeichnisse blockieren
RewriteRule ^\.git - [F,L]
RewriteRule ^\.env - [F,L]
RewriteRule ^vendor/ - [F,L]
RewriteRule ^config/ - [F,L]Hotlinking verhindern
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?example\.com/ [NC]
RewriteRule \.(jpg|jpeg|png|gif|webp)$ /images/hotlink.png [L,R=302]Bots blockieren
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (bot1|bot2|badcrawler) [NC]
RewriteRule ^ - [F,L]IP-basierte Zugriffskontrolle
RewriteEngine On
RewriteCond %{REMOTE_ADDR} !^192\.168\.1\.
RewriteRule ^admin/ - [F,L]WordPress-Beispiele
Standard Permalinks
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPressWordPress in Unterverzeichnis
RewriteEngine On
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]Laravel/Symfony
Laravel .htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>Debugging
Rewrite Log aktivieren
# In VirtualHost (nicht .htaccess)
LogLevel alert rewrite:trace3# Log prüfen
tail -f /var/log/apache2/error.log | grep rewriteHäufige Fehler
# Falsch: Endlosschleife
RewriteRule ^(.*)$ /index.php [L]
# Richtig: Bedingung hinzufügen
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php [L]# Falsch: Fehlender RewriteEngine
RewriteRule ^test$ /test.php [L]
# Richtig
RewriteEngine On
RewriteRule ^test$ /test.php [L]Reguläre Ausdrücke
Wichtige Patterns
| Pattern | Bedeutung | |---------|-----------| | ^ | Zeilenanfang | | $ | Zeilenende | | . | Beliebiges Zeichen | | * | 0 oder mehr | | + | 1 oder mehr | | ? | 0 oder 1 | | [abc] | Zeichenklasse | | [^abc] | Negierte Klasse | | (pattern) | Gruppe (Backreference) | | \| | Oder |
Beispiele
# Nur Zahlen
RewriteRule ^([0-9]+)$ /page.php?id=$1 [L]
# Alphanumerisch mit Bindestrich
RewriteRule ^([a-z0-9-]+)$ /slug.php?slug=$1 [L]
# Dateiendung optional
RewriteRule ^([^/]+)(\.html)?$ /page.php?name=$1 [L]
# Mehrere Segmente
RewriteRule ^([^/]+)/([^/]+)/([^/]+)$ /view.php?a=$1&b=$2&c=$3 [L]Performance
Regeln optimieren
# Weniger effizient
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php [L]
# Effizienter mit spezifischem Pattern
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^[a-z0-9/-]+$ /index.php [L]In VirtualHost statt .htaccess
# Besser: Direkt in VirtualHost
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/html
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php [L]
</VirtualHost>Zusammenfassung
| Komponente | Zweck | |------------|-------| | RewriteEngine On | Modul aktivieren | | RewriteRule | URL-Umschreibung | | RewriteCond | Bedingung | | RewriteBase | Basispfad |
| Typische Anwendung | Beispiel | |--------------------|----------| | SEO-URLs | /produkt/123 → /produkt.php?id=123 | | HTTPS erzwingen | HTTP → HTTPS Redirect | | Domain-Redirect | www ↔ non-www | | Front Controller | Alles → index.php |
| Flag | Häufigste Verwendung | |------|---------------------| | L | Letzte Regel | | R=301 | Permanent Redirect | | NC | Case-insensitive | | QSA | Query String erhalten |
Fazit
mod_rewrite ist unverzichtbar für SEO-freundliche URLs und flexible Weiterleitungen. Die Kombination aus RewriteRule und RewriteCond ermöglicht komplexe URL-Transformationen. Für beste Performance sollten Regeln im VirtualHost statt in .htaccess stehen. Das Verständnis von regulären Ausdrücken ist essentiell für effektive Rewrite-Regeln.