mod_rewrite ist das mächtigste Apache-Modul für URL-Manipulation. Damit erstellen Sie saubere URLs, richten Weiterleitungen ein und verbessern die SEO Ihrer Website.

Grundlagen

mod_rewrite aktivieren

# Modul aktivieren
a2enmod rewrite

# Apache neu starten
systemctl restart apache2

AllowOverride aktivieren

# /etc/apache2/sites-available/example.conf
<Directory /var/www/html>
    AllowOverride All
</Directory>

.htaccess Grundstruktur

# Rewrite-Engine aktivieren
RewriteEngine On

# Basis-Verzeichnis (optional)
RewriteBase /

RewriteRule Syntax

Grundsyntax

RewriteRule Muster Ziel [Flags]

Beispiel erklärt

RewriteRule ^artikel/([0-9]+)$ artikel.php?id=$1 [L]

# Erklärung:
# ^artikel/    - URL beginnt mit "artikel/"
# ([0-9]+)     - Eine oder mehr Ziffern (Gruppe 1)
# $            - URL endet hier
# artikel.php  - Ziel-Skript
# ?id=$1       - Parameter mit Gruppe 1
# [L]          - Last: Keine weiteren Regeln

Wichtige Flags

| Flag | Bedeutung | |------|-----------| | [L] | Last - Letzte Regel | | [R] | Redirect (302) | | [R=301] | Permanente Weiterleitung | | [NC] | No Case - Groß/Klein ignorieren | | [QSA] | Query String Append | | [F] | Forbidden (403) | | [G] | Gone (410) | | [P] | Proxy | | [NE] | No Escape |

RewriteCond - Bedingungen

Syntax

RewriteCond TestString Muster [Flags]
RewriteRule ...

Server-Variablen

# Häufig verwendete Variablen
%{REQUEST_URI}      # /pfad/seite.html
%{QUERY_STRING}     # var=wert
%{HTTP_HOST}        # example.com
%{REQUEST_METHOD}   # GET, POST
%{HTTPS}            # on oder leer
%{HTTP_USER_AGENT}  # Browser-String
%{REMOTE_ADDR}      # Client-IP
%{REQUEST_FILENAME} # Vollständiger Dateipfad

Beispiel mit Bedingung

# Nur wenn Datei nicht existiert
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [L,QSA]

Häufige Anwendungsfälle

1. HTTP zu HTTPS umleiten

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

2. www zu non-www

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [L,R=301]

3. non-www zu www

RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [L,R=301]

4. Trailing Slash entfernen

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]

5. Trailing Slash hinzufügen

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ $1/ [L,R=301]

6. Dateiendung entfernen

# .php entfernen
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]

7. Saubere URLs (Clean URLs)

# /produkt/123 → produkt.php?id=123
RewriteEngine On
RewriteRule ^produkt/([0-9]+)/?$ produkt.php?id=$1 [L,QSA]

# /kategorie/elektronik → kategorie.php?name=elektronik
RewriteRule ^kategorie/([a-zA-Z0-9-]+)/?$ kategorie.php?name=$1 [L,QSA]

# /blog/2026/01/artikel-titel
RewriteRule ^blog/([0-9]{4})/([0-9]{2})/([a-zA-Z0-9-]+)/?$ blog.php?year=$1&month=$2&slug=$3 [L,QSA]

WordPress spezifisch

Standard WordPress .htaccess

# 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

# WordPress in /blog/
RewriteEngine On
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]

WordPress Multisite

RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]

# Uploaded files
RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-includes/ms-files.php?file=$2 [L]

# Prevent access to wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]

Sicherheit

Verzeichnislisting deaktivieren

Options -Indexes

Zugriff auf bestimmte Dateien blockieren

# .htaccess und .htpasswd schützen
<FilesMatch "^\.ht">
    Require all denied
</FilesMatch>

# wp-config.php schützen
<Files wp-config.php>
    Require all denied
</Files>

# Alle .ini Dateien blockieren
<FilesMatch "\.ini$">
    Require all denied
</FilesMatch>

Verzeichnis schützen

# /admin/ nur für bestimmte IPs
<Directory /var/www/html/admin>
    Require ip 192.168.1.0/24
</Directory>

