diff --git a/configuration.md b/configuration.md index fd0edaa78..8001c2b78 100644 --- a/configuration.md +++ b/configuration.md @@ -568,6 +568,7 @@ Default: "" **location-snippet:** adds custom configuration to all the locations in the nginx configuration Default: "" +**compute-full-forwarded-for:** Append the remote address to the X-Forwarded-For header instead of replacing it. When this option is enabled, the upstream application is responsible for extracting the client IP based on its own list of trusted proxies. ### Default configuration options @@ -625,6 +626,7 @@ The following table shows the options, the default value and a description. |worker-processes|number of CPUs| |limit-conn-zone-variable|$binary_remote_addr| |bind-address|| +|compute-full-forwarded-for|"false"| ### Websockets diff --git a/pkg/nginx/config/config.go b/pkg/nginx/config/config.go index 0d9a6f165..4f363f297 100644 --- a/pkg/nginx/config/config.go +++ b/pkg/nginx/config/config.go @@ -378,6 +378,10 @@ type Configuration struct { // Default is X-Forwarded-For ForwardedForHeader string `json:"forwarded-for-header,omitempty"` + // Append the remote address to the X-Forwarded-For header instead of replacing it + // Default: false + ComputeFullForwardedFor bool `json:"compute-full-forwarded-for,omitempty"` + // EnableOpentracing enables the nginx Opentracing extension // https://github.com/rnburn/nginx-opentracing // By default this is disabled @@ -420,6 +424,7 @@ func NewDefault() Configuration { EnableUnderscoresInHeaders: false, ErrorLogLevel: errorLevel, ForwardedForHeader: "X-Forwarded-For", + ComputeFullForwardedFor: false, HTTP2MaxFieldSize: "4k", HTTP2MaxHeaderSize: "16k", HSTS: true, diff --git a/rootfs/etc/nginx/template/nginx.tmpl b/rootfs/etc/nginx/template/nginx.tmpl index c12a27b8a..81a124de1 100644 --- a/rootfs/etc/nginx/template/nginx.tmpl +++ b/rootfs/etc/nginx/template/nginx.tmpl @@ -195,12 +195,14 @@ http { '' $host; } + {{ if $cfg.ComputeFullForwardedFor }} # We can't use $proxy_add_x_forwarded_for because the realip module # replaces the remote_addr to soon - map $http_x_forwarded_for $the_real_x_forwarded_for { + map $http_x_forwarded_for $full_x_forwarded_for { default "$http_x_forwarded_for, $realip_remote_addr"; '' "$realip_remote_addr"; } + {{ end }} server_name_in_redirect off; port_in_redirect off; @@ -756,7 +758,11 @@ stream { proxy_set_header Connection $connection_upgrade; proxy_set_header X-Real-IP $the_real_ip; - proxy_set_header X-Forwarded-For $the_real_x_forwarded_for; + {{ if $all.Cfg.ComputeFullForwardedFor }} + proxy_set_header X-Forwarded-For $full_x_forwarded_for; + {{ else }} + proxy_set_header X-Forwarded-For $the_real_ip; + {{ end }} proxy_set_header X-Forwarded-Host $best_http_host; proxy_set_header X-Forwarded-Port $pass_port; proxy_set_header X-Forwarded-Proto $pass_access_scheme;