- Startseite
- CDN-Simulator
- NGINX-Konfiguration
NGINX-Konfiguration
Das Cloud-Init-Provisioning stellt eine vollständig leistungsoptimierte NGINX-CDN-Edge-Konfiguration bereit. Diese Seite dokumentiert jede Konfigurationsschicht, von der Kernel-Optimierung über das Cache-Verhalten bis hin zur Vendor-Header-Injection. Alle Einstellungen wurden in einem 48-stündigen kontinuierlichen Lasttest mit einem Spitzenwert von 172.540 req/s verifiziert.
Konfigurationsdateien
Abschnitt betitelt „Konfigurationsdateien“| Datei | Zweck |
|---|---|
/etc/sysctl.d/99-cdn-tuning.conf | Linux-Kernel-Netzwerkoptimierung |
/etc/systemd/system/nginx.service.d/override.conf | Dateideskriptor-Limits für NGINX |
/etc/security/limits.d/99-nginx.conf | Betriebssystem-Limits für den www-data-Benutzer |
/etc/nginx/nginx.conf | NGINX-Hauptkonfiguration (Worker, Buffer, Gzip, Logging) |
/etc/nginx/conf.d/cdn-edge.conf | CDN-Proxy-Konfiguration (Cache, Upstream, Header) |
Kernel-Optimierung
Abschnitt betitelt „Kernel-Optimierung“Wird beim Booten über /etc/sysctl.d/99-cdn-tuning.conf angewendet.
| Parameter | Wert | Standard | Zweck |
|---|---|---|---|
net.core.somaxconn | 65535 | 4096 | Listen-Backlog-Warteschlangengröße |
net.core.netdev_max_backlog | 65535 | 1000 | Pro-CPU eingehender Paket-Backlog |
net.ipv4.tcp_max_syn_backlog | 65535 | 256 | SYN-Anforderungswarteschlange (verhindert Drops bei Lastspitzen) |
net.ipv4.tcp_tw_reuse | 1 | 2 | Wiederverwendung von TIME_WAIT-Sockets für ausgehende Verbindungen |
net.ipv4.ip_local_port_range | 1024-65535 | 32768-60999 | Ephemerer Portbereich (64K vs. 28K) |
net.core.rmem_max | 16 MB | 212 KB | Maximaler Empfangs-Socket-Buffer |
net.core.wmem_max | 16 MB | 212 KB | Maximaler Sende-Socket-Buffer |
net.ipv4.tcp_rmem | 4K/87K/16M | 4K/131K/6M | Pro-Socket-Empfangsbuffer (Min/Standard/Max) |
net.ipv4.tcp_wmem | 4K/65K/16M | 4K/16K/4M | Pro-Socket-Sendebuffer (Min/Standard/Max) |
net.ipv4.tcp_fin_timeout | 15 | 60 | FIN_WAIT_2-Timeout (schnellere Socket-Bereinigung) |
net.ipv4.tcp_keepalive_time | 300 | 7200 | Keepalive-Probes nach 5 Min. Leerlauf starten |
net.ipv4.tcp_slow_start_after_idle | 0 | 1 | Congestion Window bei inaktiven Verbindungen warmhalten |
net.ipv4.tcp_max_tw_buckets | 2000000 | ~65536 | Maximale TIME_WAIT-Sockets |
fs.file-max | 2097152 | variiert | Systemweites Dateideskriptor-Limit |
vm.swappiness | 10 | 60 | RAM gegenüber Swap für Cache-Daten bevorzugen |
NGINX-Hauptkonfiguration
Abschnitt betitelt „NGINX-Hauptkonfiguration“Worker und Verbindungen
Abschnitt betitelt „Worker und Verbindungen“worker_processes auto; # 4 workers on D4s_v5 (1 per vCPU)worker_rlimit_nofile 65535; # Per-worker file descriptor limit
events { use epoll; # Linux-optimized event model worker_connections 8192; # 4 workers x 8192 = 32,768 max concurrent multi_accept on; # Accept all pending connections per event loop accept_mutex off; # Not needed with epoll + reuseport}Das Systemd-Override unter /etc/systemd/system/nginx.service.d/override.conf setzt LimitNOFILE=65535 entsprechend.
Proxy-Buffer
Abschnitt betitelt „Proxy-Buffer“proxy_buffering on;proxy_buffer_size 16k; # Header buffer (handles large CDN headers)proxy_buffers 64 16k; # 1 MB per connection (64 x 16k)proxy_busy_buffers_size 256k; # Can send 256k to client while still readingDie Busy-Buffer-Größe von 256k ist entscheidend — sie muss die größte gecachte Antwort übersteigen (Juice Shop ist 75 KB). Die ursprüngliche 64k-Einstellung verursachte Serialisierung unter Last.
Gzip-Komprimierung
Abschnitt betitelt „Gzip-Komprimierung“gzip on;gzip_comp_level 4; # Balance: ~85% of max compression at ~40% CPUgzip_min_length 256; # Skip tiny responses (gzip header overhead)gzip_vary on; # Vary: Accept-Encoding for correct cachinggzip_proxied any; # Compress all proxied responsesgzip_types text/plain text/css text/javascript text/xml application/json application/javascript application/xml application/xml+rss application/atom+xml application/ld+json application/manifest+json image/svg+xml;Open-File-Cache
Abschnitt betitelt „Open-File-Cache“open_file_cache max=200000 inactive=20s;open_file_cache_valid 30s;open_file_cache_min_uses 2;open_file_cache_errors on;Speichert Dateideskriptoren und Metadaten für gecachte Objekte zwischen und eliminiert damit stat()- und open()-Syscalls bei häufig abgerufenen Dateien.
Client-Keepalive
Abschnitt betitelt „Client-Keepalive“keepalive_timeout 65;keepalive_requests 100000; # Was 1000 — caused connection recycling at 90K req/sBei 90K req/s mit keepalive_requests 1000 wurden Verbindungen alle 11 Sekunden recycelt, was TIME_WAIT-Sockets erzeugte. Die Erhöhung auf 100.000 eliminierte dies vollständig.
Zugriffs-Logging
Abschnitt betitelt „Zugriffs-Logging“log_format cdn '$remote_addr [$time_local] "$request" $status $body_bytes_sent $upstream_cache_status $request_time';access_log /var/log/nginx/access.log cdn buffer=256k flush=5s;Das cdn-Logformat enthält $upstream_cache_status (HIT/MISS) und $request_time für die Latenzanalyse. Gepuffertes Logging (256k/5s Flush) reduziert den I/O-Overhead unter hoher Last.
Upstream-Keepalive
Abschnitt betitelt „Upstream-Keepalive“upstream origin_backend { server 20.12.78.159:80; keepalive 256; # Persistent connections per worker to origin keepalive_timeout 60s; keepalive_requests 1000;}Mit 4 Workern × 256 Keepalive = 1.024 warme Verbindungen zum Origin. In Kombination mit proxy_http_version 1.1 und proxy_set_header Connection "" wird der TCP-Handshake-Overhead bei jedem Cache-Miss eliminiert.
Cache-Konfiguration
Abschnitt betitelt „Cache-Konfiguration“Cache-Pfad
Abschnitt betitelt „Cache-Pfad“proxy_cache_path /var/cache/nginx/cdn levels=1:2 keys_zone=cdn_cache:32m max_size=25g inactive=24h use_temp_path=off;| Parameter | Wert | Zweck |
|---|---|---|
keys_zone=cdn_cache:32m | 32 MB Shared Memory | Speichert ~256.000 Cache-Schlüssel und Metadaten |
max_size=25g | 25 GB Festplattenlimit | Nutzt den Großteil der 30 GB OS-Festplatte; LRU-Eviction bei Erreichen des Limits |
inactive=24h | 24-Stunden-Inaktivitäts-Timeout | Nicht innerhalb von 24h abgerufene Inhalte werden entfernt (nicht identisch mit TTL) |
use_temp_path=off | Direkt ins Cache-Verzeichnis schreiben | Vermeidet dateisystemübergreifende Dateiverschiebungen |
Cache-Verhalten
Abschnitt betitelt „Cache-Verhalten“proxy_cache cdn_cache;proxy_cache_valid 200 301 302 4h;proxy_cache_valid 404 1m;proxy_cache_key "$scheme$host$request_uri";proxy_cache_lock on;proxy_cache_lock_age 3s;proxy_cache_lock_timeout 3s;proxy_cache_background_update on;proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504;proxy_ignore_headers Set-Cookie Cache-Control Expires Vary;
proxy_hide_header X-Cache-Status;proxy_hide_header Vary;| Direktive | Wert | Zweck |
|---|---|---|
proxy_cache_valid 200 301 302 4h | 4-Stunden-TTL | Gecachte Inhalte sind 4 Stunden gültig (erhöht, um Durchsatzeinbrüche bei Refresh-Wellen zu reduzieren) |
proxy_cache_lock on | Thundering-Herd-Prävention | Nur 1 Anfrage geht pro ungecachter URL zum Origin; andere warten auf die Cache-Befüllung |
proxy_cache_lock_age 3s | Lock-Timeout | Falls die erste Anfrage nach 3s nicht abgeschlossen ist, wird eine weitere durchgelassen |
proxy_cache_background_update on | Latenzfreie Aktualisierung | Liefert sofort veraltete Inhalte aus, während im Hintergrund aktualisiert wird |
proxy_cache_use_stale | Ausfallsicherheit | Liefert veraltete Inhalte während Origin-Fehlern (500/502/503/504) oder während der Aktualisierung |
proxy_ignore_headers | Caching erzwingen | Ignoriert Origin Set-Cookie, Cache-Control, Expires, Vary — das CDN bestimmt TTL und Vary-Verhalten (Juice Shop sendet max-age=0 und dreifache Vary-Header, die effektives Caching verhinderten) |
proxy_hide_header X-Cache-Status | Origin-Header entfernen | Origin-NGINX fügt einen eigenen X-Cache-Status hinzu — wird entfernt, damit nur der Cache-Status des CDN sichtbar ist |
proxy_hide_header Vary | Cache-Fragmentierung verhindern | Origin sendet mehrere Vary: Accept-Encoding-Header. Das Entfernen verhindert die Cache-Schlüssel-Fragmentierung über Accept-Encoding-Permutationen. NGINXs gzip_vary on fügt automatisch den korrekten einzelnen Vary-Header hinzu |
Proxy-Timeouts
Abschnitt betitelt „Proxy-Timeouts“proxy_read_timeout 30s;proxy_connect_timeout 10s;proxy_send_timeout 15s;Gibt dem Origin unter Last mehr Antwortzeit und schlägt dennoch bei Verbindungsproblemen schnell fehl.
Server-Block
Abschnitt betitelt „Server-Block“server { listen 80 reuseport; # Kernel distributes connections across all 4 workers server_name _;}reuseport aktiviert SO_REUSEPORT — der Kernel verteilt eingehende Verbindungen direkt auf die Worker-Prozesse und eliminiert damit Accept-Mutex-Konflikte.
CDN-Vendor-Header
Abschnitt betitelt „CDN-Vendor-Header“Der Simulator injiziert Header von allen fünf großen CDN-Anbietern gleichzeitig. Dies ermöglicht es, F5 XC mit dem “Trusted Client IP Header” eines beliebigen Anbieters zu konfigurieren und realistische Header-Payloads zu sehen, unabhängig davon, welches CDN simuliert wird.
Industrie-Standard-Header (alle CDNs)
Abschnitt betitelt „Industrie-Standard-Header (alle CDNs)“| Header | Wert | Zweck |
|---|---|---|
X-Forwarded-For | Client-IP-Kette | Standard-Weiterleitungs-IP |
X-Forwarded-Proto | http oder https | Ursprüngliches Client-Protokoll |
X-Forwarded-Host | Ursprünglicher Hostname | Ursprünglicher Host-Header |
X-Forwarded-Port | Server-Port | Ursprünglicher Port |
X-Real-IP | Client-IP | Einzelne Client-IP (Nginx-Konvention) |
Via | 1.1 cdn-simulator | Proxy-Identifikation |
Forwarded | RFC 7239-Format | Standardisierter Weiterleitungs-Header |
CDN-Loop | cdn-simulator | Schleifenerkennung |
Akamai-Header
Abschnitt betitelt „Akamai-Header“| Header | Wert | Zweck |
|---|---|---|
True-Client-IP | Client-IP | Ursprüngliche Endbenutzer-IP-Adresse |
X-Akamai-Edgescape | Zusammengesetzter Geo-String | georegion, country_code, region_code, city, dma, pmsa, msa, areacode, county, fips, lat, long, timezone, zip, continent, throughput, bw, network, asnum, network_type |
X-Akamai-Device-Characteristics | Geräteeigenschaften | brand_name, model_name, is_mobile, is_tablet, is_wireless_device, device_os, device_os_version, resolution_width, resolution_height |
X-Akamai-Request-ID | Request-UUID | Eindeutiger Anfrage-Identifikator |
Cloudflare-Header
Abschnitt betitelt „Cloudflare-Header“| Header | Wert | Zweck |
|---|---|---|
CF-Connecting-IP | Client-IP | Echte Client-IP (immer vorhanden) |
CF-IPCountry | US | Zweistelliger Ländercode |
cf-ipcity | San Jose | Client-Stadt |
cf-ipcontinent | NA | Kontinent-Code |
cf-iplatitude / cf-iplongitude | Koordinaten | Geolokalisierung |
cf-region / cf-region-code | California / CA | Regionsinformationen |
cf-metro-code | 807 | US-Metropolcode |
cf-postal-code | 95113 | Postleitzahl |
cf-timezone | America/Los_Angeles | IANA-Zeitzone |
Cf-Ray | {request_id}-SJC | Eindeutige Ray-ID mit POP-IATA-Code |
CF-Visitor | {"scheme":"https"} | Besucher-Protokollinformationen |
cf-bot-score | 85 | Bot-Score (1=Bot, 99=Mensch) |
cf-verified-bot | false | Bekannter guter Bot-Indikator |
cf-ja3-hash | e7d705a3286e19ea42f587b344ee6865 | JA3-TLS-Fingerprint |
cf-ja4 | t13d1516h2_8daaf6152771_b0da82dd1658 | JA4-TLS-Fingerprint |
Amazon CloudFront-Header
Abschnitt betitelt „Amazon CloudFront-Header“| Header | Wert | Zweck |
|---|---|---|
CloudFront-Viewer-Address | IP:Port | Client-IP und Quellport |
CloudFront-Viewer-Country | US | Ländercode |
CloudFront-Viewer-Country-Name | United States | Vollständiger Ländername |
CloudFront-Viewer-Country-Region | CA | Regionscode |
CloudFront-Viewer-Country-Region-Name | California | Vollständiger Regionsname |
CloudFront-Viewer-City | San Jose | Client-Stadt |
CloudFront-Viewer-Postal-Code | 95113 | Postleitzahl |
CloudFront-Viewer-Latitude / Longitude | 37.33530 / -121.89300 | Geolokalisierung |
CloudFront-Viewer-Time-Zone | America/Los_Angeles | IANA-Zeitzone |
CloudFront-Viewer-Metro-Code | 807 | US-Metropolcode |
CloudFront-Viewer-ASN | 7018 | Autonome Systemnummer |
CloudFront-Viewer-Http-Version | 2.0 | Client-HTTP-Version |
CloudFront-Forwarded-Proto | https | Ursprüngliches Protokoll |
CloudFront-Viewer-TLS | TLSv1.3:TLS_AES_128_GCM_SHA256:sessionResumed | TLS-Details |
CloudFront-Viewer-JA3-Fingerprint | e7d705a3286e19ea42f587b344ee6865 | JA3-TLS-Fingerprint |
CloudFront-Is-Desktop-Viewer | true/false | Geräteerkennung |
CloudFront-Is-Mobile-Viewer | true/false | Geräteerkennung |
CloudFront-Is-Tablet-Viewer | true/false | Geräteerkennung |
CloudFront-Is-SmartTV-Viewer | false | Geräteerkennung |
X-Amz-Cf-Id | Kodierte ID | CloudFront-Anfrage-Identifikator |
Fastly-Header
Abschnitt betitelt „Fastly-Header“| Header | Wert | Zweck |
|---|---|---|
Fastly-Client-IP | Client-IP | Echte Client-IP |
Fastly-SSL | 1 | Verbindung war über TLS |
Fastly-Client | 1 | Client-seitige Anfrage (nicht Shield) |
Fastly-FF | cache-sjc3120-SJC | Cache-Node-Identifikation |
X-Geo-Country-Code | US | Land (VCL-Variablen-Konvention) |
X-Geo-Country-Code3 | USA | Dreistelliger Ländercode |
X-Geo-Country-Name | United States | Vollständiger Ländername |
X-Geo-City | San Jose | Client-Stadt |
X-Geo-Region | CA | Regionscode |
X-Geo-Continent-Code | NA | Kontinent |
X-Geo-Latitude / X-Geo-Longitude | 37.3353 / -121.8938 | Geolokalisierung |
X-Geo-Postal-Code | 95113 | Postleitzahl |
X-Geo-Metro-Code | 807 | US-Metropolcode |
X-Geo-ASN | 7018 | Autonome Systemnummer |
X-Geo-Conn-Speed | broadband | Verbindungsgeschwindigkeitsklasse |
X-Geo-Conn-Type | wired | Verbindungstyp |
Azure Front Door-Header
Abschnitt betitelt „Azure Front Door-Header“| Header | Wert | Zweck |
|---|---|---|
X-Azure-ClientIP | Client-IP | Client-IP-Adresse |
X-Azure-SocketIP | Client-IP | TCP-Socket-Quell-IP |
X-Azure-Ref | Kodierter Referenzstring | Eindeutige Anfrage-Referenz zur Fehlerbehebung |
X-Azure-FDID | a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1 | Front-Door-Ressourcen-Identifikator |
X-Azure-RequestChain | hops=1 | Schleifen-Erkennung Hop-Zähler |
Antwort-Header (zu Client-Antworten hinzugefügt)
Abschnitt betitelt „Antwort-Header (zu Client-Antworten hinzugefügt)“| Header | Werte | Zweck |
|---|---|---|
X-Cache-Status | HIT, MISS, EXPIRED, STALE, UPDATING | Cache-Verhalten für diese Anfrage |
X-CDN-Edge | cdn-simulator | Identifiziert diesen Edge-Knoten |
X-CDN-POP | SJC | Simulierter Point of Presence IATA-Code |
X-Served-By | cache-sjc3120-SJC | Simulierter Cache-Knoten im Fastly-Format |
X-Request-ID | UUID (pro Anfrage) | Eindeutiger Anfrage-Identifikator |
Geräteerkennung
Abschnitt betitelt „Geräteerkennung“Der Simulator erkennt den Gerätetyp aus dem User-Agent-Header mithilfe von NGINX-map-Direktiven:
- Mobil: Erkennt iPhone, Android (kein Tablet), iPod, BlackBerry, Opera Mini, IEMobile
- Tablet: Erkennt iPad, Android-Tablet, Kindle, PlayBook
- Desktop: Standard, wenn weder Mobil noch Tablet zutrifft
Der Gerätetyp wird widergespiegelt in:
CloudFront-Is-Desktop-Viewer/CloudFront-Is-Mobile-Viewer/CloudFront-Is-Tablet-ViewerX-Akamai-Device-Characteristics(is_mobile,is_tablet,is_wireless_device-Felder)
Betrieb
Abschnitt betitelt „Betrieb“Origin-Server ändern
Abschnitt betitelt „Origin-Server ändern“ssh azureuser@<PUBLIC_IP>
# Update upstream serversudo sed -i 's|server .*;|server NEW_HOST:80;|' /etc/nginx/conf.d/cdn-edge.conf
# Clear cache and reloadsudo rm -rf /var/cache/nginx/cdn/*sudo nginx -t && sudo systemctl reload nginxAlternativ origin_host in terraform.tfvars aktualisieren und terraform apply ausführen, um neu zu provisionieren.
Cache leeren
Abschnitt betitelt „Cache leeren“ssh azureuser@<PUBLIC_IP>sudo rm -rf /var/cache/nginx/cdn/*sudo systemctl reload nginxCache-Statistiken prüfen
Abschnitt betitelt „Cache-Statistiken prüfen“# Object count and disk usagesudo find /var/cache/nginx/cdn -type f | wc -lsudo du -sh /var/cache/nginx/cdn
# Recent access log with cache statustail -20 /var/log/nginx/access.logÜberwachung unter Last
Abschnitt betitelt „Überwachung unter Last“# Real-time connections and socket statesss -s
# NGINX worker CPU usagetop -bn1 | grep nginx
# Upstream keepalive connectionsss -tn state established dst <ORIGIN_IP> | wc -l
# TIME_WAIT socket countss -tn state time-wait | wc -lLeistungsbenchmark-Ergebnisse
Abschnitt betitelt „Leistungsbenchmark-Ergebnisse“Verifiziert in einem 48-stündigen kontinuierlichen Lasttest:
| Metrik | Wert |
|---|---|
| Spitzendurchsatz (gecacht) | 172.540 req/s |
| Dauerdurchsatz (gecacht) | 85.000-103.000 req/s |
| Spitzenverbindungen | 15.000 gleichzeitig |
| Cache-Trefferquote | 100% (nach Aufwärmung) |
| Speicher unter Last | 1,2 GB stabil (8% von 16 GB) |
| CPU bei Spitzenlast | 100% (4 Kerne - CPU ist die Obergrenze) |
| Fehler während 48h-Test | 0 |
| Speicherlecks | Keine erkannt |
| Verbindungslecks | Keine erkannt |