Apache vs. Nginx: Wer nutzt was?
Bevor du dich in Konfigurationsregeln vertiefst, solltest du wissen, welchen Webserver dein Hosting nutzt. Das bestimmt, welche Datei du bearbeiten musst:
| Webserver | Konfigurationsdatei | Typischer Einsatz |
|---|---|---|
| Apache | .htaccess (pro Verzeichnis) |
Shared Hosting, klassische Hosting-Pakete |
| Nginx | nginx.conf, sites-enabled/ |
VPS, Cloud, Managed Server, High-Traffic |
| Apache + Nginx | Beide (Nginx vorne, Apache hinten) | Optimierte Setups mit Reverse Proxy |
Die meisten Shared-Hostings (Strato, 1&1, Host Europe) nutzen Apache. Professionelle Setups und VPS (Hetzner, DigitalOcean, AWS) nutzen oft Nginx — oder Apache als Backend hinter Nginx. In diesem Guide findest du beide Varianten.
.htaccess kann teuer werden
Apache liest die .htaccess-Datei bei jeder einzelnen Anfrage neu — auch bei Bildern, CSS, JS. Das kostet Performance. Bei Shared Hosting ist es okay, aber wenn du 50+ Rewrite-Rules hast, consider migrating zu einer zentralen Apache-Konfiguration oder Nginx, wo die Config nur einmal beim Start geladen wird.
SSL/HTTPS erzwingen
HTTPS ist Pflicht — für SEO, Browser-Warnungen und Nutzervertrauen. Hier die Regeln, um HTTP automatisch auf HTTPS umzuleiten:
Apache (.htaccess)
# HTTPS erzwingen
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Nginx
server {
listen 80;
server_name beispiel.de www.beispiel.de;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name www.beispiel.de;
return 301 https://beispiel.de$request_uri;
}
server {
listen 443 ssl http2;
server_name beispiel.de;
# ... restliche Konfiguration
}
WWW vs. Non-WWW umleiten
Eine klare Preference für eine Variante (mit oder ohne www) ist wichtig für SEO — duplicate content wird vermieden.
Apache: Non-WWW bevorzugen
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\beispiel.de$ [NC]
RewriteRule ^(.*)$ https://beispiel.de/$1 [L,R=301]
Apache: WWW bevorzugen
RewriteEngine On
RewriteCond %{HTTP_HOST} ^beispiel.de$ [NC]
RewriteRule ^(.*)$ https://www.beispiel.de/$1 [L,R=301]
Nginx: Non-WWW bevorzugen
server {
listen 443 ssl;
server_name www.beispiel.de;
return 301 https://beispiel.de$request_uri;
}
Security-Header setzen
Security-Header sind der einfachste Weg, deine Website gegen gängige Angriffe abzusichern. Sie werden im HTTP-Response gesendet und vom Browser interpretiert.
Apache (.htaccess)
<IfModule mod_headers.c>
# X-Frame-Options: Verhindert Clickjacking
Header set X-Frame-Options "SAMEORIGIN"
# X-Content-Type-Options: Kein MIME-Type-Sniffing
Header set X-Content-Type-Options "nosniff"
# X-XSS-Protection (veraltet, aber manche Browser nutzen es noch)
Header set X-XSS-Protection "1; mode=block"
# Referrer-Policy: Volle Referrer-Info nur bei HTTPS
Header set Referrer-Policy "strict-origin-when-cross-origin"
# Permissions-Policy: Deaktiviert unnötige Browser-Features
Header set Permissions-Policy "geolocation=(), microphone=(), camera=()"
# Content-Security-Policy: Kontrolliert, was geladen werden darf
Header set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';"
</IfModule>
Nginx
server {
# ... ssl config ...
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self';" always;
}
CSP richtig einrichten
Die Content-Security-Policy ist mächtig, aber auch fehleranfällig. Beginne mit einem Report-Only-Modus, um zu sehen, was blockiert würde: Header set Content-Security-Policy-Report-Only "..." — dann sammelst du Daten, bevor du den strikten Modus aktivierst. Eine zu strikte CSP kann deine Website komplett lahmlegen.
Browser-Caching aktivieren
Statische Ressourcen (Bilder, CSS, JS, Fonts) ändern sich selten. Caching spart Bandbreite und beschleunigt wiederholte Seitenaufrufe drastisch.
Apache (.htaccess)
<IfModule mod_expires.c>
ExpiresActive On
# Bilder
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
# CSS & JS
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
# Fonts
ExpiresByType font/woff2 "access plus 1 year"
ExpiresByType font/woff "access plus 1 year"
ExpiresByType font/ttf "access plus 1 year"
# HTML (kurz halten!)
ExpiresByType text/html "access plus 0 seconds"
</IfModule>
Nginx
server {
# ... restliche config ...
location ~* \/(jpg|jpeg|png|gif|webp|svg|ico)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
location ~* \/(css|js|javascript)$ {
expires 1M;
add_header Cache-Control "public";
}
location ~* \/(woff2|woff|ttf|otf)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
location ~* \/.*$ {
expires -1;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
}
GZIP-Komprimierung aktivieren
GZIP reduziert die Dateigröße von Text-Dateien (HTML, CSS, JS, JSON) um 60–80 %. Das ist einer der größten Performance-Hebler und kostet fast nichts.
Apache
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/json
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE image/svg+xml
# Browser-spezifische Komprimierung
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/atom+xml
</IfModule>
Nginx
# In nginx.conf, im http-Block:
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_types text/plain text/css text/javascript application/javascript application/json application/xml application/rss+xml application/atom+xml image/svg+xml;
PHP-Version und Datei-Upload begrenzen
Sicherheitsrelevante Restriktionen in der .htaccess:
# PHP-Version und Features einschränken
<IfModule mod_php.c>
php_flag display_errors Off
php_flag log_errors On
php_flag engine off
php_value upload_max_filesize 64M
php_value post_max_size 128M
php_value max_execution_time 60
php_value max_input_time 60
php_value memory_limit 256M
</IfModule>
# Verbiete den Zugriff auf versteckte Dateien
<FilesMatch "^\\.">
Order allow,deny
Deny from all
</FilesMatch>
Hotlink-Schutz
Hotlinking bedeutet, dass andere Websites deine Bilder direkt einbinden — du bezahlst für deren Bandbreite. Das blockierst du so:
Apache
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https://(www\\\\.)?beispiel\\.de [NC]
RewriteCond %{HTTP_REFERER} !^https://(www\\\\\\\\\\\\.)?google\\. [NC]
RewriteRule \\.(jpg|jpeg|png|gif|webp)$ - [F,NC]
Nginx
location ~* \\.(jpg|jpeg|png|gif|webp)$ {
valid_referers none blocked ~google. ~bing. beispiel.de;
if ($invalid_referer) {
return 403;
}
}
Error Pages und Rewrites
WordPress und andere CMS brauchen Rewrite-Regeln, damit URLs wie /blog/mein-artikel/ funktionieren.
Apache: WordPress Permalinks
# WordPress Rewrite (für "hübsche" URLs)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\\\\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Nginx: WordPress (PHP-FPM)
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \\.php$ {
fastcgi_pass unix:/var/run/php/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# Statische Dateien direkt ausliefern
location ~* \\.(css|js|jpg|jpeg|png|gif|webp|svg|ico|woff|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
try_files $uri =404;
}
Rate Limiting: Brute-Force-Angriffe stoppen
Login-Seiten und API-Endpunkte sind beliebte Ziele für Brute-Force-Angriffe. Rate Limiting begrenzt, wie oft ein IP in einer bestimmten Zeit zugreifen kann.
Nginx Rate Limiting
# Im http-Block: Limit-Zone definieren
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/s;
server {
# Login-Seiten: max 5 Requests pro Sekunde
location /wp-login.php {
limit_req zone=login burst=10 nodelay;
fastcgi_pass unix:/var/run/php/php-fpm.sock;
# ... fastcgi config
}
# API: 30 Requests pro Sekunde
location /api/ {
limit_req zone=api:10m rate=30r/s;
# ... api config
}
}
Apache: Fail2ban oder mod_evasive
Apache hat kein eingebautes Rate Limiting. Für Shared Hosting nutze Plugins (Wordfence, iThemes Security). Für VPS: Fail2ban blockiert IP-Adressen nach zu vielen fehlgeschlagenen Login-Versuchen.
Checkliste: Was du sofort umsetzen solltest
Hier die wichtigsten Punkte, sortiert nach Priorität:
- HTTPS erzwingen — 301-Redirect von HTTP zu HTTPS (oberste Priorität)
- WWW vs. Non-WWW fixieren — Duplicate Content vermeiden
- Security-Header setzen — X-Frame-Options, X-Content-Type-Options, CSP
- Browser-Caching für statische Dateien — 1 Jahr für Bilder, 1 Monat für CSS/JS
- GZIP-Komprimierung aktivieren — Text-Dateien um 60–80 % komprimieren
- WordPress Permalinks — Rewrite-Regeln für saubere URLs
- PHP-Error-Anzeige deaktivieren — display_errors = Off in Produktion
- Rate Limiting — Login-Seiten und API-Endpunkte schützen
Testen, testen, testen
Nach jeder Änderung: Browser-Cache leeren (oder Inkognito-Fenster nutzen) und die Seite prüfen. Nutze Browser DevTools → Network Tab, um zu prüfen, ob Caching und GZIP aktiv sind. Ein falscher Redirect-Loop ist schnell passiert — teste jede Regel einzeln.
Finde den perfekten Hosting-Anbieter
Vergleiche Anbieter, die SSH-Zugang und volle .htaccess/Nginx-Kontrolle bieten — für maximale Konfigurationsfreiheit.
Zum Hosting-Vergleich