Ein Reverse Proxy nimmt Anfragen entgegen und leitet sie an Backend-Server weiter. Nginx ist dafür besonders gut geeignet.
Warum Reverse Proxy?
- SSL-Terminierung: HTTPS am Proxy, HTTP zum Backend
- Load Balancing: Anfragen auf mehrere Server verteilen
- Mehrere Apps: Verschiedene Anwendungen unter einer Domain
- Caching: Statische Inhalte cachen
- Sicherheit: Backend-Server verstecken
Grundlegende Konfiguration
Einfacher Reverse Proxy
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Wichtige Proxy-Header
| Header | Beschreibung | |--------|--------------| | Host | Original-Hostname | | X-Real-IP | Client-IP-Adresse | | X-Forwarded-For | Proxy-Kette | | X-Forwarded-Proto | http oder https |
Mit SSL/TLS
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Mehrere Anwendungen
Verschiedene Pfade
server {
listen 443 ssl http2;
server_name example.com;
# Hauptanwendung
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
# API
location /api/ {
proxy_pass http://localhost:8080/;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
# Admin-Panel
location /admin/ {
proxy_pass http://localhost:8000/;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
}Verschiedene Subdomains
server {
listen 443 ssl http2;
server_name app.example.com;
location / {
proxy_pass http://localhost:3000;
}
}
server {
listen 443 ssl http2;
server_name api.example.com;
location / {
proxy_pass http://localhost:8080;
}
}Load Balancing
Upstream-Definition
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
server {
listen 443 ssl http2;
server_name example.com;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
}Gewichtung
upstream backend {
server 192.168.1.10:8080 weight=3;
server 192.168.1.11:8080 weight=2;
server 192.168.1.12:8080 weight=1;
}Backup-Server
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080 backup;
}Methoden
upstream backend {
# Round-Robin (Standard)
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
upstream backend_ip {
ip_hash; # Sticky Sessions
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
upstream backend_least {
least_conn; # Wenigste Verbindungen
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}WebSocket-Unterstützung
location /ws/ {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
}Caching
Proxy-Cache aktivieren
http {
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m;
server {
location / {
proxy_pass http://localhost:3000;
proxy_cache my_cache;
proxy_cache_valid 200 60m;
proxy_cache_valid 404 1m;
add_header X-Cache-Status $upstream_cache_status;
}
}
}Cache-Bypass
location / {
proxy_pass http://localhost:3000;
proxy_cache my_cache;
proxy_cache_bypass $http_cache_control;
proxy_no_cache $http_pragma $http_authorization;
}Health Checks
Passive Health Checks
upstream backend {
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
}Active Health Checks (Nginx Plus)
upstream backend {
zone backend 64k;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
health_check interval=5s;
}Timeouts konfigurieren
location / {
proxy_pass http://localhost:3000;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# Für langsame Uploads
client_max_body_size 100m;
client_body_timeout 120s;
}Rate Limiting
http {
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://localhost:8080;
}
}
}Sicherheitsheader
server {
location / {
proxy_pass http://localhost:3000;
# Sicherheitsheader
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;
# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
}Typische Setups
Node.js-Anwendung
server {
listen 443 ssl http2;
server_name app.example.com;
ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}Docker-Container
upstream docker_app {
server 127.0.0.1:8080;
}
server {
listen 443 ssl http2;
server_name docker.example.com;
location / {
proxy_pass http://docker_app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}Grafana
server {
listen 443 ssl http2;
server_name grafana.example.com;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /api/live/ {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}Debugging
Logs erweitern
log_format proxy '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'upstream: $upstream_addr '
'response_time: $upstream_response_time';
access_log /var/log/nginx/proxy_access.log proxy;Fehler prüfen
nginx -t
tail -f /var/log/nginx/error.logFazit
Nginx als Reverse Proxy ist extrem vielseitig. SSL-Terminierung, Load Balancing und mehrere Anwendungen unter einer Domain sind nur einige Einsatzmöglichkeiten. Mit der richtigen Konfiguration wird Nginx zum zentralen Zugangspunkt Ihrer Infrastruktur.