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 httpd
AllowOverride 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 WordPress
WordPress 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 rewrite
Hä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]
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.