server { listen 80; listen [::]:80; server_name {{ cdn_domain }}; # Redirect HTTP to HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name {{ cdn_domain }}; # SSL Configuration (wird von Certbot automatisch gefüllt) ssl_certificate /etc/letsencrypt/live/{{ cdn_domain }}/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/{{ cdn_domain }}/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # CDN Headers add_header X-CDN-Node "{{ city }}, Deutschland"; add_header X-Cache-Status $upstream_cache_status always; add_header X-Served-By "nginx-{{ inventory_hostname }}"; # Security Headers include /etc/nginx/includes/security-headers.conf; # Logging access_log /var/log/nginx/cdn/{{ cdn_domain }}.access.log cdn_format; error_log /var/log/nginx/cdn/{{ cdn_domain }}.error.log warn; # Rate Limiting include /etc/nginx/includes/rate-limiting.conf; # Gzip Compression include /etc/nginx/includes/gzip-settings.conf; # Nginx Status für Monitoring location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; allow 10.0.0.0/8; deny all; } ## # Static Files (CSS, JS, Fonts) - Lange Cache-Zeit ## location ~* \.(css|js|woff|woff2|ttf|eot|ico)$ { proxy_pass https://origin_servers; proxy_ssl_verify off; # Cache Settings proxy_cache static_cache; proxy_cache_valid 200 302 {{ cache_settings.static_files_ttl }}; proxy_cache_valid 404 1m; proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; proxy_cache_lock on; proxy_cache_revalidate on; # Headers expires {{ cache_settings.static_files_ttl }}; add_header Cache-Control "public, immutable"; add_header Vary "Accept-Encoding"; # Rate Limiting limit_req zone=static_files burst=50 nodelay; # Proxy Headers proxy_set_header Host {{ origin_domain }}; 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; } ## # Images - Mittlere Cache-Zeit ## location ~* \.(jpg|jpeg|png|gif|webp|svg|avif|bmp|tiff)$ { proxy_pass https://origin_servers; proxy_ssl_verify off; # Cache Settings proxy_cache images_cache; proxy_cache_valid 200 302 {{ cache_settings.images_ttl }}; proxy_cache_valid 404 5m; proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; # Headers expires {{ cache_settings.images_ttl }}; add_header Cache-Control "public"; add_header Vary "Accept"; # Rate Limiting limit_req zone=images burst=30 nodelay; # Proxy Headers proxy_set_header Host {{ origin_domain }}; 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; } ## # API Endpoints - Kein Caching ## location /api/ { proxy_pass https://origin_servers; proxy_ssl_verify off; # Kein Caching proxy_no_cache 1; proxy_cache_bypass 1; add_header Cache-Control "no-cache, no-store, must-revalidate"; add_header Pragma "no-cache"; add_header Expires "0"; # Rate Limiting limit_req zone=api burst=10 nodelay; # CORS Headers add_header Access-Control-Allow-Origin "https://{{ origin_domain }}"; add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"; add_header Access-Control-Allow-Headers "Authorization, Content-Type, X-Requested-With"; add_header Access-Control-Allow-Credentials true; # Proxy Headers proxy_set_header Host {{ origin_domain }}; 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; # Timeouts proxy_connect_timeout {{ proxy_settings.connect_timeout }}; proxy_send_timeout {{ proxy_settings.send_timeout }}; proxy_read_timeout {{ proxy_settings.read_timeout }}; } ## # Cache Purge (nur interne IPs) ## location ~ /purge(/.*) { allow 127.0.0.1; allow 10.0.0.0/8; allow 192.168.0.0/16; deny all; proxy_cache_purge static_cache $scheme$proxy_host$1; } ## # Health Check ## location /health { access_log off; return 200 "OK - CDN Node {{ city }}\nRegion: {{ region }}\nTier: {{ tier }}\nTimestamp: $time_iso8601\n"; add_header Content-Type text/plain; } ## # Default Location - HTML Caching ## location / { proxy_pass https://origin_servers; proxy_ssl_verify off; # Cache Settings für HTML proxy_cache html_cache; proxy_cache_valid 200 {{ cache_settings.html_ttl }}; proxy_cache_valid 404 1m; proxy_cache_bypass $arg_nocache $cookie_sessionid $http_authorization; # Headers add_header Cache-Control "public, max-age=300"; # Proxy Headers proxy_set_header Host {{ origin_domain }}; 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; proxy_set_header X-CDN-Node "{{ city }}"; # Timeouts proxy_connect_timeout {{ proxy_settings.connect_timeout }}; proxy_send_timeout {{ proxy_settings.send_timeout }}; proxy_read_timeout {{ proxy_settings.read_timeout }}; # Buffering proxy_buffering {{ proxy_settings.buffering }}; proxy_buffer_size {{ proxy_settings.buffer_size }}; proxy_buffers {{ proxy_settings.buffers }}; } }