user nginx; pid /run/nginx.pid; worker_processes auto; worker_cpu_affinity auto; worker_rlimit_nofile 65535; events { multi_accept on; use epoll; worker_connections 65535; } http { # =================== LOAD LUA ========================= # lua_package_path "/usr/nginx_lua/lib/lua/?.lua;;"; lua_package_cpath "/usr/nginx_lua/lib/lua/5.1/?.so;;"; # =================== END LUA ========================== # # =================== LOAD L7 ========================== # include modsec/l7.conf; # =================== END L7 =========================== # # ===================== LOGS =========================== # map $upstream_cache_status $log_cache_status { "" "STATIC"; default $upstream_cache_status; } more_set_headers "X-Cache-Status: $log_cache_status"; log_format main 'DATE: $time_local FROM: $remote_addr | STATUS: $status | TO: $request | CACHE: $log_cache_status | A: $http_user_agent'; # =================== END LOGS ========================= # # ==================== GENERAL ========================= # client_header_buffer_size 4k; large_client_header_buffers 4 16k; client_body_buffer_size 16k; client_max_body_size 2M; client_body_timeout 30s; client_header_timeout 30s; send_timeout 30s; reset_timedout_connection on; keepalive_timeout 65s; keepalive_requests 2000; max_headers 100; port_in_redirect off; sendfile on; sendfile_max_chunk 1m; tcp_nodelay on; tcp_nopush on; server_tokens off; server_name_in_redirect off; server_names_hash_bucket_size 128; server_names_hash_max_size 32768; types_hash_max_size 4096; # File metadata cache — biggest single win for static-heavy shared hosting. open_file_cache max=200000 inactive=30s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on; # Symlink backstop for tenant static files. Enforced by nginx at the SAME # open() that serves the file, so it complements the tenant_isolation patch # (docs/tenant-isolation.md) on the axes that patch cannot cover from its # separate openat2 probe: # * the probe->open TOCTOU window — a tenant that swaps a benign file for an # escaping symlink after the probe is still caught here, at serve time; # * the open paths the patch does not intercept — gzip_static, autoindex, # dav, mp4/flv — which all funnel through this same disable_symlinks check. # `if_not_owner` (not `on`) is deliberate: it permits a tenant's OWN in-tree # symlinks (e.g. Laravel's public/storage) while refusing a symlink whose # target has a different owner (docroot/x -> /etc/passwd, root-owned => 403), # which matches the tenant_isolation semantics. `from=$document_root` skips # symlink checks on the docroot prefix itself (owned by the platform). disable_symlinks if_not_owner from=$document_root; # ===================== TLS ============================ # ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:200m; ssl_session_timeout 1d; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; # Cloudflare dynamic TLS record sizing (build/patches/nginx-X-dynamic-tls-records.patch). # Small records up front cut TTFB by ~1 RTT, then ramp up to amortise TLS # overhead once the connection is past head-of-line blocking. ssl_dyn_rec_enable on; ssl_dyn_rec_size_lo 1369; ssl_dyn_rec_size_hi 4229; ssl_dyn_rec_threshold 40; ssl_dyn_rec_timeout 1000; # ===================== END TLS ======================== # resolver 1.1.1.1 1.0.0.1 valid=300s; resolver_timeout 5s; default_type application/octet-stream; include /nginx/mime.types; map $http_upgrade $connection_upgrade { default upgrade; '' close; } # ==================== COMPRESSION ===================== # gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 4; gzip_min_length 256; gzip_types text/plain text/css text/xml application/json application/javascript application/xml application/xml+rss application/atom+xml image/svg+xml font/ttf font/otf font/woff font/woff2; brotli on; brotli_comp_level 4; brotli_min_length 256; brotli_types text/plain text/css text/xml application/json application/javascript application/xml application/xml+rss application/atom+xml image/svg+xml font/ttf font/otf font/woff font/woff2; zstd on; zstd_comp_level 4; zstd_min_length 256; zstd_types text/plain text/css text/xml application/json application/javascript application/xml application/xml+rss application/atom+xml image/svg+xml font/ttf font/otf font/woff font/woff2; # =================== END COMPRESSION ================== # # =================== END GENERAL ====================== # # ================ LOAD VHOST +CONFIGS ================= # include live/*; include conf.d/*; include modsec/naxi.core; # =================== END CONFIGS ====================== # }