diff --git a/internal/ingress/controller/template/crossplane/testdata/README.md b/internal/ingress/controller/template/crossplane/testdata/README.md deleted file mode 100644 index 4f44e3c98..000000000 --- a/internal/ingress/controller/template/crossplane/testdata/README.md +++ /dev/null @@ -1,8 +0,0 @@ -This directory contains the following files: - -* nginx.tmpl - Should be used to track migrated directives. We will test later to see -if the ending result of it is the same as the one parsed by go-crossplane -* various nginx.conf - Will be used to see if the template parser reacts as -expected, creating files that matches and can be parsed by go-crossplane - -TODO: move files to embed.FS \ No newline at end of file diff --git a/internal/ingress/controller/template/crossplane/testdata/nginx-new-orig.tmpl b/internal/ingress/controller/template/crossplane/testdata/nginx-new-orig.tmpl deleted file mode 100644 index b7fa80382..000000000 --- a/internal/ingress/controller/template/crossplane/testdata/nginx-new-orig.tmpl +++ /dev/null @@ -1,1450 +0,0 @@ -{{ $all := . }} -{{ $servers := .Servers }} -{{ $cfg := .Cfg }} -{{ $IsIPV6Enabled := .IsIPV6Enabled }} -{{ $healthzURI := .HealthzURI }} -{{ $backends := .Backends }} -{{ $proxyHeaders := .ProxySetHeaders }} -{{ $addHeaders := .AddHeaders }} - -# Configuration checksum: {{ $all.Cfg.Checksum }} - -# setup custom paths that do not require root access -pid {{ .PID }}; # OK - -{{ if $cfg.UseGeoIP2 }} #OK -load_module /etc/nginx/modules/ngx_http_geoip2_module.so; -{{ end }} - -{{ if $cfg.EnableBrotli }} #OK -load_module /etc/nginx/modules/ngx_http_brotli_filter_module.so; -load_module /etc/nginx/modules/ngx_http_brotli_static_module.so; -{{ end }} - -{{ if (shouldLoadAuthDigestModule $servers) }} -load_module /etc/nginx/modules/ngx_http_auth_digest_module.so; -{{ end }} - -{{ if (shouldLoadModSecurityModule $cfg $servers) }} -load_module /etc/nginx/modules/ngx_http_modsecurity_module.so; -{{ end }} - -{{ if (shouldLoadOpentelemetryModule $cfg $servers) }} -load_module /etc/nginx/modules/otel_ngx_module.so; -{{ end }} - -daemon off; # OK - -worker_processes {{ $cfg.WorkerProcesses }}; # OK -{{ if gt (len $cfg.WorkerCPUAffinity) 0 }} # OK -worker_cpu_affinity {{ $cfg.WorkerCPUAffinity }}; -{{ end }} - -worker_rlimit_nofile {{ $cfg.MaxWorkerOpenFiles }}; # OK - -{{/* http://nginx.org/en/docs/ngx_core_module.html#worker_shutdown_timeout */}} -{{/* avoid waiting too long during a reload */}} -worker_shutdown_timeout {{ $cfg.WorkerShutdownTimeout }} ; # OK - -# REMOVED -# {{ if not (empty $cfg.MainSnippet) }} -# {{ $cfg.MainSnippet }} -# {{ end }} - -events { - multi_accept {{ if $cfg.EnableMultiAccept }}on{{ else }}off{{ end }}; # OK - worker_connections {{ $cfg.MaxWorkerConnections }}; # OK - use epoll; # OK - {{ range $index , $v := $cfg.DebugConnections }} # OK - debug_connection {{ $v }}; # OK - {{ end }} -} - -http { - {{ if (shouldLoadOpentelemetryModule $cfg $servers) }} - opentelemetry_config {{ $cfg.OpentelemetryConfig }}; - {{ end }} - - lua_package_path "/etc/nginx/lua/?.lua;;"; # OK - - {{ buildLuaSharedDictionaries $cfg $servers }} # OK - - lua_shared_dict luaconfig 5m; # OK - - init_by_lua_file /etc/nginx/lua/ngx_conf_init.lua; # OK - - init_worker_by_lua_file /etc/nginx/lua/ngx_conf_init_worker.lua; # OK - - {{/* Enable the real_ip module only if we use either X-Forwarded headers or Proxy Protocol. */}} - {{/* we use the value of the real IP for the geo_ip module */}} - {{ if or (or $cfg.UseForwardedHeaders $cfg.UseProxyProtocol) $cfg.EnableRealIP }} - {{ if $cfg.UseProxyProtocol }} - real_ip_header proxy_protocol; - {{ else }} - real_ip_header {{ $cfg.ForwardedForHeader }}; - {{ end }} - - real_ip_recursive on; - {{ range $trusted_ip := $cfg.ProxyRealIPCIDR }} - set_real_ip_from {{ $trusted_ip }}; - {{ end }} - {{ end }} - - {{ if $all.Cfg.EnableModsecurity }} - modsecurity on; - - {{ if (not (empty $all.Cfg.ModsecuritySnippet)) }} - modsecurity_rules ' - {{ $all.Cfg.ModsecuritySnippet }} - '; - {{ else }} - modsecurity_rules_file /etc/nginx/modsecurity/modsecurity.conf; - {{ end }} - - {{ if $all.Cfg.EnableOWASPCoreRules }} - modsecurity_rules_file /etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf; - {{ end }} - - {{ end }} - - {{ if $cfg.UseGeoIP2 }} - # https://github.com/leev/ngx_http_geoip2_module#example-usage - - {{ range $index, $file := $all.MaxmindEditionFiles }} - {{ if eq $file "GeoLite2-Country.mmdb" }} - geoip2 /etc/ingress-controller/geoip/GeoLite2-Country.mmdb { - {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} - auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; - {{ end }} - $geoip2_country_code source=$remote_addr country iso_code; - $geoip2_country_name source=$remote_addr country names en; - $geoip2_country_geoname_id source=$remote_addr country geoname_id; - $geoip2_continent_code source=$remote_addr continent code; - $geoip2_continent_name source=$remote_addr continent names en; - $geoip2_continent_geoname_id source=$remote_addr continent geoname_id; - } - {{ end }} - - {{ if eq $file "GeoIP2-Country.mmdb" }} - geoip2 /etc/ingress-controller/geoip/GeoIP2-Country.mmdb { - {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} - auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; - {{ end }} - $geoip2_country_code source=$remote_addr country iso_code; - $geoip2_country_name source=$remote_addr country names en; - $geoip2_country_geoname_id source=$remote_addr country geoname_id; - $geoip2_continent_code source=$remote_addr continent code; - $geoip2_continent_name source=$remote_addr continent names en; - $geoip2_continent_geoname_id source=$remote_addr continent geoname_id; - } - {{ end }} - - {{ if eq $file "GeoLite2-City.mmdb" }} - geoip2 /etc/ingress-controller/geoip/GeoLite2-City.mmdb { - {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} - auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; - {{ end }} - $geoip2_city_country_code source=$remote_addr country iso_code; - $geoip2_city_country_name source=$remote_addr country names en; - $geoip2_city_country_geoname_id source=$remote_addr country geoname_id; - $geoip2_city source=$remote_addr city names en; - $geoip2_city_geoname_id source=$remote_addr city geoname_id; - $geoip2_postal_code source=$remote_addr postal code; - $geoip2_dma_code source=$remote_addr location metro_code; - $geoip2_latitude source=$remote_addr location latitude; - $geoip2_longitude source=$remote_addr location longitude; - $geoip2_time_zone source=$remote_addr location time_zone; - $geoip2_region_code source=$remote_addr subdivisions 0 iso_code; - $geoip2_region_name source=$remote_addr subdivisions 0 names en; - $geoip2_region_geoname_id source=$remote_addr subdivisions 0 geoname_id; - $geoip2_subregion_code source=$remote_addr subdivisions 1 iso_code; - $geoip2_subregion_name source=$remote_addr subdivisions 1 names en; - $geoip2_subregion_geoname_id source=$remote_addr subdivisions 1 geoname_id; - $geoip2_city_continent_code source=$remote_addr continent code; - $geoip2_city_continent_name source=$remote_addr continent names en; - } - {{ end }} - - {{ if eq $file "GeoIP2-City.mmdb" }} - geoip2 /etc/ingress-controller/geoip/GeoIP2-City.mmdb { - {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} - auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; - {{ end }} - $geoip2_city_country_code source=$remote_addr country iso_code; - $geoip2_city_country_name source=$remote_addr country names en; - $geoip2_city_country_geoname_id source=$remote_addr country geoname_id; - $geoip2_city source=$remote_addr city names en; - $geoip2_city_geoname_id source=$remote_addr city geoname_id; - $geoip2_postal_code source=$remote_addr postal code; - $geoip2_dma_code source=$remote_addr location metro_code; - $geoip2_latitude source=$remote_addr location latitude; - $geoip2_longitude source=$remote_addr location longitude; - $geoip2_time_zone source=$remote_addr location time_zone; - $geoip2_region_code source=$remote_addr subdivisions 0 iso_code; - $geoip2_region_name source=$remote_addr subdivisions 0 names en; - $geoip2_region_geoname_id source=$remote_addr subdivisions 0 geoname_id; - $geoip2_subregion_code source=$remote_addr subdivisions 1 iso_code; - $geoip2_subregion_name source=$remote_addr subdivisions 1 names en; - $geoip2_subregion_geoname_id source=$remote_addr subdivisions 1 geoname_id; - $geoip2_city_continent_code source=$remote_addr continent code; - $geoip2_city_continent_name source=$remote_addr continent names en; - } - {{ end }} - - {{ if eq $file "GeoLite2-ASN.mmdb" }} - geoip2 /etc/ingress-controller/geoip/GeoLite2-ASN.mmdb { - {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} - auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; - {{ end }} - $geoip2_asn source=$remote_addr autonomous_system_number; - $geoip2_org source=$remote_addr autonomous_system_organization; - } - {{ end }} - - {{ if eq $file "GeoIP2-ASN.mmdb" }} - geoip2 /etc/ingress-controller/geoip/GeoIP2-ASN.mmdb { - {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} - auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; - {{ end }} - $geoip2_asn source=$remote_addr autonomous_system_number; - $geoip2_org source=$remote_addr autonomous_system_organization; - } - {{ end }} - - {{ if eq $file "GeoIP2-ISP.mmdb" }} - geoip2 /etc/ingress-controller/geoip/GeoIP2-ISP.mmdb { - {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} - auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; - {{ end }} - $geoip2_isp source=$remote_addr isp; - $geoip2_isp_org source=$remote_addr organization; - $geoip2_asn source=$remote_addr default=0 autonomous_system_number; - } - {{ end }} - - {{ if eq $file "GeoIP2-Connection-Type.mmdb" }} - geoip2 /etc/ingress-controller/geoip/GeoIP2-Connection-Type.mmdb { - $geoip2_connection_type connection_type; - } - {{ end }} - - {{ if eq $file "GeoIP2-Anonymous-IP.mmdb" }} - geoip2 /etc/ingress-controller/geoip/GeoIP2-Anonymous-IP.mmdb { - {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} - auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; - {{ end }} - $geoip2_is_anon source=$remote_addr is_anonymous; - $geoip2_is_anonymous source=$remote_addr default=0 is_anonymous; - $geoip2_is_anonymous_vpn source=$remote_addr default=0 is_anonymous_vpn; - $geoip2_is_hosting_provider source=$remote_addr default=0 is_hosting_provider; - $geoip2_is_public_proxy source=$remote_addr default=0 is_public_proxy; - $geoip2_is_tor_exit_node source=$remote_addr default=0 is_tor_exit_node; - } - {{ end }} - - {{ end }} - - {{ end }} - - aio threads; - - {{ if $cfg.EnableAioWrite }} - aio_write on; - {{ end }} - - tcp_nopush on; - tcp_nodelay on; - - log_subrequest on; - - reset_timedout_connection on; - - keepalive_timeout {{ $cfg.KeepAlive }}s; - keepalive_requests {{ $cfg.KeepAliveRequests }}; - - client_body_temp_path /tmp/nginx/client-body; - fastcgi_temp_path /tmp/nginx/fastcgi-temp; - proxy_temp_path /tmp/nginx/proxy-temp; - - client_header_buffer_size {{ $cfg.ClientHeaderBufferSize }}; - client_header_timeout {{ $cfg.ClientHeaderTimeout }}s; - large_client_header_buffers {{ $cfg.LargeClientHeaderBuffers }}; - client_body_buffer_size {{ $cfg.ClientBodyBufferSize }}; - client_body_timeout {{ $cfg.ClientBodyTimeout }}s; - - {{ if gt $cfg.GRPCBufferSizeKb 0 }} - grpc_buffer_size {{ $cfg.GRPCBufferSizeKb }}k; - {{ end }} - - {{ if and (ne $cfg.HTTP2MaxHeaderSize "") (ne $cfg.HTTP2MaxFieldSize "") }} - http2_max_field_size {{ $cfg.HTTP2MaxFieldSize }}; - http2_max_header_size {{ $cfg.HTTP2MaxHeaderSize }}; - {{ end }} - - {{ if (gt $cfg.HTTP2MaxRequests 0) }} - http2_max_requests {{ $cfg.HTTP2MaxRequests }}; - {{ end }} - - http2_max_concurrent_streams {{ $cfg.HTTP2MaxConcurrentStreams }}; - - types_hash_max_size 2048; - server_names_hash_max_size {{ $cfg.ServerNameHashMaxSize }}; - server_names_hash_bucket_size {{ $cfg.ServerNameHashBucketSize }}; - map_hash_bucket_size {{ $cfg.MapHashBucketSize }}; - - proxy_headers_hash_max_size {{ $cfg.ProxyHeadersHashMaxSize }}; - proxy_headers_hash_bucket_size {{ $cfg.ProxyHeadersHashBucketSize }}; - - variables_hash_bucket_size {{ $cfg.VariablesHashBucketSize }}; - variables_hash_max_size {{ $cfg.VariablesHashMaxSize }}; - - underscores_in_headers {{ if $cfg.EnableUnderscoresInHeaders }}on{{ else }}off{{ end }}; - ignore_invalid_headers {{ if $cfg.IgnoreInvalidHeaders }}on{{ else }}off{{ end }}; - - limit_req_status {{ $cfg.LimitReqStatusCode }}; - limit_conn_status {{ $cfg.LimitConnStatusCode }}; - - {{ buildOpentelemetry $cfg $servers }} - - include /etc/nginx/mime.types; - default_type {{ $cfg.DefaultType }}; - - {{ if $cfg.EnableBrotli }} - brotli on; - brotli_comp_level {{ $cfg.BrotliLevel }}; - brotli_min_length {{ $cfg.BrotliMinLength }}; - brotli_types {{ $cfg.BrotliTypes }}; - {{ end }} - - {{ if $cfg.UseGzip }} - gzip on; - gzip_comp_level {{ $cfg.GzipLevel }}; - {{- if $cfg.GzipDisable }} - gzip_disable "{{ $cfg.GzipDisable }}"; - {{- end }} - gzip_http_version 1.1; - gzip_min_length {{ $cfg.GzipMinLength}}; - gzip_types {{ $cfg.GzipTypes }}; - gzip_proxied any; - gzip_vary on; - {{ end }} - - # Custom headers for response - {{ range $k, $v := $addHeaders }} - more_set_headers {{ printf "%s: %s" $k $v | quote }}; - {{ end }} - - server_tokens {{ if $cfg.ShowServerTokens }}on{{ else }}off{{ end }}; - {{ if not $cfg.ShowServerTokens }} - more_clear_headers Server; - {{ end }} - - # disable warnings - uninitialized_variable_warn off; - - # Additional available variables: - # $namespace - # $ingress_name - # $service_name - # $service_port - log_format upstreaminfo {{ if $cfg.LogFormatEscapeNone }}escape=none {{ else if $cfg.LogFormatEscapeJSON }}escape=json {{ end }}'{{ $cfg.LogFormatUpstream }}'; - - {{/* map urls that should not appear in access.log */}} - {{/* http://nginx.org/en/docs/http/ngx_http_log_module.html#access_log */}} - map $request_uri $loggable { - {{ range $reqUri := $cfg.SkipAccessLogURLs }} - {{ $reqUri }} 0;{{ end }} - default 1; - } - - {{ if or $cfg.DisableAccessLog $cfg.DisableHTTPAccessLog }} - access_log off; - {{ else }} - {{ if $cfg.EnableSyslog }} - access_log syslog:server={{ $cfg.SyslogHost }}:{{ $cfg.SyslogPort }} upstreaminfo if=$loggable; - {{ else }} - access_log {{ or $cfg.HTTPAccessLogPath $cfg.AccessLogPath }} upstreaminfo {{ $cfg.AccessLogParams }} if=$loggable; - {{ end }} - {{ end }} - - {{ if $cfg.EnableSyslog }} - error_log syslog:server={{ $cfg.SyslogHost }}:{{ $cfg.SyslogPort }} {{ $cfg.ErrorLogLevel }}; - {{ else }} - error_log {{ $cfg.ErrorLogPath }} {{ $cfg.ErrorLogLevel }}; - {{ end }} - - {{ buildResolvers $cfg.Resolver $cfg.DisableIpv6DNS }} - - # See https://www.nginx.com/blog/websocket-nginx - map $http_upgrade $connection_upgrade { - default upgrade; - {{ if (gt $cfg.UpstreamKeepaliveConnections 0) }} - # See http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive - '' ''; - {{ else }} - '' close; - {{ end }} - } - - # Reverse proxies can detect if a client provides a X-Request-ID header, and pass it on to the backend server. - # If no such header is provided, it can provide a random value. - map $http_x_request_id $req_id { - default $http_x_request_id; - {{ if $cfg.GenerateRequestID }} - "" $request_id; - {{ end }} - } - - {{ if and $cfg.UseForwardedHeaders $cfg.ComputeFullForwardedFor }} - # We can't use $proxy_add_x_forwarded_for because the realip module - # replaces the remote_addr too soon - map $http_x_forwarded_for $full_x_forwarded_for { - {{ if $all.Cfg.UseProxyProtocol }} - default "$http_x_forwarded_for, $proxy_protocol_addr"; - '' "$proxy_protocol_addr"; - {{ else }} - default "$http_x_forwarded_for, $realip_remote_addr"; - '' "$realip_remote_addr"; - {{ end}} - } - - {{ end }} - - # Create a variable that contains the literal $ character. - # This works because the geo module will not resolve variables. - geo $literal_dollar { - default "$"; - } - - server_name_in_redirect off; - port_in_redirect off; - - ssl_protocols {{ $cfg.SSLProtocols }}; - - ssl_early_data {{ if $cfg.SSLEarlyData }}on{{ else }}off{{ end }}; - - # turn on session caching to drastically improve performance - {{ if $cfg.SSLSessionCache }} - ssl_session_cache shared:SSL:{{ $cfg.SSLSessionCacheSize }}; - ssl_session_timeout {{ $cfg.SSLSessionTimeout }}; - {{ end }} - - # allow configuring ssl session tickets - ssl_session_tickets {{ if $cfg.SSLSessionTickets }}on{{ else }}off{{ end }}; - - {{ if not (empty $cfg.SSLSessionTicketKey ) }} - ssl_session_ticket_key /etc/ingress-controller/tickets.key; - {{ end }} - - # slightly reduce the time-to-first-byte - ssl_buffer_size {{ $cfg.SSLBufferSize }}; - - {{ if not (empty $cfg.SSLCiphers) }} - # allow configuring custom ssl ciphers - ssl_ciphers '{{ $cfg.SSLCiphers }}'; - ssl_prefer_server_ciphers on; - {{ end }} - - {{ if not (empty $cfg.SSLDHParam) }} - # allow custom DH file http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_dhparam - ssl_dhparam {{ $cfg.SSLDHParam }}; - {{ end }} - - ssl_ecdh_curve {{ $cfg.SSLECDHCurve }}; - - # PEM sha: {{ $cfg.DefaultSSLCertificate.PemSHA }} - ssl_certificate {{ $cfg.DefaultSSLCertificate.PemFileName }}; - ssl_certificate_key {{ $cfg.DefaultSSLCertificate.PemFileName }}; - - {{ if and $cfg.CustomHTTPErrors (not $cfg.DisableProxyInterceptErrors) }} - proxy_intercept_errors on; - {{ end }} - - {{ range $errCode := $cfg.CustomHTTPErrors }} - error_page {{ $errCode }} = @custom_upstream-default-backend_{{ $errCode }};{{ end }} - - proxy_ssl_session_reuse on; - - {{ if $cfg.AllowBackendServerHeader }} - proxy_pass_header Server; - {{ end }} - - {{ range $header := $cfg.HideHeaders }}proxy_hide_header {{ $header }}; - {{ end }} - - {{ if not (empty $cfg.HTTPSnippet) }} - # Custom code snippet configured in the configuration configmap - {{ $cfg.HTTPSnippet }} - {{ end }} - - upstream upstream_balancer { - ### Attention!!! - # - # We no longer create "upstream" section for every backend. - # Backends are handled dynamically using Lua. If you would like to debug - # and see what backends ingress-nginx has in its memory you can - # install our kubectl plugin https://kubernetes.github.io/ingress-nginx/kubectl-plugin. - # Once you have the plugin you can use "kubectl ingress-nginx backends" command to - # inspect current backends. - # - ### - - server 0.0.0.1; # placeholder - - balancer_by_lua_file /etc/nginx/lua/nginx/ngx_conf_balancer.lua; - - {{ if (gt $cfg.UpstreamKeepaliveConnections 0) }} - keepalive {{ $cfg.UpstreamKeepaliveConnections }}; - keepalive_time {{ $cfg.UpstreamKeepaliveTime }}; - keepalive_timeout {{ $cfg.UpstreamKeepaliveTimeout }}s; - keepalive_requests {{ $cfg.UpstreamKeepaliveRequests }}; - {{ end }} - } - - {{ range $rl := (filterRateLimits $servers ) }} - # Ratelimit {{ $rl.Name }} - geo $remote_addr $allowlist_{{ $rl.ID }} { - default 0; - {{ range $ip := $rl.Allowlist }} - {{ $ip }} 1;{{ end }} - } - - # Ratelimit {{ $rl.Name }} - map $allowlist_{{ $rl.ID }} $limit_{{ $rl.ID }} { - 0 {{ $cfg.LimitConnZoneVariable }}; - 1 ""; - } - {{ end }} - - {{/* build all the required rate limit zones. Each annotation requires a dedicated zone */}} - {{/* 1MB -> 16 thousand 64-byte states or about 8 thousand 128-byte states */}} - {{ range $zone := (buildRateLimitZones $servers) }} - {{ $zone }} - {{ end }} - - # Cache for internal auth checks - proxy_cache_path /tmp/nginx/nginx-cache-auth levels=1:2 keys_zone=auth_cache:10m max_size=128m inactive=30m use_temp_path=off; - - # Global filters - {{ range $ip := $cfg.BlockCIDRs }}deny {{ trimSpace $ip }}; - {{ end }} - - {{ if gt (len $cfg.BlockUserAgents) 0 }} - map $http_user_agent $block_ua { - default 0; - - {{ range $ua := $cfg.BlockUserAgents }}{{ trimSpace $ua }} 1; - {{ end }} - } - {{ end }} - - {{ if gt (len $cfg.BlockReferers) 0 }} - map $http_referer $block_ref { - default 0; - - {{ range $ref := $cfg.BlockReferers }}{{ trimSpace $ref }} 1; - {{ end }} - } - {{ end }} - - {{/* Build server redirects (from/to www) */}} - {{ range $redirect := .RedirectServers }} - ## start server {{ $redirect.From }} - server { - server_name {{ $redirect.From }}; - - {{ buildHTTPListener $all $redirect.From }} - {{ buildHTTPSListener $all $redirect.From }} - - ssl_certificate_by_lua_file /etc/nginx/lua/nginx/ngx_conf_certificate.lua; - - {{ if gt (len $cfg.BlockUserAgents) 0 }} - if ($block_ua) { - return 403; - } - {{ end }} - {{ if gt (len $cfg.BlockReferers) 0 }} - if ($block_ref) { - return 403; - } - {{ end }} - - set_by_lua_file $redirect_to /etc/nginx/lua/nginx/ngx_srv_redirect.lua {{ $redirect.To }}; - - return {{ $all.Cfg.HTTPRedirectCode }} $redirect_to; - } - ## end server {{ $redirect.From }} - {{ end }} - - {{ range $server := $servers }} - {{ range $location := $server.Locations }} - {{ $applyGlobalAuth := shouldApplyGlobalAuth $location $all.Cfg.GlobalExternalAuth.URL }} - {{ $applyAuthUpstream := shouldApplyAuthUpstream $location $all.Cfg }} - {{ if and (eq $applyAuthUpstream true) (eq $applyGlobalAuth false) }} - ## start auth upstream {{ $server.Hostname }}{{ $location.Path }} - upstream {{ buildAuthUpstreamName $location $server.Hostname }} { - {{- $externalAuth := $location.ExternalAuth }} - server {{ extractHostPort $externalAuth.URL }}; - - keepalive {{ $externalAuth.KeepaliveConnections }}; - keepalive_requests {{ $externalAuth.KeepaliveRequests }}; - keepalive_timeout {{ $externalAuth.KeepaliveTimeout }}s; - } - ## end auth upstream {{ $server.Hostname }}{{ $location.Path }} - {{ end }} - {{ end }} - {{ end }} - - {{ range $server := $servers }} - ## start server {{ $server.Hostname }} - server { - server_name {{ buildServerName $server.Hostname }} {{range $server.Aliases }}{{ . }} {{ end }}; - - {{ if $cfg.UseHTTP2 }} - http2 on; - {{ end }} - - {{ if gt (len $cfg.BlockUserAgents) 0 }} - if ($block_ua) { - return 403; - } - {{ end }} - {{ if gt (len $cfg.BlockReferers) 0 }} - if ($block_ref) { - return 403; - } - {{ end }} - - {{ template "SERVER" serverConfig $all $server }} - - {{ if not (empty $cfg.ServerSnippet) }} - # Custom code snippet configured in the configuration configmap - {{ $cfg.ServerSnippet }} - {{ end }} - - {{ template "CUSTOM_ERRORS" (buildCustomErrorDeps "upstream-default-backend" $cfg.CustomHTTPErrors $all.EnableMetrics $cfg.EnableModsecurity) }} - } - ## end server {{ $server.Hostname }} - - {{ end }} - - # backend for when default-backend-service is not configured or it does not have endpoints - server { - listen {{ $all.ListenPorts.Default }} default_server {{ if $all.Cfg.ReusePort }}reuseport{{ end }} backlog={{ $all.BacklogSize }}; - {{ if $IsIPV6Enabled }}listen [::]:{{ $all.ListenPorts.Default }} default_server {{ if $all.Cfg.ReusePort }}reuseport{{ end }} backlog={{ $all.BacklogSize }};{{ end }} - set $proxy_upstream_name "internal"; - - access_log off; - - location / { - return 404; - } - } - - # default server, used for NGINX healthcheck and access to nginx stats - server { - # Ensure that modsecurity will not run on an internal location as this is not accessible from outside - {{ if $all.Cfg.EnableModsecurity }} - modsecurity off; - {{ end }} - - listen 127.0.0.1:{{ .StatusPort }}; - set $proxy_upstream_name "internal"; - - keepalive_timeout 0; - gzip off; - - access_log off; - - {{ if $cfg.EnableOpentelemetry }} - opentelemetry off; - {{ end }} - location {{ $healthzURI }} { - return 200; - } - - location /is-dynamic-lb-initialized { - content_by_lua_file /etc/nginx/lua/nginx/ngx_conf_is_dynamic_lb_initialized.lua; - } - - location {{ .StatusPath }} { - stub_status on; - } - - location /configuration { - client_max_body_size {{ luaConfigurationRequestBodySize $cfg }}; - client_body_buffer_size {{ luaConfigurationRequestBodySize $cfg }}; - proxy_buffering off; - - content_by_lua_file /etc/nginx/lua/nginx/ngx_conf_configuration.lua; - } - - location / { - return 404; - } - } -} - -stream { - lua_package_path "/etc/nginx/lua/?.lua;/etc/nginx/lua/vendor/?.lua;;"; - - lua_shared_dict tcp_udp_configuration_data 5M; - - {{ buildResolvers $cfg.Resolver $cfg.DisableIpv6DNS }} - - init_by_lua_file /etc/nginx/lua/ngx_conf_init_stream.lua; - - init_worker_by_lua_file /etc/nginx/lua/nginx/ngx_conf_init_tcp_udp.lua; - - lua_add_variable $proxy_upstream_name; - - log_format log_stream '{{ $cfg.LogFormatStream }}'; - - {{ if or $cfg.DisableAccessLog $cfg.DisableStreamAccessLog }} - access_log off; - {{ else }} - access_log {{ or $cfg.StreamAccessLogPath $cfg.AccessLogPath }} log_stream {{ $cfg.AccessLogParams }}; - {{ end }} - - - error_log {{ $cfg.ErrorLogPath }} {{ $cfg.ErrorLogLevel }}; - {{ if $cfg.EnableRealIP }} - {{ range $trusted_ip := $cfg.ProxyRealIPCIDR }} - set_real_ip_from {{ $trusted_ip }}; - {{ end }} - {{ end }} - - upstream upstream_balancer { - server 0.0.0.1:1234; # placeholder - balancer_by_lua_file /etc/nginx/lua/nginx/ngx_conf_balancer_tcp_udp.lua; - } - - server { - listen 127.0.0.1:{{ .StreamPort }}; - - access_log off; - - content_by_lua_file /etc/nginx/lua/nginx/ngx_conf_content_tcp_udp.lua; - } - - # TCP services - {{ range $tcpServer := .TCPBackends }} - server { - preread_by_lua_block { - ngx.var.proxy_upstream_name="tcp-{{ $tcpServer.Backend.Namespace }}-{{ $tcpServer.Backend.Name }}-{{ $tcpServer.Backend.Port }}"; - } - - {{ range $address := $all.Cfg.BindAddressIpv4 }} - listen {{ $address }}:{{ $tcpServer.Port }}{{ if $tcpServer.Backend.ProxyProtocol.Decode }} proxy_protocol{{ end }}; - {{ else }} - listen {{ $tcpServer.Port }}{{ if $tcpServer.Backend.ProxyProtocol.Decode }} proxy_protocol{{ end }}; - {{ end }} - {{ if $IsIPV6Enabled }} - {{ range $address := $all.Cfg.BindAddressIpv6 }} - listen {{ $address }}:{{ $tcpServer.Port }}{{ if $tcpServer.Backend.ProxyProtocol.Decode }} proxy_protocol{{ end }}; - {{ else }} - listen [::]:{{ $tcpServer.Port }}{{ if $tcpServer.Backend.ProxyProtocol.Decode }} proxy_protocol{{ end }}; - {{ end }} - {{ end }} - proxy_timeout {{ $cfg.ProxyStreamTimeout }}; - proxy_next_upstream {{ if $cfg.ProxyStreamNextUpstream }}on{{ else }}off{{ end }}; - proxy_next_upstream_timeout {{ $cfg.ProxyStreamNextUpstreamTimeout }}; - proxy_next_upstream_tries {{ $cfg.ProxyStreamNextUpstreamTries }}; - - proxy_pass upstream_balancer; - {{ if $tcpServer.Backend.ProxyProtocol.Encode }} - proxy_protocol on; - {{ end }} - } - {{ end }} - - # UDP services - {{ range $udpServer := .UDPBackends }} - server { - preread_by_lua_block { - ngx.var.proxy_upstream_name="udp-{{ $udpServer.Backend.Namespace }}-{{ $udpServer.Backend.Name }}-{{ $udpServer.Backend.Port }}"; - } - - {{ range $address := $all.Cfg.BindAddressIpv4 }} - listen {{ $address }}:{{ $udpServer.Port }} udp; - {{ else }} - listen {{ $udpServer.Port }} udp; - {{ end }} - {{ if $IsIPV6Enabled }} - {{ range $address := $all.Cfg.BindAddressIpv6 }} - listen {{ $address }}:{{ $udpServer.Port }} udp; - {{ else }} - listen [::]:{{ $udpServer.Port }} udp; - {{ end }} - {{ end }} - proxy_responses {{ $cfg.ProxyStreamResponses }}; - proxy_timeout {{ $cfg.ProxyStreamTimeout }}; - proxy_next_upstream {{ if $cfg.ProxyStreamNextUpstream }}on{{ else }}off{{ end }}; - proxy_next_upstream_timeout {{ $cfg.ProxyStreamNextUpstreamTimeout }}; - proxy_next_upstream_tries {{ $cfg.ProxyStreamNextUpstreamTries }}; - proxy_pass upstream_balancer; - } - {{ end }} - - # Stream Snippets - {{ range $snippet := .StreamSnippets }} - {{ $snippet }} - {{ end }} -} - -{{/* definition of templates to avoid repetitions */}} -{{ define "CUSTOM_ERRORS" }} - {{ $enableMetrics := .EnableMetrics }} - {{ $modsecurityEnabled := .ModsecurityEnabled }} - {{ $upstreamName := .UpstreamName }} - {{ range $errCode := .ErrorCodes }} - location @custom_{{ $upstreamName }}_{{ $errCode }} { - internal; - - # Ensure that modsecurity will not run on custom error pages or they might be blocked - {{ if $modsecurityEnabled }} - modsecurity off; - {{ end }} - - proxy_intercept_errors off; - - proxy_set_header X-Code {{ $errCode }}; - proxy_set_header X-Format $http_accept; - proxy_set_header X-Original-URI $request_uri; - proxy_set_header X-Namespace $namespace; - proxy_set_header X-Ingress-Name $ingress_name; - proxy_set_header X-Service-Name $service_name; - proxy_set_header X-Service-Port $service_port; - proxy_set_header X-Request-ID $req_id; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_set_header Host $best_http_host; - - set $proxy_upstream_name {{ $upstreamName | quote }}; - - rewrite (.*) / break; - - proxy_pass http://upstream_balancer; - {{ if $enableMetrics }} - log_by_lua_file /etc/nginx/lua/nginx/ngx_conf_log.lua; - {{ end }} - } - {{ end }} -{{ end }} - -{{/* CORS support from https://michielkalkman.com/snippets/nginx-cors-open-configuration.html */}} -{{ define "CORS" }} - {{ $cors := .CorsConfig }} - # Cors Preflight methods needs additional options and different Return Code - {{ if $cors.CorsAllowOrigin }} - {{ buildCorsOriginRegex $cors.CorsAllowOrigin }} - {{ end }} - if ($request_method = 'OPTIONS') { - set $cors ${cors}options; - } - - if ($cors = "true") { - more_set_headers 'Access-Control-Allow-Origin: $http_origin'; - {{ if $cors.CorsAllowCredentials }} more_set_headers 'Access-Control-Allow-Credentials: {{ $cors.CorsAllowCredentials }}'; {{ end }} - more_set_headers 'Access-Control-Allow-Methods: {{ $cors.CorsAllowMethods }}'; - more_set_headers 'Access-Control-Allow-Headers: {{ $cors.CorsAllowHeaders }}'; - {{ if not (empty $cors.CorsExposeHeaders) }} more_set_headers 'Access-Control-Expose-Headers: {{ $cors.CorsExposeHeaders }}'; {{ end }} - more_set_headers 'Access-Control-Max-Age: {{ $cors.CorsMaxAge }}'; - } - - if ($cors = "trueoptions") { - more_set_headers 'Access-Control-Allow-Origin: $http_origin'; - {{ if $cors.CorsAllowCredentials }} more_set_headers 'Access-Control-Allow-Credentials: {{ $cors.CorsAllowCredentials }}'; {{ end }} - more_set_headers 'Access-Control-Allow-Methods: {{ $cors.CorsAllowMethods }}'; - more_set_headers 'Access-Control-Allow-Headers: {{ $cors.CorsAllowHeaders }}'; - {{ if not (empty $cors.CorsExposeHeaders) }} more_set_headers 'Access-Control-Expose-Headers: {{ $cors.CorsExposeHeaders }}'; {{ end }} - more_set_headers 'Access-Control-Max-Age: {{ $cors.CorsMaxAge }}'; - more_set_headers 'Content-Type: text/plain charset=UTF-8'; - more_set_headers 'Content-Length: 0'; - return 204; - } -{{ end }} - -{{/* definition of server-template to avoid repetitions with server-alias */}} -{{ define "SERVER" }} - {{ $all := .First }} - {{ $server := .Second }} - - {{ buildHTTPListener $all $server.Hostname }} - {{ buildHTTPSListener $all $server.Hostname }} - - set $proxy_upstream_name "-"; - - {{ if not ( empty $server.CertificateAuth.MatchCN ) }} - {{ if gt (len $server.CertificateAuth.MatchCN) 0 }} - if ( $ssl_client_s_dn !~ {{ $server.CertificateAuth.MatchCN }} ) { - return 403 "client certificate unauthorized"; - } - {{ end }} - {{ end }} - - {{ if eq $server.Hostname "_" }} - ssl_reject_handshake {{ if $all.Cfg.SSLRejectHandshake }}on{{ else }}off{{ end }}; - {{ end }} - - ssl_certificate_by_lua_file /etc/nginx/lua/nginx/ngx_conf_certificate.lua; - - {{ if not (empty $server.AuthTLSError) }} - # {{ $server.AuthTLSError }} - return 403; - {{ else }} - - {{ if not (empty $server.CertificateAuth.CAFileName) }} - # PEM sha: {{ $server.CertificateAuth.CASHA }} - ssl_client_certificate {{ $server.CertificateAuth.CAFileName }}; - ssl_verify_client {{ $server.CertificateAuth.VerifyClient }}; - ssl_verify_depth {{ $server.CertificateAuth.ValidationDepth }}; - - {{ if not (empty $server.CertificateAuth.CRLFileName) }} - # PEM sha: {{ $server.CertificateAuth.CRLSHA }} - ssl_crl {{ $server.CertificateAuth.CRLFileName }}; - {{ end }} - - {{ if not (empty $server.CertificateAuth.ErrorPage)}} - error_page 495 496 = {{ $server.CertificateAuth.ErrorPage }}; - {{ end }} - {{ end }} - - {{ if not (empty $server.ProxySSL.CAFileName) }} - # PEM sha: {{ $server.ProxySSL.CASHA }} - proxy_ssl_trusted_certificate {{ $server.ProxySSL.CAFileName }}; - proxy_ssl_ciphers {{ $server.ProxySSL.Ciphers }}; - proxy_ssl_protocols {{ $server.ProxySSL.Protocols }}; - proxy_ssl_verify {{ $server.ProxySSL.Verify }}; - proxy_ssl_verify_depth {{ $server.ProxySSL.VerifyDepth }}; - {{ if not (empty $server.ProxySSL.ProxySSLName) }} - proxy_ssl_name {{ $server.ProxySSL.ProxySSLName }}; - proxy_ssl_server_name {{ $server.ProxySSL.ProxySSLServerName }}; - {{ end }} - {{ end }} - - {{ if not (empty $server.ProxySSL.PemFileName) }} - proxy_ssl_certificate {{ $server.ProxySSL.PemFileName }}; - proxy_ssl_certificate_key {{ $server.ProxySSL.PemFileName }}; - {{ end }} - - {{ if not (empty $server.SSLCiphers) }} - ssl_ciphers {{ $server.SSLCiphers }}; - {{ end }} - - {{ if not (empty $server.SSLPreferServerCiphers) }} - ssl_prefer_server_ciphers {{ $server.SSLPreferServerCiphers }}; - {{ end }} - - {{ if not (empty $server.ServerSnippet) }} - # Custom code snippet configured for host {{ $server.Hostname }} - {{ $server.ServerSnippet }} - {{ end }} - - {{ range $errorLocation := (buildCustomErrorLocationsPerServer $server) }} - {{ template "CUSTOM_ERRORS" (buildCustomErrorDeps $errorLocation.UpstreamName $errorLocation.Codes $all.EnableMetrics $all.Cfg.EnableModsecurity) }} - {{ end }} - - {{ buildMirrorLocations $server.Locations }} - - {{ $enforceRegex := enforceRegexModifier $server.Locations }} - {{ range $location := $server.Locations }} - {{ $path := buildLocation $location $enforceRegex }} - {{ $proxySetHeader := proxySetHeader $location }} - {{ $authPath := buildAuthLocation $location $all.Cfg.GlobalExternalAuth.URL }} - {{ $applyGlobalAuth := shouldApplyGlobalAuth $location $all.Cfg.GlobalExternalAuth.URL }} - {{ $applyAuthUpstream := shouldApplyAuthUpstream $location $all.Cfg }} - - {{ $externalAuth := $location.ExternalAuth }} - {{ if eq $applyGlobalAuth true }} - {{ $externalAuth = $all.Cfg.GlobalExternalAuth }} - {{ end }} - - {{ if not (empty $location.Rewrite.AppRoot) }} - if ($uri = /) { - return 302 $scheme://$http_host{{ $location.Rewrite.AppRoot }}; - } - {{ end }} - - {{ if $authPath }} - location = {{ $authPath }} { - internal; - - {{ if (or $all.Cfg.EnableOpentelemetry $location.Opentelemetry.Enabled) }} - opentelemetry on; - opentelemetry_propagate; - {{ end }} - - {{ if not $all.Cfg.EnableAuthAccessLog }} - access_log off; - {{ end }} - - # Ensure that modsecurity will not run on an internal location as this is not accessible from outside - {{ if $all.Cfg.EnableModsecurity }} - modsecurity off; - {{ end }} - - {{ if $externalAuth.AuthCacheKey }} - set $tmp_cache_key '{{ $server.Hostname }}{{ $authPath }}{{ $externalAuth.AuthCacheKey }}'; - set $cache_key ''; - - rewrite_by_lua_file /etc/nginx/lua/nginx/ngx_conf_rewrite_auth.lua; - - proxy_cache auth_cache; - - {{- range $dur := $externalAuth.AuthCacheDuration }} - proxy_cache_valid {{ $dur }}; - {{- end }} - - proxy_cache_key "$cache_key"; - {{ end }} - - # ngx_auth_request module overrides variables in the parent request, - # therefore we have to explicitly set this variable again so that when the parent request - # resumes it has the correct value set for this variable so that Lua can pick backend correctly - set $proxy_upstream_name {{ buildUpstreamName $location | quote }}; - - proxy_pass_request_body off; - proxy_set_header Content-Length ""; - proxy_set_header X-Forwarded-Proto ""; - proxy_set_header X-Request-ID $req_id; - - {{ if $externalAuth.Method }} - proxy_method {{ $externalAuth.Method }}; - proxy_set_header X-Original-URI $request_uri; - proxy_set_header X-Scheme $pass_access_scheme; - {{ end }} - - proxy_set_header Host {{ $externalAuth.Host }}; - proxy_set_header X-Original-URL $scheme://$http_host$request_uri; - proxy_set_header X-Original-Method $request_method; - proxy_set_header X-Sent-From "nginx-ingress-controller"; - proxy_set_header X-Real-IP $remote_addr; - {{ if and $all.Cfg.UseForwardedHeaders $all.Cfg.ComputeFullForwardedFor }} - proxy_set_header X-Forwarded-For $full_x_forwarded_for; - {{ else }} - proxy_set_header X-Forwarded-For $remote_addr; - {{ end }} - - {{ if $externalAuth.RequestRedirect }} - proxy_set_header X-Auth-Request-Redirect {{ $externalAuth.RequestRedirect }}; - {{ else }} - proxy_set_header X-Auth-Request-Redirect $request_uri; - {{ end }} - - {{ if $externalAuth.AuthCacheKey }} - proxy_buffering "on"; - {{ else }} - proxy_buffering {{ $location.Proxy.ProxyBuffering }}; - {{ end }} - proxy_buffer_size {{ $location.Proxy.BufferSize }}; - proxy_buffers {{ $location.Proxy.BuffersNumber }} {{ $location.Proxy.BufferSize }}; - proxy_request_buffering {{ $location.Proxy.RequestBuffering }}; - - proxy_ssl_server_name on; - proxy_pass_request_headers on; - {{ if isValidByteSize $location.Proxy.BodySize true }} - client_max_body_size {{ $location.Proxy.BodySize }}; - {{ end }} - {{ if isValidByteSize $location.ClientBodyBufferSize false }} - client_body_buffer_size {{ $location.ClientBodyBufferSize }}; - {{ end }} - - # Pass the extracted client certificate to the auth provider - {{ if not (empty $server.CertificateAuth.CAFileName) }} - {{ if $server.CertificateAuth.PassCertToUpstream }} - proxy_set_header ssl-client-cert $ssl_client_escaped_cert; - {{ end }} - proxy_set_header ssl-client-verify $ssl_client_verify; - proxy_set_header ssl-client-subject-dn $ssl_client_s_dn; - proxy_set_header ssl-client-issuer-dn $ssl_client_i_dn; - {{ end }} - - {{- range $line := buildAuthProxySetHeaders $externalAuth.ProxySetHeaders}} - {{ $line }} - {{- end }} - - {{ if not (empty $externalAuth.AuthSnippet) }} - {{ $externalAuth.AuthSnippet }} - {{ end }} - - {{ if and (eq $applyAuthUpstream true) (eq $applyGlobalAuth false) }} - {{ $authUpstreamName := buildAuthUpstreamName $location $server.Hostname }} - # The target is an upstream with HTTP keepalive, that is why the - # Connection header is cleared and the HTTP version is set to 1.1 as - # the Nginx documentation suggests: - # http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive - proxy_http_version 1.1; - proxy_set_header Connection ""; - set $target {{ changeHostPort $externalAuth.URL $authUpstreamName }}; - {{ else }} - proxy_http_version {{ $location.Proxy.ProxyHTTPVersion }}; - set $target {{ $externalAuth.URL }}; - {{ end }} - proxy_pass $target; - } - {{ end }} - - {{ if isLocationAllowed $location }} - {{ if $externalAuth.SigninURL }} - location {{ buildAuthSignURLLocation $location.Path $externalAuth.SigninURL }} { - internal; - - add_header Set-Cookie $auth_cookie; - - {{ if $location.CorsConfig.CorsEnabled }} - {{ template "CORS" $location }} - {{ end }} - - # Ensure that modsecurity will not run on an internal location as this is not accessible from outside - {{ if $all.Cfg.EnableModsecurity }} - modsecurity off; - {{ end }} - - return 302 {{ buildAuthSignURL $externalAuth.SigninURL $externalAuth.SigninURLRedirectParam }}; - } - {{ end }} - {{ end }} - - location {{ $path }} { - {{ $ing := (getIngressInformation $location.Ingress $server.Hostname $location.IngressPath) }} - set $namespace {{ $ing.Namespace | quote}}; - set $ingress_name {{ $ing.Rule | quote }}; - set $service_name {{ $ing.Service | quote }}; - set $service_port {{ $ing.ServicePort | quote }}; - set $location_path {{ $ing.Path | escapeLiteralDollar | quote }}; - - {{ buildOpentelemetryForLocation $all.Cfg.EnableOpentelemetry $all.Cfg.OpentelemetryTrustIncomingSpan $location }} - - {{ if $location.Mirror.Source }} - mirror {{ $location.Mirror.Source }}; - mirror_request_body {{ $location.Mirror.RequestBody }}; - {{ end }} - - {{ locationConfigForLua $location $all }} - - rewrite_by_lua_file /etc/nginx/lua/nginx/ngx_rewrite.lua; - - header_filter_by_lua_file /etc/nginx/lua/nginx/ngx_conf_srv_hdr_filter.lua; - - log_by_lua_file /etc/nginx/lua/nginx/ngx_conf_log_block.lua; - - {{ if not $location.Logs.Access }} - access_log off; - {{ end }} - - {{ if $location.Logs.Rewrite }} - rewrite_log on; - {{ end }} - - {{ if $location.HTTP2PushPreload }} - http2_push_preload on; - {{ end }} - - port_in_redirect {{ if $location.UsePortInRedirects }}on{{ else }}off{{ end }}; - - set $balancer_ewma_score -1; - set $proxy_upstream_name {{ buildUpstreamName $location | quote }}; - set $proxy_host $proxy_upstream_name; - set $pass_access_scheme $scheme; - - {{ if $all.Cfg.UseProxyProtocol }} - set $pass_server_port $proxy_protocol_server_port; - {{ else }} - set $pass_server_port $server_port; - {{ end }} - - set $best_http_host $http_host; - set $pass_port $pass_server_port; - - set $proxy_alternative_upstream_name ""; - - {{ buildModSecurityForLocation $all.Cfg $location }} - - {{ if isLocationAllowed $location }} - {{ if gt (len $location.Denylist.CIDR) 0 }} - {{ range $ip := $location.Denylist.CIDR }} - deny {{ $ip }};{{ end }} - {{ end }} - {{ if gt (len $location.Allowlist.CIDR) 0 }} - {{ range $ip := $location.Allowlist.CIDR }} - allow {{ $ip }};{{ end }} - deny all; - {{ end }} - - {{ if $location.CorsConfig.CorsEnabled }} - {{ template "CORS" $location }} - {{ end }} - - {{ if not (isLocationInLocationList $location $all.Cfg.NoAuthLocations) }} - {{ if $authPath }} - # this location requires authentication - {{ if and (eq $applyAuthUpstream true) (eq $applyGlobalAuth false) }} - set $auth_cookie ''; - add_header Set-Cookie $auth_cookie; - {{- range $line := buildAuthResponseHeaders $proxySetHeader $externalAuth.ResponseHeaders true }} - {{ $line }} - {{- end }} - # `auth_request` module does not support HTTP keepalives in upstream block: - # https://trac.nginx.org/nginx/ticket/1579 - access_by_lua_block { - local res = ngx.location.capture('{{ $authPath }}', { method = ngx.HTTP_GET, body = '', share_all_vars = {{ $externalAuth.KeepaliveShareVars }} }) - if res.status == ngx.HTTP_OK then - ngx.var.auth_cookie = res.header['Set-Cookie'] - {{- range $line := buildAuthUpstreamLuaHeaders $externalAuth.ResponseHeaders }} - {{ $line }} - {{- end }} - return - end - if res.status == ngx.HTTP_UNAUTHORIZED or res.status == ngx.HTTP_FORBIDDEN then - ngx.exit(res.status) - end - ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) - } - {{ else }} - auth_request {{ $authPath }}; - auth_request_set $auth_cookie $upstream_http_set_cookie; - {{ if $externalAuth.AlwaysSetCookie }} - add_header Set-Cookie $auth_cookie always; - {{ else }} - add_header Set-Cookie $auth_cookie; - {{ end }} - {{- range $line := buildAuthResponseHeaders $proxySetHeader $externalAuth.ResponseHeaders false }} - {{ $line }} - {{- end }} - {{ end }} - {{ end }} - - {{ if $externalAuth.SigninURL }} - set_escape_uri $escaped_request_uri $request_uri; - error_page 401 = {{ buildAuthSignURLLocation $location.Path $externalAuth.SigninURL }}; - {{ end }} - - {{ if $location.BasicDigestAuth.Secured }} - {{ if eq $location.BasicDigestAuth.Type "basic" }} - auth_basic {{ $location.BasicDigestAuth.Realm | quote }}; - auth_basic_user_file {{ $location.BasicDigestAuth.File }}; - {{ else }} - auth_digest {{ $location.BasicDigestAuth.Realm | quote }}; - auth_digest_user_file {{ $location.BasicDigestAuth.File }}; - {{ end }} - {{ $proxySetHeader }} Authorization ""; - {{ end }} - {{ end }} - - {{/* if the location contains a rate limit annotation, create one */}} - {{ $limits := buildRateLimit $location }} - {{ range $limit := $limits }} - {{ $limit }}{{ end }} - - {{ if isValidByteSize $location.Proxy.BodySize true }} - client_max_body_size {{ $location.Proxy.BodySize }}; - {{ end }} - {{ if isValidByteSize $location.ClientBodyBufferSize false }} - client_body_buffer_size {{ $location.ClientBodyBufferSize }}; - {{ end }} - - {{/* By default use vhost as Host to upstream, but allow overrides */}} - {{ if not (empty $location.UpstreamVhost) }} - {{ $proxySetHeader }} Host {{ $location.UpstreamVhost | quote }}; - {{ else }} - {{ $proxySetHeader }} Host $best_http_host; - {{ end }} - - # Pass the extracted client certificate to the backend - {{ if not (empty $server.CertificateAuth.CAFileName) }} - {{ if $server.CertificateAuth.PassCertToUpstream }} - {{ $proxySetHeader }} ssl-client-cert $ssl_client_escaped_cert; - {{ end }} - {{ $proxySetHeader }} ssl-client-verify $ssl_client_verify; - {{ $proxySetHeader }} ssl-client-subject-dn $ssl_client_s_dn; - {{ $proxySetHeader }} ssl-client-issuer-dn $ssl_client_i_dn; - {{ end }} - - # Allow websocket connections - {{ $proxySetHeader }} Upgrade $http_upgrade; - {{ if $location.Connection.Enabled}} - {{ $proxySetHeader }} Connection {{ $location.Connection.Header }}; - {{ else }} - {{ $proxySetHeader }} Connection $connection_upgrade; - {{ end }} - - {{ $proxySetHeader }} X-Request-ID $req_id; - {{ $proxySetHeader }} X-Real-IP $remote_addr; - {{ if and $all.Cfg.UseForwardedHeaders $all.Cfg.ComputeFullForwardedFor }} - {{ $proxySetHeader }} X-Forwarded-For $full_x_forwarded_for; - {{ else }} - {{ $proxySetHeader }} X-Forwarded-For $remote_addr; - {{ end }} - {{ $proxySetHeader }} X-Forwarded-Host $best_http_host; - {{ $proxySetHeader }} X-Forwarded-Port $pass_port; - {{ $proxySetHeader }} X-Forwarded-Proto $pass_access_scheme; - {{ $proxySetHeader }} X-Forwarded-Scheme $pass_access_scheme; - {{ if $all.Cfg.ProxyAddOriginalURIHeader }} - {{ $proxySetHeader }} X-Original-URI $request_uri; - {{ end }} - {{ $proxySetHeader }} X-Scheme $pass_access_scheme; - - # Pass the original X-Forwarded-For - {{ $proxySetHeader }} X-Original-Forwarded-For {{ buildForwardedFor $all.Cfg.ForwardedForHeader }}; - - # mitigate HTTPoxy Vulnerability - # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/ - {{ $proxySetHeader }} Proxy ""; - - # Custom headers to proxied server - {{ range $k, $v := $all.ProxySetHeaders }} - {{ $proxySetHeader }} {{ $k }} {{ $v | quote }}; - {{ end }} - - proxy_connect_timeout {{ $location.Proxy.ConnectTimeout }}s; - proxy_send_timeout {{ $location.Proxy.SendTimeout }}s; - proxy_read_timeout {{ $location.Proxy.ReadTimeout }}s; - - proxy_buffering {{ $location.Proxy.ProxyBuffering }}; - proxy_buffer_size {{ $location.Proxy.BufferSize }}; - proxy_buffers {{ $location.Proxy.BuffersNumber }} {{ $location.Proxy.BufferSize }}; - {{ if isValidByteSize $location.Proxy.ProxyMaxTempFileSize true }} - proxy_max_temp_file_size {{ $location.Proxy.ProxyMaxTempFileSize }}; - {{ end }} - proxy_request_buffering {{ $location.Proxy.RequestBuffering }}; - proxy_http_version {{ $location.Proxy.ProxyHTTPVersion }}; - - proxy_cookie_domain {{ $location.Proxy.CookieDomain }}; - proxy_cookie_path {{ $location.Proxy.CookiePath }}; - - # In case of errors try the next upstream server before returning an error - proxy_next_upstream {{ buildNextUpstream $location.Proxy.NextUpstream $all.Cfg.RetryNonIdempotent }}; - proxy_next_upstream_timeout {{ $location.Proxy.NextUpstreamTimeout }}; - proxy_next_upstream_tries {{ $location.Proxy.NextUpstreamTries }}; - - {{ if or (eq $location.BackendProtocol "GRPC") (eq $location.BackendProtocol "GRPCS") }} - # Grpc settings - grpc_connect_timeout {{ $location.Proxy.ConnectTimeout }}s; - grpc_send_timeout {{ $location.Proxy.SendTimeout }}s; - grpc_read_timeout {{ $location.Proxy.ReadTimeout }}s; - {{ end }} - - {{/* Add any additional configuration defined */}} - {{ $location.ConfigurationSnippet }} - - {{ if not (empty $all.Cfg.LocationSnippet) }} - # Custom code snippet configured in the configuration configmap - {{ $all.Cfg.LocationSnippet }} - {{ end }} - - {{ if $location.CustomHeaders }} - # Custom Response Headers - {{ range $k, $v := $location.CustomHeaders.Headers }} - more_set_headers {{ printf "%s: %s" $k $v | escapeLiteralDollar | quote }}; - {{ end }} - {{ end }} - - {{/* if we are sending the request to a custom default backend, we add the required headers */}} - {{ if (hasPrefix $location.Backend "custom-default-backend-") }} - proxy_set_header X-Code 503; - proxy_set_header X-Format $http_accept; - proxy_set_header X-Namespace $namespace; - proxy_set_header X-Ingress-Name $ingress_name; - proxy_set_header X-Service-Name $service_name; - proxy_set_header X-Service-Port $service_port; - proxy_set_header X-Request-ID $req_id; - {{ end }} - - {{ if $location.Satisfy }} - satisfy {{ $location.Satisfy }}; - {{ end }} - - {{/* if a location-specific error override is set, add the proxy_intercept here */}} - {{ if and $location.CustomHTTPErrors (not $location.DisableProxyInterceptErrors) }} - # Custom error pages per ingress - proxy_intercept_errors on; - {{ end }} - - {{ range $errCode := $location.CustomHTTPErrors }} - error_page {{ $errCode }} = @custom_{{ $location.DefaultBackendUpstreamName }}_{{ $errCode }};{{ end }} - - {{ if (eq $location.BackendProtocol "FCGI") }} - include /etc/nginx/fastcgi_params; - {{ end }} - {{- if $location.FastCGI.Index -}} - fastcgi_index {{ $location.FastCGI.Index | quote }}; - {{- end -}} - {{ range $k, $v := $location.FastCGI.Params }} - fastcgi_param {{ $k }} {{ $v | quote }}; - {{ end }} - - {{ if not (empty $location.Redirect.URL) }} - return {{ $location.Redirect.Code }} {{ $location.Redirect.URL }}; - {{ end }} - - {{ buildProxyPass $server.Hostname $all.Backends $location }} - {{ if (or (eq $location.Proxy.ProxyRedirectFrom "default") (eq $location.Proxy.ProxyRedirectFrom "off")) }} - proxy_redirect {{ $location.Proxy.ProxyRedirectFrom }}; - {{ else if not (eq $location.Proxy.ProxyRedirectTo "off") }} - proxy_redirect {{ $location.Proxy.ProxyRedirectFrom }} {{ $location.Proxy.ProxyRedirectTo }}; - {{ end }} - {{ else }} - # Location denied. Reason: {{ $location.Denied | quote }} - return 503; - {{ end }} - {{ if not (empty $location.ProxySSL.CAFileName) }} - # PEM sha: {{ $location.ProxySSL.CASHA }} - proxy_ssl_trusted_certificate {{ $location.ProxySSL.CAFileName }}; - proxy_ssl_ciphers {{ $location.ProxySSL.Ciphers }}; - proxy_ssl_protocols {{ $location.ProxySSL.Protocols }}; - proxy_ssl_verify {{ $location.ProxySSL.Verify }}; - proxy_ssl_verify_depth {{ $location.ProxySSL.VerifyDepth }}; - {{ end }} - - {{ if not (empty $location.ProxySSL.ProxySSLName) }} - proxy_ssl_name {{ $location.ProxySSL.ProxySSLName }}; - {{ end }} - {{ if not (empty $location.ProxySSL.ProxySSLServerName) }} - proxy_ssl_server_name {{ $location.ProxySSL.ProxySSLServerName }}; - {{ end }} - - {{ if not (empty $location.ProxySSL.PemFileName) }} - proxy_ssl_certificate {{ $location.ProxySSL.PemFileName }}; - proxy_ssl_certificate_key {{ $location.ProxySSL.PemFileName }}; - {{ end }} - } - {{ end }} - {{ end }} - - {{ if eq $server.Hostname "_" }} - # health checks in cloud providers require the use of port {{ $all.ListenPorts.HTTP }} - location {{ $all.HealthzURI }} { - - {{ if $all.Cfg.EnableOpentelemetry }} - opentelemetry off; - {{ end }} - - access_log off; - return 200; - } - - # this is required to avoid error if nginx is being monitored - # with an external software (like sysdig) - location /nginx_status { - - {{ if $all.Cfg.EnableOpentelemetry }} - opentelemetry off; - {{ end }} - - {{ range $v := $all.NginxStatusIpv4Whitelist }} - allow {{ $v }}; - {{ end }} - {{ if $all.IsIPV6Enabled -}} - {{ range $v := $all.NginxStatusIpv6Whitelist }} - allow {{ $v }}; - {{ end }} - {{ end -}} - deny all; - - access_log off; - stub_status on; - } - - {{ end }} - -{{ end }} diff --git a/internal/ingress/controller/template/crossplane/testdata/nginx-new.tmpl b/internal/ingress/controller/template/crossplane/testdata/nginx-new.tmpl deleted file mode 100644 index 547fd12da..000000000 --- a/internal/ingress/controller/template/crossplane/testdata/nginx-new.tmpl +++ /dev/null @@ -1,1268 +0,0 @@ -{{ $all := . }} -{{ $servers := .Servers }} -{{ $cfg := .Cfg }} -{{ $IsIPV6Enabled := .IsIPV6Enabled }} -{{ $healthzURI := .HealthzURI }} -{{ $backends := .Backends }} -{{ $proxyHeaders := .ProxySetHeaders }} -{{ $addHeaders := .AddHeaders }} - -# Configuration checksum: {{ $all.Cfg.Checksum }} - -# setup custom paths that do not require root access -pid {{ .PID }}; # OK - -{{ if $cfg.UseGeoIP2 }} -load_module /etc/nginx/modules/ngx_http_geoip2_module.so; # OK -{{ end }} - -{{ if $cfg.EnableBrotli }} -load_module /etc/nginx/modules/ngx_http_brotli_filter_module.so; # OK -load_module /etc/nginx/modules/ngx_http_brotli_static_module.so; # OK -{{ end }} - -{{ if (shouldLoadAuthDigestModule $servers) }} -load_module /etc/nginx/modules/ngx_http_auth_digest_module.so; # OK -{{ end }} - -{{ if (shouldLoadOpentelemetryModule $cfg $servers) }} -load_module /etc/nginx/modules/otel_ngx_module.so; # OK -{{ end }} - -daemon off; # OK - -worker_processes {{ $cfg.WorkerProcesses }}; # OK -{{ if gt (len $cfg.WorkerCPUAffinity) 0 }} -worker_cpu_affinity {{ $cfg.WorkerCPUAffinity }}; # OK -{{ end }} - -worker_rlimit_nofile {{ $cfg.MaxWorkerOpenFiles }}; # OK - -{{/* http://nginx.org/en/docs/ngx_core_module.html#worker_shutdown_timeout */}} -{{/* avoid waiting too long during a reload */}} -worker_shutdown_timeout {{ $cfg.WorkerShutdownTimeout }} ; # OK - -events { - multi_accept {{ if $cfg.EnableMultiAccept }}on{{ else }}off{{ end }}; # OK - worker_connections {{ $cfg.MaxWorkerConnections }}; # OK - use epoll; # OK - {{ range $index , $v := $cfg.DebugConnections }} - debug_connection {{ $v }}; # OK - {{ end }} -} - -http { - {{ if (shouldLoadOpentelemetryModule $cfg $servers) }} - opentelemetry_config {{ $cfg.OpentelemetryConfig }}; # OK - {{ end }} - - lua_package_path "/etc/nginx/lua/?.lua;;"; # OK - - {{ buildLuaSharedDictionaries $cfg $servers }} # OK - - lua_shared_dict luaconfig 5m; # OK - - init_by_lua_file /etc/nginx/lua/ngx_conf_init.lua; # OK - - init_worker_by_lua_file /etc/nginx/lua/ngx_conf_init_worker.lua; # OK - - {{/* Enable the real_ip module only if we use either X-Forwarded headers or Proxy Protocol. */}} - {{/* we use the value of the real IP for the geo_ip module */}} - {{ if or (or $cfg.UseForwardedHeaders $cfg.UseProxyProtocol) $cfg.EnableRealIP }} - {{ if $cfg.UseProxyProtocol }} - real_ip_header proxy_protocol; # OK - {{ else }} - real_ip_header {{ $cfg.ForwardedForHeader }}; # OK - {{ end }} - - real_ip_recursive on; # OK - {{ range $trusted_ip := $cfg.ProxyRealIPCIDR }} - set_real_ip_from {{ $trusted_ip }}; # OK - {{ end }} - {{ end }} - - {{ if $cfg.UseGeoIP2 }} - # https://github.com/leev/ngx_http_geoip2_module#example-usage - - {{ range $index, $file := $all.MaxmindEditionFiles }} - {{ if eq $file "GeoLite2-Country.mmdb" }} - geoip2 /etc/ingress-controller/geoip/GeoLite2-Country.mmdb { # OK - {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} - auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; # OK - {{ end }} - $geoip2_country_code source=$remote_addr country iso_code; # OK - $geoip2_country_name source=$remote_addr country names en; # OK - $geoip2_country_geoname_id source=$remote_addr country geoname_id; # OK - $geoip2_continent_code source=$remote_addr continent code; # OK - $geoip2_continent_name source=$remote_addr continent names en; # OK - $geoip2_continent_geoname_id source=$remote_addr continent geoname_id; # OK - } - {{ end }} - - {{ if eq $file "GeoIP2-Country.mmdb" }} - geoip2 /etc/ingress-controller/geoip/GeoIP2-Country.mmdb { # OK - {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} - auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; # OK - {{ end }} - $geoip2_country_code source=$remote_addr country iso_code; # OK - $geoip2_country_name source=$remote_addr country names en; # OK - $geoip2_country_geoname_id source=$remote_addr country geoname_id; # OK - $geoip2_continent_code source=$remote_addr continent code; # OK - $geoip2_continent_name source=$remote_addr continent names en; # OK - $geoip2_continent_geoname_id source=$remote_addr continent geoname_id; # OK - } - {{ end }} - - {{ if eq $file "GeoLite2-City.mmdb" }} - geoip2 /etc/ingress-controller/geoip/GeoLite2-City.mmdb { # OK - {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} - auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; # OK - {{ end }} - $geoip2_city_country_code source=$remote_addr country iso_code; # OK - $geoip2_city_country_name source=$remote_addr country names en; # OK - $geoip2_city_country_geoname_id source=$remote_addr country geoname_id; # OK - $geoip2_city source=$remote_addr city names en; # OK - $geoip2_city_geoname_id source=$remote_addr city geoname_id; # OK - $geoip2_postal_code source=$remote_addr postal code; # OK - $geoip2_dma_code source=$remote_addr location metro_code; # OK - $geoip2_latitude source=$remote_addr location latitude; # OK - $geoip2_longitude source=$remote_addr location longitude; # OK - $geoip2_time_zone source=$remote_addr location time_zone; # OK - $geoip2_region_code source=$remote_addr subdivisions 0 iso_code; # OK - $geoip2_region_name source=$remote_addr subdivisions 0 names en; # OK - $geoip2_region_geoname_id source=$remote_addr subdivisions 0 geoname_id; # OK - $geoip2_subregion_code source=$remote_addr subdivisions 1 iso_code; # OK - $geoip2_subregion_name source=$remote_addr subdivisions 1 names en; # OK - $geoip2_subregion_geoname_id source=$remote_addr subdivisions 1 geoname_id; # OK - $geoip2_city_continent_code source=$remote_addr continent code; # OK - $geoip2_city_continent_name source=$remote_addr continent names en; # OK - } - {{ end }} - - {{ if eq $file "GeoIP2-City.mmdb" }} - geoip2 /etc/ingress-controller/geoip/GeoIP2-City.mmdb { # OK - {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} - auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; # OK - {{ end }} - $geoip2_city_country_code source=$remote_addr country iso_code; # OK - $geoip2_city_country_name source=$remote_addr country names en; # OK - $geoip2_city_country_geoname_id source=$remote_addr country geoname_id; # OK - $geoip2_city source=$remote_addr city names en; # OK - $geoip2_city_geoname_id source=$remote_addr city geoname_id; # OK - $geoip2_postal_code source=$remote_addr postal code; # OK - $geoip2_dma_code source=$remote_addr location metro_code; # OK - $geoip2_latitude source=$remote_addr location latitude; # OK - $geoip2_longitude source=$remote_addr location longitude; # OK - $geoip2_time_zone source=$remote_addr location time_zone; # OK - $geoip2_region_code source=$remote_addr subdivisions 0 iso_code; # OK - $geoip2_region_name source=$remote_addr subdivisions 0 names en; # OK - $geoip2_region_geoname_id source=$remote_addr subdivisions 0 geoname_id; # OK - $geoip2_subregion_code source=$remote_addr subdivisions 1 iso_code; # OK - $geoip2_subregion_name source=$remote_addr subdivisions 1 names en; # OK - $geoip2_subregion_geoname_id source=$remote_addr subdivisions 1 geoname_id; # OK - $geoip2_city_continent_code source=$remote_addr continent code; # OK - $geoip2_city_continent_name source=$remote_addr continent names en; # OK - } - {{ end }} - - {{ if eq $file "GeoLite2-ASN.mmdb" }} - geoip2 /etc/ingress-controller/geoip/GeoLite2-ASN.mmdb { # OK - {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} - auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; # OK - {{ end }} - $geoip2_asn source=$remote_addr autonomous_system_number; # OK - $geoip2_org source=$remote_addr autonomous_system_organization; # OK - } - {{ end }} - - {{ if eq $file "GeoIP2-ASN.mmdb" }} - geoip2 /etc/ingress-controller/geoip/GeoIP2-ASN.mmdb { # OK - {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} - auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; # OK - {{ end }} - $geoip2_asn source=$remote_addr autonomous_system_number; # OK - $geoip2_org source=$remote_addr autonomous_system_organization; # OK - } - {{ end }} - - {{ if eq $file "GeoIP2-ISP.mmdb" }} - geoip2 /etc/ingress-controller/geoip/GeoIP2-ISP.mmdb { # OK - {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} - auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; # OK - {{ end }} - $geoip2_isp source=$remote_addr isp; # OK - $geoip2_isp_org source=$remote_addr organization; # OK - $geoip2_asn source=$remote_addr default=0 autonomous_system_number; # OK - } - {{ end }} - - {{ if eq $file "GeoIP2-Connection-Type.mmdb" }} - geoip2 /etc/ingress-controller/geoip/GeoIP2-Connection-Type.mmdb { - $geoip2_connection_type connection_type; - } - {{ end }} - - {{ if eq $file "GeoIP2-Anonymous-IP.mmdb" }} - geoip2 /etc/ingress-controller/geoip/GeoIP2-Anonymous-IP.mmdb { # OK - {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} - auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; # OK - {{ end }} - $geoip2_is_anon source=$remote_addr is_anonymous; # OK - $geoip2_is_anonymous source=$remote_addr default=0 is_anonymous; # OK - $geoip2_is_anonymous_vpn source=$remote_addr default=0 is_anonymous_vpn; # OK - $geoip2_is_hosting_provider source=$remote_addr default=0 is_hosting_provider; # OK - $geoip2_is_public_proxy source=$remote_addr default=0 is_public_proxy; # OK - $geoip2_is_tor_exit_node source=$remote_addr default=0 is_tor_exit_node; # OK - } - {{ end }} - - {{ end }} - - {{ end }} - - aio threads; # OK - - {{ if $cfg.EnableAioWrite }} - aio_write on; # OK - {{ end }} - - tcp_nopush on; # OK - tcp_nodelay on; # OK - - log_subrequest on; # OK - - reset_timedout_connection on; # OK - - keepalive_timeout {{ $cfg.KeepAlive }}s; # OK - keepalive_requests {{ $cfg.KeepAliveRequests }}; # OK - - client_body_temp_path /tmp/nginx/client-body; # OK - fastcgi_temp_path /tmp/nginx/fastcgi-temp; # OK - proxy_temp_path /tmp/nginx/proxy-temp; # OK - - client_header_buffer_size {{ $cfg.ClientHeaderBufferSize }}; # OK - client_header_timeout {{ $cfg.ClientHeaderTimeout }}s; # OK - large_client_header_buffers {{ $cfg.LargeClientHeaderBuffers }}; # OK - client_body_buffer_size {{ $cfg.ClientBodyBufferSize }}; # OK - client_body_timeout {{ $cfg.ClientBodyTimeout }}s; # OK - - {{ if gt $cfg.GRPCBufferSizeKb 0 }} - grpc_buffer_size {{ $cfg.GRPCBufferSizeKb }}k; # OK - {{ end }} - - {{ if and (ne $cfg.HTTP2MaxHeaderSize "") (ne $cfg.HTTP2MaxFieldSize "") }} # OK - http2_max_field_size {{ $cfg.HTTP2MaxFieldSize }}; # OK - http2_max_header_size {{ $cfg.HTTP2MaxHeaderSize }}; # OK - {{ end }} - - {{ if (gt $cfg.HTTP2MaxRequests 0) }} # OK - http2_max_requests {{ $cfg.HTTP2MaxRequests }}; # OK - {{ end }} - - http2_max_concurrent_streams {{ $cfg.HTTP2MaxConcurrentStreams }}; # OK - - types_hash_max_size 2048; # OK - server_names_hash_max_size {{ $cfg.ServerNameHashMaxSize }}; # OK - server_names_hash_bucket_size {{ $cfg.ServerNameHashBucketSize }}; # OK - map_hash_bucket_size {{ $cfg.MapHashBucketSize }}; # OK - - proxy_headers_hash_max_size {{ $cfg.ProxyHeadersHashMaxSize }}; # OK - proxy_headers_hash_bucket_size {{ $cfg.ProxyHeadersHashBucketSize }}; # OK - - variables_hash_bucket_size {{ $cfg.VariablesHashBucketSize }}; # OK - variables_hash_max_size {{ $cfg.VariablesHashMaxSize }}; # OK - - underscores_in_headers {{ if $cfg.EnableUnderscoresInHeaders }}on{{ else }}off{{ end }}; # OK - ignore_invalid_headers {{ if $cfg.IgnoreInvalidHeaders }}on{{ else }}off{{ end }}; # OK - - limit_req_status {{ $cfg.LimitReqStatusCode }}; # OK - limit_conn_status {{ $cfg.LimitConnStatusCode }}; # OK - - {{ buildOpentelemetry $cfg $servers }} - - include /etc/nginx/mime.types; # OK - default_type {{ $cfg.DefaultType }}; # OK - - {{ if $cfg.EnableBrotli }} - brotli on; # OK - brotli_comp_level {{ $cfg.BrotliLevel }}; # OK - brotli_min_length {{ $cfg.BrotliMinLength }}; # OK - brotli_types {{ $cfg.BrotliTypes }}; # OK - {{ end }} - - {{ if $cfg.UseGzip }} - gzip on; # OK - gzip_comp_level {{ $cfg.GzipLevel }}; # OK - {{- if $cfg.GzipDisable }} - gzip_disable "{{ $cfg.GzipDisable }}"; # OK - {{- end }} - gzip_http_version 1.1; # OK - gzip_min_length {{ $cfg.GzipMinLength}}; # OK - gzip_types {{ $cfg.GzipTypes }}; # OK - gzip_proxied any; # OK - gzip_vary on; # OK - {{ end }} - - # Custom headers for response - {{ range $k, $v := $addHeaders }} - more_set_headers {{ printf "%s: %s" $k $v | quote }}; # OK - {{ end }} - - server_tokens {{ if $cfg.ShowServerTokens }}on{{ else }}off{{ end }}; # OK - {{ if not $cfg.ShowServerTokens }} - more_clear_headers Server; # OK - {{ end }} - - # disable warnings - uninitialized_variable_warn off; # OK - - # Additional available variables: - # $namespace - # $ingress_name - # $service_name - # $service_port - log_format upstreaminfo {{ if $cfg.LogFormatEscapeNone }}escape=none {{ else if $cfg.LogFormatEscapeJSON }}escape=json {{ end }}'{{ $cfg.LogFormatUpstream }}'; # OK - - {{/* map urls that should not appear in access.log */}} - {{/* http://nginx.org/en/docs/http/ngx_http_log_module.html#access_log */}} - map $request_uri $loggable { # OK - {{ range $reqUri := $cfg.SkipAccessLogURLs }} - {{ $reqUri }} 0;{{ end }} # OK - default 1; # OK - } - - {{ if or $cfg.DisableAccessLog $cfg.DisableHTTPAccessLog }} - access_log off; # OK - {{ else }} - {{ if $cfg.EnableSyslog }} - access_log syslog:server={{ $cfg.SyslogHost }}:{{ $cfg.SyslogPort }} upstreaminfo if=$loggable; # OK - {{ else }} - access_log {{ or $cfg.HTTPAccessLogPath $cfg.AccessLogPath }} upstreaminfo {{ $cfg.AccessLogParams }} if=$loggable; # OK - {{ end }} - {{ end }} - - {{ if $cfg.EnableSyslog }} - error_log syslog:server={{ $cfg.SyslogHost }}:{{ $cfg.SyslogPort }} {{ $cfg.ErrorLogLevel }}; # OK - {{ else }} - error_log {{ $cfg.ErrorLogPath }} {{ $cfg.ErrorLogLevel }}; # OK - {{ end }} - - {{ buildResolvers $cfg.Resolver $cfg.DisableIpv6DNS }} # OK - - # See https://www.nginx.com/blog/websocket-nginx - map $http_upgrade $connection_upgrade { # OK - default upgrade; # OK - {{ if (gt $cfg.UpstreamKeepaliveConnections 0) }} - # See http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive - '' ''; # OK - {{ else }} - '' close; # OK - {{ end }} - } - - # Reverse proxies can detect if a client provides a X-Request-ID header, and pass it on to the backend server. - # If no such header is provided, it can provide a random value. - map $http_x_request_id $req_id { # OK - default $http_x_request_id; # OK - {{ if $cfg.GenerateRequestID }} - "" $request_id; # OK - {{ end }} - } - - {{ if and $cfg.UseForwardedHeaders $cfg.ComputeFullForwardedFor }} - # We can't use $proxy_add_x_forwarded_for because the realip module - # replaces the remote_addr too soon - map $http_x_forwarded_for $full_x_forwarded_for { # OK - {{ if $all.Cfg.UseProxyProtocol }} - default "$http_x_forwarded_for, $proxy_protocol_addr"; # OK - '' "$proxy_protocol_addr"; # OK - {{ else }} - default "$http_x_forwarded_for, $realip_remote_addr"; # OK - '' "$realip_remote_addr"; # OK - {{ end}} - } - - {{ end }} - - # Create a variable that contains the literal $ character. - # This works because the geo module will not resolve variables. - geo $literal_dollar { # OK - default "$"; # OK - } - - server_name_in_redirect off; # OK - port_in_redirect off; # OK - - ssl_protocols {{ $cfg.SSLProtocols }}; # OK - - ssl_early_data {{ if $cfg.SSLEarlyData }}on{{ else }}off{{ end }}; # OK - - # turn on session caching to drastically improve performance - {{ if $cfg.SSLSessionCache }} - ssl_session_cache shared:SSL:{{ $cfg.SSLSessionCacheSize }}; # OK - ssl_session_timeout {{ $cfg.SSLSessionTimeout }}; # OK - {{ end }} - - # allow configuring ssl session tickets - ssl_session_tickets {{ if $cfg.SSLSessionTickets }}on{{ else }}off{{ end }}; # OK - - {{ if not (empty $cfg.SSLSessionTicketKey ) }} - ssl_session_ticket_key /etc/ingress-controller/tickets.key; # OK - {{ end }} - - # slightly reduce the time-to-first-byte - ssl_buffer_size {{ $cfg.SSLBufferSize }}; # OK - - {{ if not (empty $cfg.SSLCiphers) }} - # allow configuring custom ssl ciphers - ssl_ciphers '{{ $cfg.SSLCiphers }}'; # OK - ssl_prefer_server_ciphers on; # OK - {{ end }} - - {{ if not (empty $cfg.SSLDHParam) }} - # allow custom DH file http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_dhparam - ssl_dhparam {{ $cfg.SSLDHParam }}; # OK - {{ end }} - - ssl_ecdh_curve {{ $cfg.SSLECDHCurve }}; # OK - - # PEM sha: {{ $cfg.DefaultSSLCertificate.PemSHA }} - ssl_certificate {{ $cfg.DefaultSSLCertificate.PemFileName }}; # OK - ssl_certificate_key {{ $cfg.DefaultSSLCertificate.PemFileName }}; # OK - - {{ if and $cfg.CustomHTTPErrors (not $cfg.DisableProxyInterceptErrors) }} - proxy_intercept_errors on; # OK - {{ end }} - - {{ range $errCode := $cfg.CustomHTTPErrors }} - error_page {{ $errCode }} = @custom_upstream-default-backend_{{ $errCode }};{{ end }} # OK - - proxy_ssl_session_reuse on; # OK - - {{ if $cfg.AllowBackendServerHeader }} - proxy_pass_header Server; # OK - {{ end }} - - {{ range $header := $cfg.HideHeaders }}proxy_hide_header {{ $header }}; # OK - {{ end }} - - upstream upstream_balancer { - ### Attention!!! - # - # We no longer create "upstream" section for every backend. - # Backends are handled dynamically using Lua. If you would like to debug - # and see what backends ingress-nginx has in its memory you can - # install our kubectl plugin https://kubernetes.github.io/ingress-nginx/kubectl-plugin. - # Once you have the plugin you can use "kubectl ingress-nginx backends" command to - # inspect current backends. - # - ### - - server 0.0.0.1; # OK - - balancer_by_lua_file /etc/nginx/lua/nginx/ngx_conf_balancer.lua; # OK - - {{ if (gt $cfg.UpstreamKeepaliveConnections 0) }} - keepalive {{ $cfg.UpstreamKeepaliveConnections }}; # OK - keepalive_time {{ $cfg.UpstreamKeepaliveTime }}; # OK - keepalive_timeout {{ $cfg.UpstreamKeepaliveTimeout }}s; # OK - keepalive_requests {{ $cfg.UpstreamKeepaliveRequests }}; # OK - {{ end }} - } - - {{ range $rl := (filterRateLimits $servers ) }} - # Ratelimit {{ $rl.Name }} - geo $remote_addr $allowlist_{{ $rl.ID }} { - default 0; - {{ range $ip := $rl.Allowlist }} - {{ $ip }} 1;{{ end }} - } - - # Ratelimit {{ $rl.Name }} - map $allowlist_{{ $rl.ID }} $limit_{{ $rl.ID }} { - 0 {{ $cfg.LimitConnZoneVariable }}; - 1 ""; - } - {{ end }} - - {{/* build all the required rate limit zones. Each annotation requires a dedicated zone */}} - {{/* 1MB -> 16 thousand 64-byte states or about 8 thousand 128-byte states */}} - {{ range $zone := (buildRateLimitZones $servers) }} - {{ $zone }} - {{ end }} - - # Cache for internal auth checks - proxy_cache_path /tmp/nginx/nginx-cache-auth levels=1:2 keys_zone=auth_cache:10m max_size=128m inactive=30m use_temp_path=off; # OK - - # Global filters - {{ range $ip := $cfg.BlockCIDRs }}deny {{ trimSpace $ip }}; # OK - {{ end }} - - {{ if gt (len $cfg.BlockUserAgents) 0 }} - map $http_user_agent $block_ua { # OK - default 0; # OK - - {{ range $ua := $cfg.BlockUserAgents }}{{ trimSpace $ua }} 1; # OK - {{ end }} - } - {{ end }} - - {{ if gt (len $cfg.BlockReferers) 0 }} - map $http_referer $block_ref { # OK - default 0; # OK - - {{ range $ref := $cfg.BlockReferers }}{{ trimSpace $ref }} 1; # OK - {{ end }} - } - {{ end }} - - {{/* Build server redirects (from/to www) */}} - {{ range $redirect := .RedirectServers }} - ## start server {{ $redirect.From }} - server { #OK - server_name {{ $redirect.From }}; # OK - - {{ buildHTTPListener $all $redirect.From }} # OK - {{ buildHTTPSListener $all $redirect.From }} # OK - - ssl_certificate_by_lua_file /etc/nginx/lua/nginx/ngx_conf_certificate.lua; # OK - - {{ if gt (len $cfg.BlockUserAgents) 0 }} - if ($block_ua) { # OK - return 403; # OK - } - {{ end }} - {{ if gt (len $cfg.BlockReferers) 0 }} - if ($block_ref) { # OK - return 403; #OK - } - {{ end }} - - set_by_lua_file $redirect_to /etc/nginx/lua/nginx/ngx_srv_redirect.lua {{ $redirect.To }}; # OK - - return {{ $all.Cfg.HTTPRedirectCode }} $redirect_to; # OK - } - ## end server {{ $redirect.From }} - {{ end }} - - {{ range $server := $servers }} - {{ range $location := $server.Locations }} - {{ $applyGlobalAuth := shouldApplyGlobalAuth $location $all.Cfg.GlobalExternalAuth.URL }} - {{ $applyAuthUpstream := shouldApplyAuthUpstream $location $all.Cfg }} - {{ if and (eq $applyAuthUpstream true) (eq $applyGlobalAuth false) }} - ## start auth upstream {{ $server.Hostname }}{{ $location.Path }} - upstream {{ buildAuthUpstreamName $location $server.Hostname }} { - {{- $externalAuth := $location.ExternalAuth }} - server {{ extractHostPort $externalAuth.URL }}; - - keepalive {{ $externalAuth.KeepaliveConnections }}; - keepalive_requests {{ $externalAuth.KeepaliveRequests }}; - keepalive_timeout {{ $externalAuth.KeepaliveTimeout }}s; - } - ## end auth upstream {{ $server.Hostname }}{{ $location.Path }} - {{ end }} - {{ end }} - {{ end }} - - {{ range $server := $servers }} - ## start server {{ $server.Hostname }} - server { - server_name {{ buildServerName $server.Hostname }} {{range $server.Aliases }}{{ . }} {{ end }}; OK - - {{ if $cfg.UseHTTP2 }} - http2 on; OK - {{ end }} - - {{ if gt (len $cfg.BlockUserAgents) 0 }} - if ($block_ua) { OK - return 403; OK - } - {{ end }} - {{ if gt (len $cfg.BlockReferers) 0 }} - if ($block_ref) { OK - return 403; OK - } - {{ end }} - - {{ template "SERVER" serverConfig $all $server }} - - {{ template "CUSTOM_ERRORS" (buildCustomErrorDeps "upstream-default-backend" $cfg.CustomHTTPErrors $all.EnableMetrics) }} # OK - } - ## end server {{ $server.Hostname }} - - {{ end }} - - # backend for when default-backend-service is not configured or it does not have endpoints - server { # OK - listen {{ $all.ListenPorts.Default }} default_server {{ if $all.Cfg.ReusePort }}reuseport{{ end }} backlog={{ $all.BacklogSize }}; # OK - {{ if $IsIPV6Enabled }}listen [::]:{{ $all.ListenPorts.Default }} default_server {{ if $all.Cfg.ReusePort }}reuseport{{ end }} backlog={{ $all.BacklogSize }};{{ end }} # OK - set $proxy_upstream_name "internal"; # OK - - access_log off; # OK - - location / { # OK - return 404; # OK - } - } - - # default server, used for NGINX healthcheck and access to nginx stats - server { # OK - - listen 127.0.0.1:{{ .StatusPort }}; # OK - set $proxy_upstream_name "internal"; # OK - - keepalive_timeout 0; # OK - gzip off; # OK - - access_log off; # OK - - {{ if $cfg.EnableOpentelemetry }} - opentelemetry off; # OK - {{ end }} - location {{ $healthzURI }} { # OK - return 200; # OK - } - - location /is-dynamic-lb-initialized { # OK - content_by_lua_file /etc/nginx/lua/nginx/ngx_conf_is_dynamic_lb_initialized.lua; # OK - } - - location {{ .StatusPath }} { # OK - stub_status on; # OK - } - - location /configuration { # OK - client_max_body_size {{ luaConfigurationRequestBodySize $cfg }}; # OK - client_body_buffer_size {{ luaConfigurationRequestBodySize $cfg }}; # OK - proxy_buffering off; # OK - - content_by_lua_file /etc/nginx/lua/nginx/ngx_conf_configuration.lua; # OK - } - - location / { # OK - return 404; # OK - } - } -} - -{{/* definition of templates to avoid repetitions */}} -{{ define "CUSTOM_ERRORS" }} - {{ $enableMetrics := .EnableMetrics }} - {{ $upstreamName := .UpstreamName }} - {{ range $errCode := .ErrorCodes }} - location @custom_{{ $upstreamName }}_{{ $errCode }} { # OK - internal; # OK - proxy_intercept_errors off; # OK - - proxy_set_header X-Code {{ $errCode }}; # OK - proxy_set_header X-Format $http_accept; # OK - proxy_set_header X-Original-URI $request_uri; # OK - proxy_set_header X-Namespace $namespace; # OK - proxy_set_header X-Ingress-Name $ingress_name; # OK - proxy_set_header X-Service-Name $service_name;# OK - proxy_set_header X-Service-Port $service_port; # OK - proxy_set_header X-Request-ID $req_id;# OK - proxy_set_header X-Forwarded-For $remote_addr; # OK - proxy_set_header Host $best_http_host; # OK - - set $proxy_upstream_name {{ $upstreamName | quote }}; # OK - - rewrite (.*) / break; # OK - - proxy_pass http://upstream_balancer; # OK - {{ if $enableMetrics }} - log_by_lua_file /etc/nginx/lua/nginx/ngx_conf_log.lua; # OK - {{ end }} - } - {{ end }} -{{ end }} - -{{/* CORS support from https://michielkalkman.com/snippets/nginx-cors-open-configuration.html */}} -{{ define "CORS" }} - {{ $cors := .CorsConfig }} - # Cors Preflight methods needs additional options and different Return Code - {{ if $cors.CorsAllowOrigin }} - {{ buildCorsOriginRegex $cors.CorsAllowOrigin }} - {{ end }} - if ($request_method = 'OPTIONS') { # OK - set $cors ${cors}options; # OK - } - - if ($cors = "true") { # OK - more_set_headers 'Access-Control-Allow-Origin: $http_origin'; # OK - {{ if $cors.CorsAllowCredentials }} more_set_headers 'Access-Control-Allow-Credentials: {{ $cors.CorsAllowCredentials }}'; {{ end }} # OK - more_set_headers 'Access-Control-Allow-Methods: {{ $cors.CorsAllowMethods }}'; # OK - more_set_headers 'Access-Control-Allow-Headers: {{ $cors.CorsAllowHeaders }}'; # OK - {{ if not (empty $cors.CorsExposeHeaders) }} more_set_headers 'Access-Control-Expose-Headers: {{ $cors.CorsExposeHeaders }}'; {{ end }} # OK - more_set_headers 'Access-Control-Max-Age: {{ $cors.CorsMaxAge }}'; # OK - } - - if ($cors = "trueoptions") { # OK - more_set_headers 'Access-Control-Allow-Origin: $http_origin'; # OK - {{ if $cors.CorsAllowCredentials }} more_set_headers 'Access-Control-Allow-Credentials: {{ $cors.CorsAllowCredentials }}'; {{ end }} # OK - more_set_headers 'Access-Control-Allow-Methods: {{ $cors.CorsAllowMethods }}'; # OK - more_set_headers 'Access-Control-Allow-Headers: {{ $cors.CorsAllowHeaders }}'; # OK - {{ if not (empty $cors.CorsExposeHeaders) }} more_set_headers 'Access-Control-Expose-Headers: {{ $cors.CorsExposeHeaders }}'; {{ end }} # OK - more_set_headers 'Access-Control-Max-Age: {{ $cors.CorsMaxAge }}'; # OK - more_set_headers 'Content-Type: text/plain charset=UTF-8'; # OK - more_set_headers 'Content-Length: 0'; # OK - return 204; # OK - } -{{ end }} - -{{/* definition of server-template to avoid repetitions with server-alias */}} -{{ define "SERVER" }} - {{ $all := .First }} - {{ $server := .Second }} - - {{ buildHTTPListener $all $server.Hostname }} # OK - {{ buildHTTPSListener $all $server.Hostname }} # OK - - set $proxy_upstream_name "-"; # OK - - {{ if not ( empty $server.CertificateAuth.MatchCN ) }} - {{ if gt (len $server.CertificateAuth.MatchCN) 0 }} - if ( $ssl_client_s_dn !~ {{ $server.CertificateAuth.MatchCN }} ) { # OK - return 403 "client certificate unauthorized"; # OK - } - {{ end }} - {{ end }} - - {{ if eq $server.Hostname "_" }} - ssl_reject_handshake {{ if $all.Cfg.SSLRejectHandshake }}on{{ else }}off{{ end }}; # OK - {{ end }} - - ssl_certificate_by_lua_file /etc/nginx/lua/nginx/ngx_conf_certificate.lua; # OK - - {{ if not (empty $server.AuthTLSError) }} - # {{ $server.AuthTLSError }} # NOT, WHERE THIS IF ENDS?? Couldn't reproduce this config on my ingress - return 403; - {{ else }} - - {{ if not (empty $server.CertificateAuth.CAFileName) }} - # PEM sha: {{ $server.CertificateAuth.CASHA }} - ssl_client_certificate {{ $server.CertificateAuth.CAFileName }}; # OK - ssl_verify_client {{ $server.CertificateAuth.VerifyClient }}; # OK - ssl_verify_depth {{ $server.CertificateAuth.ValidationDepth }}; # OK - - {{ if not (empty $server.CertificateAuth.CRLFileName) }} - # PEM sha: {{ $server.CertificateAuth.CRLSHA }} - ssl_crl {{ $server.CertificateAuth.CRLFileName }}; # OK - {{ end }} - - {{ if not (empty $server.CertificateAuth.ErrorPage)}} - error_page 495 496 = {{ $server.CertificateAuth.ErrorPage }}; # OK - {{ end }} - {{ end }} - - {{ if not (empty $server.ProxySSL.CAFileName) }} - # PEM sha: {{ $server.ProxySSL.CASHA }} - proxy_ssl_trusted_certificate {{ $server.ProxySSL.CAFileName }}; # OK - proxy_ssl_ciphers {{ $server.ProxySSL.Ciphers }}; # OK - proxy_ssl_protocols {{ $server.ProxySSL.Protocols }}; # OK - proxy_ssl_verify {{ $server.ProxySSL.Verify }}; # OK - proxy_ssl_verify_depth {{ $server.ProxySSL.VerifyDepth }}; # OK - {{ if not (empty $server.ProxySSL.ProxySSLName) }} - proxy_ssl_name {{ $server.ProxySSL.ProxySSLName }}; # OK - proxy_ssl_server_name {{ $server.ProxySSL.ProxySSLServerName }}; # OK - {{ end }} - {{ end }} - - {{ if not (empty $server.ProxySSL.PemFileName) }} - proxy_ssl_certificate {{ $server.ProxySSL.PemFileName }}; # OK - proxy_ssl_certificate_key {{ $server.ProxySSL.PemFileName }}; # OK - {{ end }} - - {{ if not (empty $server.SSLCiphers) }} - ssl_ciphers {{ $server.SSLCiphers }}; # OK - {{ end }} - - {{ if not (empty $server.SSLPreferServerCiphers) }} - ssl_prefer_server_ciphers {{ $server.SSLPreferServerCiphers }}; # OK - {{ end }} - - {{ range $errorLocation := (buildCustomErrorLocationsPerServer $server) }} # OK - {{ template "CUSTOM_ERRORS" (buildCustomErrorDeps $errorLocation.UpstreamName $errorLocation.Codes $all.EnableMetrics) }} # OK - {{ end }} - - {{ buildMirrorLocations $server.Locations }} # OK - - {{ $enforceRegex := enforceRegexModifier $server.Locations }} # OK - {{ range $location := $server.Locations }} - {{ $path := buildLocation $location $enforceRegex }} # OK - {{ $proxySetHeader := proxySetHeader $location }} # OK - {{ $authPath := buildAuthLocation $location $all.Cfg.GlobalExternalAuth.URL }} # OK - {{ $applyGlobalAuth := shouldApplyGlobalAuth $location $all.Cfg.GlobalExternalAuth.URL }} # OK - {{ $applyAuthUpstream := shouldApplyAuthUpstream $location $all.Cfg }} # OK - - {{ $externalAuth := $location.ExternalAuth }} # OK - {{ if eq $applyGlobalAuth true }} - {{ $externalAuth = $all.Cfg.GlobalExternalAuth }} # OK - {{ end }} - - {{ if not (empty $location.Rewrite.AppRoot) }} - if ($uri = /) { # OK - return 302 $scheme://$http_host{{ $location.Rewrite.AppRoot }}; # OK - } - {{ end }} - - {{ if $authPath }} - location = {{ $authPath }} { - internal; # OK - - {{ if (or $all.Cfg.EnableOpentelemetry $location.Opentelemetry.Enabled) }} - opentelemetry on; # OK - opentelemetry_propagate; # OK - {{ end }} - - {{ if not $all.Cfg.EnableAuthAccessLog }} - access_log off; # OK - {{ end }} - - {{ if $externalAuth.AuthCacheKey }} - set $tmp_cache_key '{{ $server.Hostname }}{{ $authPath }}{{ $externalAuth.AuthCacheKey }}'; # OK - set $cache_key ''; # OK - - rewrite_by_lua_file /etc/nginx/lua/nginx/ngx_conf_rewrite_auth.lua; # OK - - proxy_cache auth_cache; # OK - - {{- range $dur := $externalAuth.AuthCacheDuration }} - proxy_cache_valid {{ $dur }}; # OK - {{- end }} - - proxy_cache_key "$cache_key"; # OK - {{ end }} - - # ngx_auth_request module overrides variables in the parent request, - # therefore we have to explicitly set this variable again so that when the parent request - # resumes it has the correct value set for this variable so that Lua can pick backend correctly - set $proxy_upstream_name {{ buildUpstreamName $location | quote }}; # OK - - proxy_pass_request_body off; # OK - proxy_set_header Content-Length ""; # OK - proxy_set_header X-Forwarded-Proto ""; # OK - proxy_set_header X-Request-ID $req_id; # OK - - {{ if $externalAuth.Method }} - proxy_method {{ $externalAuth.Method }}; - proxy_set_header X-Original-URI $request_uri; # OK - proxy_set_header X-Scheme $pass_access_scheme; # OK - {{ end }} - - proxy_set_header Host {{ $externalAuth.Host }}; # OK - proxy_set_header X-Original-URL $scheme://$http_host$request_uri; # OK - proxy_set_header X-Original-Method $request_method; # OK - proxy_set_header X-Sent-From "nginx-ingress-controller"; # OK - proxy_set_header X-Real-IP $remote_addr; # OK - {{ if and $all.Cfg.UseForwardedHeaders $all.Cfg.ComputeFullForwardedFor }} - proxy_set_header X-Forwarded-For $full_x_forwarded_for; # OK - {{ else }} - proxy_set_header X-Forwarded-For $remote_addr; # OK - {{ end }} - - {{ if $externalAuth.RequestRedirect }} - proxy_set_header X-Auth-Request-Redirect {{ $externalAuth.RequestRedirect }}; # OK - {{ else }} - proxy_set_header X-Auth-Request-Redirect $request_uri; # OK - {{ end }} - - {{ if $externalAuth.AuthCacheKey }} - proxy_buffering "on"; # OK - {{ else }} - proxy_buffering {{ $location.Proxy.ProxyBuffering }}; # OK - {{ end }} - proxy_buffer_size {{ $location.Proxy.BufferSize }}; # OK - proxy_buffers {{ $location.Proxy.BuffersNumber }} {{ $location.Proxy.BufferSize }}; # OK - proxy_request_buffering {{ $location.Proxy.RequestBuffering }}; # OK - - proxy_ssl_server_name on; # OK - proxy_pass_request_headers on; # OK - {{ if isValidByteSize $location.Proxy.BodySize true }} - client_max_body_size {{ $location.Proxy.BodySize }}; # OK - {{ end }} - {{ if isValidByteSize $location.ClientBodyBufferSize false }} - client_body_buffer_size {{ $location.ClientBodyBufferSize }}; # OK - {{ end }} - - # Pass the extracted client certificate to the auth provider - {{ if not (empty $server.CertificateAuth.CAFileName) }} - {{ if $server.CertificateAuth.PassCertToUpstream }} - proxy_set_header ssl-client-cert $ssl_client_escaped_cert; # OK - {{ end }} - proxy_set_header ssl-client-verify $ssl_client_verify; # OK - proxy_set_header ssl-client-subject-dn $ssl_client_s_dn; # OK - proxy_set_header ssl-client-issuer-dn $ssl_client_i_dn; # OK - {{ end }} - - {{- range $line := buildAuthProxySetHeaders $externalAuth.ProxySetHeaders}} - {{ $line }} # OK - {{- end }} - - {{ if and (eq $applyAuthUpstream true) (eq $applyGlobalAuth false) }} - {{ $authUpstreamName := buildAuthUpstreamName $location $server.Hostname }} - # The target is an upstream with HTTP keepalive, that is why the - # Connection header is cleared and the HTTP version is set to 1.1 as - # the Nginx documentation suggests: - # http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive - proxy_http_version 1.1; # OK - proxy_set_header Connection ""; # OK - set $target {{ changeHostPort $externalAuth.URL $authUpstreamName }}; # OK - {{ else }} - proxy_http_version {{ $location.Proxy.ProxyHTTPVersion }}; # OK - set $target {{ $externalAuth.URL }}; # OK - {{ end }} - proxy_pass $target; # OK - } - {{ end }} - - {{ if isLocationAllowed $location }} - {{ if $externalAuth.SigninURL }} - location {{ buildAuthSignURLLocation $location.Path $externalAuth.SigninURL }} { - internal; # OK - - add_header Set-Cookie $auth_cookie; # OK - - {{ if $location.CorsConfig.CorsEnabled }} - {{ template "CORS" $location }} # OK - {{ end }} - - return 302 {{ buildAuthSignURL $externalAuth.SigninURL $externalAuth.SigninURLRedirectParam }}; # OK - } - {{ end }} - {{ end }} - - location {{ $path }} { - {{ $ing := (getIngressInformation $location.Ingress $server.Hostname $location.IngressPath) }} - set $namespace {{ $ing.Namespace | quote}}; # OK - set $ingress_name {{ $ing.Rule | quote }}; # OK - set $service_name {{ $ing.Service | quote }}; # OK - set $service_port {{ $ing.ServicePort | quote }}; # OK - set $location_path {{ $ing.Path | escapeLiteralDollar | quote }}; # OK - - {{ buildOpentelemetryForLocation $all.Cfg.EnableOpentelemetry $all.Cfg.OpentelemetryTrustIncomingSpan $location }} # OK - - {{ if $location.Mirror.Source }} - mirror {{ $location.Mirror.Source }}; # OK - mirror_request_body {{ $location.Mirror.RequestBody }}; # OK - {{ end }} - - {{ locationConfigForLua $location $all }} # OK - - rewrite_by_lua_file /etc/nginx/lua/nginx/ngx_rewrite.lua; # OK - - header_filter_by_lua_file /etc/nginx/lua/nginx/ngx_conf_srv_hdr_filter.lua; # OK - - log_by_lua_file /etc/nginx/lua/nginx/ngx_conf_log_block.lua; # OK - - {{ if not $location.Logs.Access }} - access_log off; # OK - {{ end }} - - {{ if $location.Logs.Rewrite }} - rewrite_log on; # OK - {{ end }} - - {{ if $location.HTTP2PushPreload }} - http2_push_preload on; # OK - {{ end }} - - port_in_redirect {{ if $location.UsePortInRedirects }}on{{ else }}off{{ end }}; # OK - - set $balancer_ewma_score -1; # OK - set $proxy_upstream_name {{ buildUpstreamName $location | quote }}; # OK - set $proxy_host $proxy_upstream_name; # OK - set $pass_access_scheme $scheme; # OK - - {{ if $all.Cfg.UseProxyProtocol }} - set $pass_server_port $proxy_protocol_server_port; # OK - {{ else }} - set $pass_server_port $server_port; # OK - {{ end }} - - set $best_http_host $http_host; # OK - set $pass_port $pass_server_port; # OK - - set $proxy_alternative_upstream_name ""; # OK - - {{ if isLocationAllowed $location }} # 1 - {{ if gt (len $location.Denylist.CIDR) 0 }} # 2 - {{ range $ip := $location.Denylist.CIDR }} # 3 - deny {{ $ip }};{{ end }} # 2 # OK - {{ end }} # 1 - {{ if gt (len $location.Allowlist.CIDR) 0 }} # 2 - {{ range $ip := $location.Allowlist.CIDR }} # 3 - allow {{ $ip }};{{ end }} # 2 # OK - deny all; # OK - {{ end }} # 1 - - {{ if $location.CorsConfig.CorsEnabled }} # 2 - {{ template "CORS" $location }} # OK - {{ end }} # 1 - - {{ if not (isLocationInLocationList $location $all.Cfg.NoAuthLocations) }} # 2 - {{ if $authPath }} # 3 - # this location requires authentication - {{ if and (eq $applyAuthUpstream true) (eq $applyGlobalAuth false) }} # 4 - set $auth_cookie ''; - add_header Set-Cookie $auth_cookie; - {{- range $line := buildAuthResponseHeaders $proxySetHeader $externalAuth.ResponseHeaders true }} # 5 - {{ $line }} - {{- end }} # 4 - # `auth_request` module does not support HTTP keepalives in upstream block: - # https://trac.nginx.org/nginx/ticket/1579 - access_by_lua_block { - local res = ngx.location.capture('{{ $authPath }}', { method = ngx.HTTP_GET, body = '', share_all_vars = {{ $externalAuth.KeepaliveShareVars }} }) - if res.status == ngx.HTTP_OK then - ngx.var.auth_cookie = res.header['Set-Cookie'] - {{- range $line := buildAuthUpstreamLuaHeaders $externalAuth.ResponseHeaders }} - {{ $line }} - {{- end }} - return - end - if res.status == ngx.HTTP_UNAUTHORIZED or res.status == ngx.HTTP_FORBIDDEN then - ngx.exit(res.status) - end - ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) - } - {{ else }} - auth_request {{ $authPath }}; - auth_request_set $auth_cookie $upstream_http_set_cookie; - {{ if $externalAuth.AlwaysSetCookie }} # 5 - add_header Set-Cookie $auth_cookie always; - {{ else }} - add_header Set-Cookie $auth_cookie; - {{ end }} # 4 - {{- range $line := buildAuthResponseHeaders $proxySetHeader $externalAuth.ResponseHeaders false }} # 5 - {{ $line }} - {{- end }} # 4 - {{ end }} # 3 - {{ end }} # 2 - - {{ if $externalAuth.SigninURL }} # 3 - set_escape_uri $escaped_request_uri $request_uri; - error_page 401 = {{ buildAuthSignURLLocation $location.Path $externalAuth.SigninURL }}; - {{ end }} # 2 - - {{ if $location.BasicDigestAuth.Secured }} # 3 - {{ if eq $location.BasicDigestAuth.Type "basic" }} # 4 - auth_basic {{ $location.BasicDigestAuth.Realm | quote }}; - auth_basic_user_file {{ $location.BasicDigestAuth.File }}; - {{ else }} - auth_digest {{ $location.BasicDigestAuth.Realm | quote }}; - auth_digest_user_file {{ $location.BasicDigestAuth.File }}; - {{ end }} # 3 - {{ $proxySetHeader }} Authorization ""; - {{ end }} # 2 - {{ end }} # 1 - - {{/* if the location contains a rate limit annotation, create one */}} - {{ $limits := buildRateLimit $location }} - {{ range $limit := $limits }} # 2 # OK - {{ $limit }}{{ end }} # 1 - - {{ if isValidByteSize $location.Proxy.BodySize true }} - client_max_body_size {{ $location.Proxy.BodySize }}; # OK - {{ end }} - {{ if isValidByteSize $location.ClientBodyBufferSize false }} - client_body_buffer_size {{ $location.ClientBodyBufferSize }}; # OK - {{ end }} # 1 - - {{/* By default use vhost as Host to upstream, but allow overrides */}} - {{ if not (empty $location.UpstreamVhost) }} - {{ $proxySetHeader }} Host {{ $location.UpstreamVhost | quote }}; # OK - {{ else }} - {{ $proxySetHeader }} Host $best_http_host; # OK - {{ end }} # 1 - - # Pass the extracted client certificate to the backend - {{ if not (empty $server.CertificateAuth.CAFileName) }} # 2 - {{ if $server.CertificateAuth.PassCertToUpstream }} # 3 - {{ $proxySetHeader }} ssl-client-cert $ssl_client_escaped_cert; # OK - {{ end }} # 2 - {{ $proxySetHeader }} ssl-client-verify $ssl_client_verify; # OK - {{ $proxySetHeader }} ssl-client-subject-dn $ssl_client_s_dn; # OK - {{ $proxySetHeader }} ssl-client-issuer-dn $ssl_client_i_dn; # OK - {{ end }} # 1 - - # Allow websocket connections - {{ $proxySetHeader }} Upgrade $http_upgrade; # OK - {{ if $location.Connection.Enabled}} - {{ $proxySetHeader }} Connection {{ $location.Connection.Header }}; # OK - {{ else }} - {{ $proxySetHeader }} Connection $connection_upgrade; # OK - {{ end }} - - {{ $proxySetHeader }} X-Request-ID $req_id; # OK - {{ $proxySetHeader }} X-Real-IP $remote_addr; # OK - {{ if and $all.Cfg.UseForwardedHeaders $all.Cfg.ComputeFullForwardedFor }} - {{ $proxySetHeader }} X-Forwarded-For $full_x_forwarded_for; # OK - {{ else }} - {{ $proxySetHeader }} X-Forwarded-For $remote_addr; # OK - {{ end }} # 1 - {{ $proxySetHeader }} X-Forwarded-Host $best_http_host; # OK - {{ $proxySetHeader }} X-Forwarded-Port $pass_port; # OK - {{ $proxySetHeader }} X-Forwarded-Proto $pass_access_scheme; # OK - {{ $proxySetHeader }} X-Forwarded-Scheme $pass_access_scheme; # OK - {{ if $all.Cfg.ProxyAddOriginalURIHeader }} - {{ $proxySetHeader }} X-Original-URI $request_uri; # OK - {{ end }} # 1 - {{ $proxySetHeader }} X-Scheme $pass_access_scheme; # OK - - # Pass the original X-Forwarded-For - {{ $proxySetHeader }} X-Original-Forwarded-For {{ buildForwardedFor $all.Cfg.ForwardedForHeader }}; # OK - - # mitigate HTTPoxy Vulnerability - # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/ - {{ $proxySetHeader }} Proxy ""; # OK - - # Custom headers to proxied server - {{ range $k, $v := $all.ProxySetHeaders }} - {{ $proxySetHeader }} {{ $k }} {{ $v | quote }}; # OK - {{ end }} # 1 - - proxy_connect_timeout {{ $location.Proxy.ConnectTimeout }}s; OK - proxy_send_timeout {{ $location.Proxy.SendTimeout }}s; # OK - proxy_read_timeout {{ $location.Proxy.ReadTimeout }}s; # OK - - proxy_buffering {{ $location.Proxy.ProxyBuffering }}; # OK - proxy_buffer_size {{ $location.Proxy.BufferSize }}; # OK - proxy_buffers {{ $location.Proxy.BuffersNumber }} {{ $location.Proxy.BufferSize }}; # OK - {{ if isValidByteSize $location.Proxy.ProxyMaxTempFileSize true }} - proxy_max_temp_file_size {{ $location.Proxy.ProxyMaxTempFileSize }}; # OK - {{ end }} - proxy_request_buffering {{ $location.Proxy.RequestBuffering }}; # OK - proxy_http_version {{ $location.Proxy.ProxyHTTPVersion }}; # OK - - proxy_cookie_domain {{ $location.Proxy.CookieDomain }}; # OK - proxy_cookie_path {{ $location.Proxy.CookiePath }}; # OK - - # In case of errors try the next upstream server before returning an error - proxy_next_upstream {{ buildNextUpstream $location.Proxy.NextUpstream $all.Cfg.RetryNonIdempotent }}; # OK - proxy_next_upstream_timeout {{ $location.Proxy.NextUpstreamTimeout }}; # OK - proxy_next_upstream_tries {{ $location.Proxy.NextUpstreamTries }}; # OK - - {{ if or (eq $location.BackendProtocol "GRPC") (eq $location.BackendProtocol "GRPCS") }} - # Grpc settings - grpc_connect_timeout {{ $location.Proxy.ConnectTimeout }}s; # OK - grpc_send_timeout {{ $location.Proxy.SendTimeout }}s; # OK - grpc_read_timeout {{ $location.Proxy.ReadTimeout }}s; # OK - {{ end }} # 1 - - - {{ if $location.CustomHeaders }} # 2 - # Custom Response Headers - {{ range $k, $v := $location.CustomHeaders.Headers }} # 3 - more_set_headers {{ printf "%s: %s" $k $v | escapeLiteralDollar | quote }}; # OK - {{ end }} # 2 - {{ end }} # 1 - - {{/* if we are sending the request to a custom default backend, we add the required headers */}} - {{ if (hasPrefix $location.Backend "custom-default-backend-") }} - proxy_set_header X-Code 503; # OK - proxy_set_header X-Format $http_accept; # OK - proxy_set_header X-Namespace $namespace; # OK - proxy_set_header X-Ingress-Name $ingress_name; # OK - proxy_set_header X-Service-Name $service_name; # OK - proxy_set_header X-Service-Port $service_port; # OK - proxy_set_header X-Request-ID $req_id; # OK - {{ end }} # 1 - - {{ if $location.Satisfy }} - satisfy {{ $location.Satisfy }}; # OK - {{ end }} # 1 - - {{/* if a location-specific error override is set, add the proxy_intercept here */}} - {{ if and $location.CustomHTTPErrors (not $location.DisableProxyInterceptErrors) }} - # Custom error pages per ingress - proxy_intercept_errors on; # OK - {{ end }} # 1 - - {{ range $errCode := $location.CustomHTTPErrors }} - error_page {{ $errCode }} = @custom_{{ $location.DefaultBackendUpstreamName }}_{{ $errCode }};{{ end }} # OK - - {{ if (eq $location.BackendProtocol "FCGI") }} - include /etc/nginx/fastcgi_params; OK - {{ end }} # 1 - {{- if $location.FastCGI.Index -}} - fastcgi_index {{ $location.FastCGI.Index | quote }}; # OK - {{- end -}} # 1 - {{ range $k, $v := $location.FastCGI.Params }} - fastcgi_param {{ $k }} {{ $v | quote }}; # OK - {{ end }} # 1 - - {{ if not (empty $location.Redirect.URL) }} - return {{ $location.Redirect.Code }} {{ $location.Redirect.URL }}; # OK - {{ end }} # 1 - - {{ buildProxyPass $server.Hostname $all.Backends $location }} # OK - {{ if (or (eq $location.Proxy.ProxyRedirectFrom "default") (eq $location.Proxy.ProxyRedirectFrom "off")) }} - proxy_redirect {{ $location.Proxy.ProxyRedirectFrom }}; # OK - {{ else if not (eq $location.Proxy.ProxyRedirectTo "off") }} - proxy_redirect {{ $location.Proxy.ProxyRedirectFrom }} {{ $location.Proxy.ProxyRedirectTo }}; # OK - {{ end }} # 1 - {{ else }} - # Location denied. Reason: {{ $location.Denied | quote }} # OK - return 503; # OK - {{ end }} # 0 - {{ if not (empty $location.ProxySSL.CAFileName) }} # 1 - # PEM sha: {{ $location.ProxySSL.CASHA }} # OK - proxy_ssl_trusted_certificate {{ $location.ProxySSL.CAFileName }}; # OK - proxy_ssl_ciphers {{ $location.ProxySSL.Ciphers }}; # OK - proxy_ssl_protocols {{ $location.ProxySSL.Protocols }}; # OK - proxy_ssl_verify {{ $location.ProxySSL.Verify }}; # OK - proxy_ssl_verify_depth {{ $location.ProxySSL.VerifyDepth }}; # OK - {{ end }} # 0 - - {{ if not (empty $location.ProxySSL.ProxySSLName) }} # 1 - proxy_ssl_name {{ $location.ProxySSL.ProxySSLName }}; # OK - {{ end }} # 0 - {{ if not (empty $location.ProxySSL.ProxySSLServerName) }} # 1 - proxy_ssl_server_name {{ $location.ProxySSL.ProxySSLServerName }}; # OK - {{ end }} # 0 - - {{ if not (empty $location.ProxySSL.PemFileName) }} # 1 - proxy_ssl_certificate {{ $location.ProxySSL.PemFileName }}; # OK - proxy_ssl_certificate_key {{ $location.ProxySSL.PemFileName }}; # OK - {{ end }} # 0 - } - {{ end }} # End range - {{ end }} # Maybe that missing if... - - {{ if eq $server.Hostname "_" }} - # health checks in cloud providers require the use of port {{ $all.ListenPorts.HTTP }} - location {{ $all.HealthzURI }} { # OK - - {{ if $all.Cfg.EnableOpentelemetry }} - opentelemetry off; # OK - {{ end }} - - access_log off; # OK - return 200; # OK - } - - # this is required to avoid error if nginx is being monitored - # with an external software (like sysdig) - location /nginx_status { - - {{ if $all.Cfg.EnableOpentelemetry }} - opentelemetry off; # OK - {{ end }} - - {{ range $v := $all.NginxStatusIpv4Whitelist }} - allow {{ $v }}; # OK - {{ end }} - {{ if $all.IsIPV6Enabled -}} - {{ range $v := $all.NginxStatusIpv6Whitelist }} - allow {{ $v }}; # OK - {{ end }} - {{ end -}} - deny all; # OK - - access_log off; # OK - stub_status on; # OK - } - - {{ end }} - -{{ end }}