# In .htaccess
RewriteEngine On
RewriteCond %{REMOTE_ADDR} !^192\.168\.1\.
RewriteRule ^admin/ - [F,L]

Bot-Blocking

# Bekannte Bad Bots blockieren
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (bot1|bot2|scraper) [NC]
RewriteRule .* - [F,L]
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?example\.com [NC]
RewriteRule \.(jpg|jpeg|png|gif|webp)$ - [F,NC]

Weiterleitungen

Einzelne Seite umleiten

# 301 Redirect
Redirect 301 /alte-seite.html https://example.com/neue-seite

# Mit RewriteRule
RewriteRule ^alte-seite\.html$ /neue-seite [R=301,L]

Ganzes Verzeichnis umleiten

RewriteRule ^altes-verzeichnis/(.*)$ /neues-verzeichnis/$1 [R=301,L]

Domain-Umleitung

RewriteEngine On
RewriteCond %{HTTP_HOST} ^alte-domain\.com$ [NC]
RewriteRule ^(.*)$ https://neue-domain.com/$1 [R=301,L]

Query-String Weiterleitung

# /seite.php?id=123 → /seite/123
RewriteCond %{QUERY_STRING} ^id=([0-9]+)$
RewriteRule ^seite\.php$ /seite/%1? [R=301,L]

Performance-Optimierung

Caching-Header

<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType text/css "access plus 1 month"
    ExpiresByType application/javascript "access plus 1 month"
</IfModule>

Kompression

<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/xml
    AddOutputFilterByType DEFLATE text/css application/javascript
    AddOutputFilterByType DEFLATE application/json
</IfModule>

Debugging

Rewrite-Log aktivieren

# Apache 2.4+ in VirtualHost
LogLevel alert rewrite:trace3

Log-Datei prüfen

tail -f /var/log/apache2/error.log | grep rewrite

Regel testen

# Temporäre Test-Regel
RewriteRule ^test$ /debug.php?matched=yes [L]

Reguläre Ausdrücke

Wichtige Muster

| Muster | Bedeutung | |--------|-----------| | ^ | Zeilenanfang | | $ | Zeilenende | | . | Beliebiges Zeichen | | * | 0 oder mehr | | + | 1 oder mehr | | ? | 0 oder 1 | | [abc] | a, b oder c | | [a-z] | Kleinbuchstaben | | [0-9] | Ziffern | | () | Gruppe (für $1, $2) | | \ | Escape |

Beispiele

# Beliebige Zeichen
^(.*)$

# Nur Ziffern
^([0-9]+)$

# Slug (Buchstaben, Zahlen, Bindestrich)
^([a-zA-Z0-9-]+)$

# Dateiname mit Endung
^([a-zA-Z0-9-]+)\.(html|php)$

# Datum Format
^([0-9]{4})-([0-9]{2})-([0-9]{2})$

Komplettes Beispiel

# .htaccess für eine typische Website

# Rewrite aktivieren
RewriteEngine On
RewriteBase /

# HTTPS erzwingen
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# www entfernen
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [L,R=301]

# Trailing Slash entfernen
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]

# Saubere URLs
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9-]+)/?$ seite.php?slug=$1 [L,QSA]

RewriteRule ^produkt/([0-9]+)/?$ produkt.php?id=$1 [L,QSA]
RewriteRule ^kategorie/([a-zA-Z0-9-]+)/?$ kategorie.php?name=$1 [L,QSA]

# Sicherheit
Options -Indexes
<FilesMatch "\.(htaccess|htpasswd|ini|log|sh)$">
    Require all denied
</FilesMatch>

# Caching
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType text/css "access plus 1 month"
    ExpiresByType application/javascript "access plus 1 month"
</IfModule>

# Kompression
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/css
    AddOutputFilterByType DEFLATE application/javascript application/json
</IfModule>

Fazit

mod_rewrite ist unverzichtbar für moderne Webentwicklung. Mit sauberen URLs verbessern Sie SEO, mit Weiterleitungen erhalten Sie Link-Equity bei Umstrukturierungen. Testen Sie Regeln immer gründlich und aktivieren Sie das Rewrite-Log zum Debugging. Die Reihenfolge der Regeln ist wichtig - spezifischere Regeln sollten vor allgemeineren stehen.