From 2cdfa1cae18eb62095e4b6629d052484822c46d6 Mon Sep 17 00:00:00 2001 From: Bjorn Post Date: Mon, 18 Jan 2021 20:07:55 +0100 Subject: [PATCH 1/6] feat: trust proxy_add_x_forwarded_for iso resetting to remote_addr, refs #4339 --- docs/configuration/ssl.md | 39 +------------------ .../nginx-vhosts/templates/nginx.conf.sigil | 4 +- tests/unit/test_helper.bash | 4 +- 3 files changed, 6 insertions(+), 41 deletions(-) diff --git a/docs/configuration/ssl.md b/docs/configuration/ssl.md index 5455ce56a..bf4411968 100644 --- a/docs/configuration/ssl.md +++ b/docs/configuration/ssl.md @@ -136,44 +136,9 @@ Certain versions of nginx have bugs that prevent [HTTP/2](https://nginx.org/en/d Your application has access to the HTTP headers `X-Forwarded-Proto`, `X-Forwarded-Port` and `X-Forwarded-For`. These headers indicate the protocol of the original request (HTTP or HTTPS), the port number, and the IP address of the client making the request, respectively. The default configuration is for Nginx to set these headers. -If your server runs behind an HTTP(S) load balancer, then Nginx will see all requests as coming from the load balancer. If your load balancer sets the `X-Forwarded-` headers, you can tell Nginx to pass these headers from load balancer to your application by using a [custom nginx template](/docs/configuration/nginx.md#customizing-the-nginx-configuration). The following is a simple example of how to do so. +By default, Dokku will append the IP address of the Nginx server to the `X-Forwarded-For`. To your application, `X-Forwarded-For` will contain a list of the IP address of the client making the request, any intermediate load balancer and the Nginx IP address. -```go -server { - listen [::]:{{ .PROXY_PORT }}; - listen {{ .PROXY_PORT }}; - server_name {{ .NOSSL_SERVER_NAME }}; - access_log /var/log/nginx/{{ .APP }}-access.log; - error_log /var/log/nginx/{{ .APP }}-error.log; - - location / { - proxy_pass http://{{ .APP }}; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $http_connection; - proxy_set_header Host $http_host; - proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; - proxy_set_header X-Forwarded-For $http_x_forwarded_for; - proxy_set_header X-Forwarded-Port $http_x_forwarded_port; - proxy_set_header X-Request-Start $msec; - } - include {{ .DOKKU_ROOT }}/{{ .APP }}/nginx.conf.d/*.conf; -} - -upstream {{ .APP }} { -{{ range .DOKKU_APP_WEB_LISTENERS | split " " }} - server {{ . }}; -{{ end }} -} -``` - -Only use this option if: -1. All requests are terminated at the load balancer, and forwarded to Nginx -2. The load balancer is configured to send the `X-Forwarded-` headers (this may be off by default) - -If it's possible to make HTTP(S) requests directly to Nginx, bypassing the load balancer, or if the load balancer is not configured to set these headers, then it becomes possible for a client to set these headers to arbitrary values. - -This could result in security issue, for example, if your application looks at the value of the `X-Forwarded-Proto` to determine if the request was made over HTTPS. +If you do not want this behavior, you can create a [custom nginx template](/docs/configuration/nginx.md#customizing-the-nginx-configuration) that resets the `X-Forwarded-For` header to a specific value (i.e. `$remote_addr`). ### SSL Port Exposure diff --git a/plugins/nginx-vhosts/templates/nginx.conf.sigil b/plugins/nginx-vhosts/templates/nginx.conf.sigil index a195a0a17..27e3e1d39 100644 --- a/plugins/nginx-vhosts/templates/nginx.conf.sigil +++ b/plugins/nginx-vhosts/templates/nginx.conf.sigil @@ -34,7 +34,7 @@ server { proxy_set_header Connection $http_connection; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header X-Request-Start $msec; } @@ -97,7 +97,7 @@ server { proxy_set_header Connection $http_connection; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header X-Request-Start $msec; } diff --git a/tests/unit/test_helper.bash b/tests/unit/test_helper.bash index 8d693fd9d..c6c49683b 100644 --- a/tests/unit/test_helper.bash +++ b/tests/unit/test_helper.bash @@ -406,7 +406,7 @@ server { proxy_set_header Connection \$http_connection; proxy_set_header Host \$http_host; proxy_set_header X-Forwarded-Proto \$scheme; - proxy_set_header X-Forwarded-For \$remote_addr; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Port \$server_port; proxy_set_header X-Request-Start \$msec; } @@ -453,7 +453,7 @@ server { proxy_set_header Connection "upgrade"; proxy_set_header Host \$http_host; proxy_set_header X-Forwarded-Proto \$scheme; - proxy_set_header X-Forwarded-For \$remote_addr; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Port \$server_port; proxy_set_header X-Request-Start \$msec; } From 7cd6f7666c258d0aaa688da5cabd9b0d28191bfd Mon Sep 17 00:00:00 2001 From: Bjorn Post Date: Mon, 18 Jan 2021 21:09:00 +0100 Subject: [PATCH 2/6] feat: configure trust x-forwarded-for headers via nginx:set iso trust by default, refs #4339 --- docs/configuration/ssl.md | 7 +++++-- plugins/nginx-vhosts/functions | 5 ++++- plugins/nginx-vhosts/templates/nginx.conf.sigil | 4 ++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/docs/configuration/ssl.md b/docs/configuration/ssl.md index bf4411968..e9b1769de 100644 --- a/docs/configuration/ssl.md +++ b/docs/configuration/ssl.md @@ -136,9 +136,12 @@ Certain versions of nginx have bugs that prevent [HTTP/2](https://nginx.org/en/d Your application has access to the HTTP headers `X-Forwarded-Proto`, `X-Forwarded-Port` and `X-Forwarded-For`. These headers indicate the protocol of the original request (HTTP or HTTPS), the port number, and the IP address of the client making the request, respectively. The default configuration is for Nginx to set these headers. -By default, Dokku will append the IP address of the Nginx server to the `X-Forwarded-For`. To your application, `X-Forwarded-For` will contain a list of the IP address of the client making the request, any intermediate load balancer and the Nginx IP address. +If your server runs behind an HTTP(S) load balancer, then Nginx will see all requests as coming from the load balancer. If your load balancer sets the `X-Forwarded-` headers, you can tell Nginx to pass these headers from load balancer to your application via `nginx:set`: -If you do not want this behavior, you can create a [custom nginx template](/docs/configuration/nginx.md#customizing-the-nginx-configuration) that resets the `X-Forwarded-For` header to a specific value (i.e. `$remote_addr`). +```shell +dokku nginx:set node-js-app trust-x-forwarded-for true +dokku nginx:set node-js-app trust-x-forwarded-for false +``` ### SSL Port Exposure diff --git a/plugins/nginx-vhosts/functions b/plugins/nginx-vhosts/functions index 23c60b27a..47e91d133 100755 --- a/plugins/nginx-vhosts/functions +++ b/plugins/nginx-vhosts/functions @@ -462,6 +462,8 @@ nginx_build_config() { local NGINX_BIND_ADDRESS_IP6="$(fn-plugin-property-get-default "nginx" "$APP" "bind-address-ipv6" "::")" [[ -z "$NGINX_BIND_ADDRESS_IP6" ]] && NGINX_BIND_ADDRESS_IP6="::" + local PROXY_TRUST_X_FORWARDED_FOR="$(fn-plugin-property-get-default "nginx" "$APP" "trust-x-forwarded-for" "false")" + eval "$(config_export app "$APP")" local SIGIL_PARAMS=(-f "$NGINX_TEMPLATE" APP="$APP" DOKKU_ROOT="$DOKKU_ROOT" NOSSL_SERVER_NAME="$NOSSL_SERVER_NAME" @@ -490,7 +492,8 @@ nginx_build_config() { # Deprecated: Remove this after a few versions NGINX_PORT="$PROXY_PORT" NGINX_SSL_PORT="$PROXY_SSL_PORT" PROXY_PORT="$PROXY_PORT" PROXY_SSL_PORT="$PROXY_SSL_PORT" RAW_TCP_PORTS="$RAW_TCP_PORTS" - PROXY_PORT_MAP="$PROXY_PORT_MAP" PROXY_UPSTREAM_PORTS="$PROXY_UPSTREAM_PORTS") + PROXY_PORT_MAP="$PROXY_PORT_MAP" PROXY_UPSTREAM_PORTS="$PROXY_UPSTREAM_PORTS" + PROXY_TRUST_X_FORWARDED_FOR="$PROXY_TRUST_X_FORWARDED_FOR") local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE" while read -r line || [[ -n "$line" ]]; do diff --git a/plugins/nginx-vhosts/templates/nginx.conf.sigil b/plugins/nginx-vhosts/templates/nginx.conf.sigil index 27e3e1d39..3c3e3a619 100644 --- a/plugins/nginx-vhosts/templates/nginx.conf.sigil +++ b/plugins/nginx-vhosts/templates/nginx.conf.sigil @@ -34,7 +34,7 @@ server { proxy_set_header Connection $http_connection; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-For {{ if $.PROXY_TRUST_X_FORWARDED_FOR eq "true" }}$proxy_add_x_forwarded_for{{ else }}$remote_addr{{ end }}; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header X-Request-Start $msec; } @@ -97,7 +97,7 @@ server { proxy_set_header Connection $http_connection; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-For {{ if $.PROXY_TRUST_X_FORWARDED_FOR eq "true" }}$proxy_add_x_forwarded_for{{ else }}$remote_addr{{ end }}; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header X-Request-Start $msec; } From bdb160bec1374532a5595b8bd778147a970c7913 Mon Sep 17 00:00:00 2001 From: Bjorn Post Date: Mon, 18 Jan 2021 21:58:45 +0100 Subject: [PATCH 3/6] feat: add trust-x-forwarded-for status in report, refs #4339 --- plugins/nginx-vhosts/command-functions | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/nginx-vhosts/command-functions b/plugins/nginx-vhosts/command-functions index 1fda16313..21a19c29f 100755 --- a/plugins/nginx-vhosts/command-functions +++ b/plugins/nginx-vhosts/command-functions @@ -54,6 +54,7 @@ cmd-nginx-report-single() { "--nginx-proxy-busy-buffers-size: $(fn-nginx-proxy-busy-buffers-size "$APP")" "--nginx-proxy-read-timeout: $(fn-nginx-proxy-read-timeout "$APP")" "--nginx-last-visited-at: $(fn-nginx-vhosts-last-visited-at "$APP")" + "--nginx-trust-x-forwarded-for: $(fn-plugin-property-get-default "nginx" "$APP" "trust-x-forwarded-for" "")" ) if [[ -z "$INFO_FLAG" ]]; then From 7c818eda47c40bd0894e059c9b0534804dc03790 Mon Sep 17 00:00:00 2001 From: Bjorn Post Date: Mon, 18 Jan 2021 21:59:36 +0100 Subject: [PATCH 4/6] test: add tests for trust-x-forwarded-for, refs #4339 --- tests/unit/nginx-vhosts_6.bats | 47 ++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/unit/nginx-vhosts_6.bats b/tests/unit/nginx-vhosts_6.bats index 0ff29f4e5..5232f3222 100644 --- a/tests/unit/nginx-vhosts_6.bats +++ b/tests/unit/nginx-vhosts_6.bats @@ -156,6 +156,53 @@ teardown() { assert_output_contains "127.0.0.1:80;" 0 } +@test "(nginx-vhosts) nginx:set trust-x-forwarded-for" { + run deploy_app + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku nginx:build-config $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku nginx:show-config $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_output_contains "X-Forwarded-For $remote_addr;" + + run /bin/bash -c "dokku nginx:set $TEST_APP trust-x-forwarded-for true" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku nginx:build-config $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku nginx:show-config $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_output_contains "X-Forwarded-For $proxy_add_x_forwarded_for;" + + run /bin/bash -c "dokku nginx:set $TEST_APP trust-x-forwarded-for false" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku nginx:build-config $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku nginx:show-config $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_output_contains "X-Forwarded-For $remote_addr;" +} + @test "(nginx-vhosts) nginx:validate-config" { deploy_app run /bin/bash -c "dokku nginx:validate-config" From ca56fa1b8b9714d47d35cd7a3302d0f25f00af89 Mon Sep 17 00:00:00 2001 From: Bjorn Post Date: Mon, 18 Jan 2021 22:00:13 +0100 Subject: [PATCH 5/6] fix: revert doc deletion, revert test_helper change, refs #4339 --- docs/configuration/ssl.md | 6 ++++++ tests/unit/test_helper.bash | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/configuration/ssl.md b/docs/configuration/ssl.md index e9b1769de..bfb9409bc 100644 --- a/docs/configuration/ssl.md +++ b/docs/configuration/ssl.md @@ -143,6 +143,12 @@ dokku nginx:set node-js-app trust-x-forwarded-for true dokku nginx:set node-js-app trust-x-forwarded-for false ``` +Only use this option if: +1. All requests are terminated at the load balancer, and forwarded to Nginx +2. The load balancer is configured to send the `X-Forwarded-` headers (this may be off by default) + +If it's possible to make HTTP(S) requests directly to Nginx, bypassing the load balancer, or if the load balancer is not configured to set these headers, then it becomes possible for a client to set these headers to arbitrary values. + ### SSL Port Exposure When your app is served from port `80` then the `/home/dokku/APP/nginx.conf` file will automatically be updated to instruct nginx to respond to ssl on port 443 as a new cert is added. If your app uses a non-standard port (perhaps you have a dockerfile deploy exposing port `99999`) you may need to manually expose an ssl port via `dokku proxy:ports-add https:443:99999`. diff --git a/tests/unit/test_helper.bash b/tests/unit/test_helper.bash index c6c49683b..8d693fd9d 100644 --- a/tests/unit/test_helper.bash +++ b/tests/unit/test_helper.bash @@ -406,7 +406,7 @@ server { proxy_set_header Connection \$http_connection; proxy_set_header Host \$http_host; proxy_set_header X-Forwarded-Proto \$scheme; - proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-For \$remote_addr; proxy_set_header X-Forwarded-Port \$server_port; proxy_set_header X-Request-Start \$msec; } @@ -453,7 +453,7 @@ server { proxy_set_header Connection "upgrade"; proxy_set_header Host \$http_host; proxy_set_header X-Forwarded-Proto \$scheme; - proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-For \$remote_addr; proxy_set_header X-Forwarded-Port \$server_port; proxy_set_header X-Request-Start \$msec; } From a6062d4ab4c28758c29c397301f0dc52cfa7af07 Mon Sep 17 00:00:00 2001 From: Bjorn Post Date: Tue, 19 Jan 2021 21:40:47 +0100 Subject: [PATCH 6/6] feat: make feature more generic, also add support for setting -port and -proto values via nginx:set, refs #4339 --- docs/configuration/ssl.md | 5 +- plugins/nginx-vhosts/command-functions | 4 +- plugins/nginx-vhosts/functions | 8 ++- plugins/nginx-vhosts/subcommands/set | 4 +- .../nginx-vhosts/templates/nginx.conf.sigil | 12 ++-- tests/unit/nginx-vhosts_6.bats | 61 +++++++++++++++++-- 6 files changed, 75 insertions(+), 19 deletions(-) diff --git a/docs/configuration/ssl.md b/docs/configuration/ssl.md index bfb9409bc..a03dad677 100644 --- a/docs/configuration/ssl.md +++ b/docs/configuration/ssl.md @@ -139,8 +139,9 @@ Your application has access to the HTTP headers `X-Forwarded-Proto`, `X-Forwarde If your server runs behind an HTTP(S) load balancer, then Nginx will see all requests as coming from the load balancer. If your load balancer sets the `X-Forwarded-` headers, you can tell Nginx to pass these headers from load balancer to your application via `nginx:set`: ```shell -dokku nginx:set node-js-app trust-x-forwarded-for true -dokku nginx:set node-js-app trust-x-forwarded-for false +dokku nginx:set node-js-app x-forwarded-for-value "\$http_x_forwarded_for" +dokku nginx:set node-js-app x-forwarded-port-value "\$http_x_forwarded_port" +dokku nginx:set node-js-app x-forwarded-proto-value "\$http_x_forwarded_proto" ``` Only use this option if: diff --git a/plugins/nginx-vhosts/command-functions b/plugins/nginx-vhosts/command-functions index 21a19c29f..99e954391 100755 --- a/plugins/nginx-vhosts/command-functions +++ b/plugins/nginx-vhosts/command-functions @@ -54,7 +54,9 @@ cmd-nginx-report-single() { "--nginx-proxy-busy-buffers-size: $(fn-nginx-proxy-busy-buffers-size "$APP")" "--nginx-proxy-read-timeout: $(fn-nginx-proxy-read-timeout "$APP")" "--nginx-last-visited-at: $(fn-nginx-vhosts-last-visited-at "$APP")" - "--nginx-trust-x-forwarded-for: $(fn-plugin-property-get-default "nginx" "$APP" "trust-x-forwarded-for" "")" + "--nginx-x-forwarded-for-value: $(fn-plugin-property-get-default "nginx" "$APP" "x-forwarded-for-value" "\$remote_addr")" + "--nginx-x-forwarded-port-value: $(fn-plugin-property-get-default "nginx" "$APP" "x-forwarded-port-value" "\$server_port")" + "--nginx-x-forwarded-proto-value: $(fn-plugin-property-get-default "nginx" "$APP" "x-forwarded-proto-value" "\$scheme")" ) if [[ -z "$INFO_FLAG" ]]; then diff --git a/plugins/nginx-vhosts/functions b/plugins/nginx-vhosts/functions index 47e91d133..a2f04e9c8 100755 --- a/plugins/nginx-vhosts/functions +++ b/plugins/nginx-vhosts/functions @@ -462,7 +462,9 @@ nginx_build_config() { local NGINX_BIND_ADDRESS_IP6="$(fn-plugin-property-get-default "nginx" "$APP" "bind-address-ipv6" "::")" [[ -z "$NGINX_BIND_ADDRESS_IP6" ]] && NGINX_BIND_ADDRESS_IP6="::" - local PROXY_TRUST_X_FORWARDED_FOR="$(fn-plugin-property-get-default "nginx" "$APP" "trust-x-forwarded-for" "false")" + local PROXY_X_FORWARDED_FOR="$(fn-plugin-property-get-default "nginx" "$APP" "x-forwarded-for-value" "\$remote_addr")" + local PROXY_X_FORWARDED_PORT="$(fn-plugin-property-get-default "nginx" "$APP" "x-forwarded-port-value" "\$server_port")" + local PROXY_X_FORWARDED_PROTO="$(fn-plugin-property-get-default "nginx" "$APP" "x-forwarded-proto-value" "\$scheme")" eval "$(config_export app "$APP")" local SIGIL_PARAMS=(-f "$NGINX_TEMPLATE" APP="$APP" DOKKU_ROOT="$DOKKU_ROOT" @@ -493,7 +495,9 @@ nginx_build_config() { NGINX_PORT="$PROXY_PORT" NGINX_SSL_PORT="$PROXY_SSL_PORT" PROXY_PORT="$PROXY_PORT" PROXY_SSL_PORT="$PROXY_SSL_PORT" RAW_TCP_PORTS="$RAW_TCP_PORTS" PROXY_PORT_MAP="$PROXY_PORT_MAP" PROXY_UPSTREAM_PORTS="$PROXY_UPSTREAM_PORTS" - PROXY_TRUST_X_FORWARDED_FOR="$PROXY_TRUST_X_FORWARDED_FOR") + PROXY_X_FORWARDED_FOR="$PROXY_X_FORWARDED_FOR" + PROXY_X_FORWARDED_PORT="$PROXY_X_FORWARDED_PORT" + PROXY_X_FORWARDED_PROTO="$PROXY_X_FORWARDED_PROTO") local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE" while read -r line || [[ -n "$line" ]]; do diff --git a/plugins/nginx-vhosts/subcommands/set b/plugins/nginx-vhosts/subcommands/set index 5066e860e..681041933 100755 --- a/plugins/nginx-vhosts/subcommands/set +++ b/plugins/nginx-vhosts/subcommands/set @@ -9,13 +9,13 @@ cmd-nginx-set() { declare cmd="nginx:set" [[ "$1" == "$cmd" ]] && shift 1 declare APP="$1" KEY="$2" VALUE="$3" - local VALID_KEYS=("access-log-format" "access-log-path" "bind-address-ipv4" "bind-address-ipv6" "disable-custom-config" "error-log-path" "hsts" "hsts-include-subdomains" "hsts-preload" "hsts-max-age" "proxy-read-timeout" "proxy-buffer-size" "proxy-buffering" "proxy-buffers" "proxy-busy-buffers-size") + local VALID_KEYS=("access-log-format" "access-log-path" "bind-address-ipv4" "bind-address-ipv6" "disable-custom-config" "error-log-path" "hsts" "hsts-include-subdomains" "hsts-preload" "hsts-max-age" "proxy-read-timeout" "proxy-buffer-size" "proxy-buffering" "proxy-buffers" "proxy-busy-buffers-size" "x-forwarded-for-value" "x-forwarded-port-value" "x-forwarded-proto-value") verify_app_name "$APP" [[ -z "$KEY" ]] && dokku_log_fail "No key specified" if ! fn-in-array "$KEY" "${VALID_KEYS[@]}"; then - dokku_log_fail "Invalid key specified, valid keys include: access-log-format, access-log-path, bind-address-ipv4, bind-address-ipv6, disable-custom-config, error-log-path, hsts, hsts-include-subdomains, hsts-preload, hsts-max-age, proxy-read-timeout, proxy-buffer-size, proxy-buffering, proxy-buffers, proxy-busy-buffers-size" + dokku_log_fail "Invalid key specified, valid keys include: access-log-format, access-log-path, bind-address-ipv4, bind-address-ipv6, disable-custom-config, error-log-path, hsts, hsts-include-subdomains, hsts-preload, hsts-max-age, proxy-read-timeout, proxy-buffer-size, proxy-buffering, proxy-buffers, proxy-busy-buffers-size, x-forwarded-for-value, x-forwarded-port-value, x-forwarded-proto-value" fi if [[ -n "$VALUE" ]]; then diff --git a/plugins/nginx-vhosts/templates/nginx.conf.sigil b/plugins/nginx-vhosts/templates/nginx.conf.sigil index 3c3e3a619..dd3fae51f 100644 --- a/plugins/nginx-vhosts/templates/nginx.conf.sigil +++ b/plugins/nginx-vhosts/templates/nginx.conf.sigil @@ -33,9 +33,9 @@ server { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $http_connection; proxy_set_header Host $http_host; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For {{ if $.PROXY_TRUST_X_FORWARDED_FOR eq "true" }}$proxy_add_x_forwarded_for{{ else }}$remote_addr{{ end }}; - proxy_set_header X-Forwarded-Port $server_port; + proxy_set_header X-Forwarded-For {{ $.PROXY_X_FORWARDED_FOR }}; + proxy_set_header X-Forwarded-Port {{ $.PROXY_X_FORWARDED_PORT }}; + proxy_set_header X-Forwarded-Proto {{ $.PROXY_X_FORWARDED_PROTO }}; proxy_set_header X-Request-Start $msec; } include {{ $.DOKKU_ROOT }}/{{ $.APP }}/nginx.conf.d/*.conf; @@ -96,9 +96,9 @@ server { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $http_connection; proxy_set_header Host $http_host; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For {{ if $.PROXY_TRUST_X_FORWARDED_FOR eq "true" }}$proxy_add_x_forwarded_for{{ else }}$remote_addr{{ end }}; - proxy_set_header X-Forwarded-Port $server_port; + proxy_set_header X-Forwarded-For {{ $.PROXY_X_FORWARDED_FOR }}; + proxy_set_header X-Forwarded-Port {{ $.PROXY_X_FORWARDED_PORT }}; + proxy_set_header X-Forwarded-Proto {{ $.PROXY_X_FORWARDED_PROTO }}; proxy_set_header X-Request-Start $msec; } include {{ $.DOKKU_ROOT }}/{{ $.APP }}/nginx.conf.d/*.conf; diff --git a/tests/unit/nginx-vhosts_6.bats b/tests/unit/nginx-vhosts_6.bats index 5232f3222..1e49fa352 100644 --- a/tests/unit/nginx-vhosts_6.bats +++ b/tests/unit/nginx-vhosts_6.bats @@ -156,7 +156,7 @@ teardown() { assert_output_contains "127.0.0.1:80;" 0 } -@test "(nginx-vhosts) nginx:set trust-x-forwarded-for" { +@test "(nginx-vhosts) nginx:set x-forwarded-for-value" { run deploy_app echo "output: $output" echo "status: $status" @@ -170,9 +170,9 @@ teardown() { run /bin/bash -c "dokku nginx:show-config $TEST_APP" echo "output: $output" echo "status: $status" - assert_output_contains "X-Forwarded-For $remote_addr;" + assert_output_contains "X-Forwarded-For \$remote_addr;" - run /bin/bash -c "dokku nginx:set $TEST_APP trust-x-forwarded-for true" + run /bin/bash -c "dokku nginx:set $TEST_APP x-forwarded-for-value '\$http_x_forwarded_for'" echo "output: $output" echo "status: $status" assert_success @@ -185,9 +185,11 @@ teardown() { run /bin/bash -c "dokku nginx:show-config $TEST_APP" echo "output: $output" echo "status: $status" - assert_output_contains "X-Forwarded-For $proxy_add_x_forwarded_for;" + assert_output_contains "X-Forwarded-For \$http_x_forwarded_for;" +} - run /bin/bash -c "dokku nginx:set $TEST_APP trust-x-forwarded-for false" +@test "(nginx-vhosts) nginx:set x-forwarded-port-value" { + run deploy_app echo "output: $output" echo "status: $status" assert_success @@ -200,7 +202,54 @@ teardown() { run /bin/bash -c "dokku nginx:show-config $TEST_APP" echo "output: $output" echo "status: $status" - assert_output_contains "X-Forwarded-For $remote_addr;" + assert_output_contains "X-Forwarded-Port \$server_port;" + + run /bin/bash -c "dokku nginx:set $TEST_APP x-forwarded-port-value '\$http_x_forwarded_port'" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku nginx:build-config $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku nginx:show-config $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_output_contains "X-Forwarded-Port \$http_x_forwarded_port;" +} + +@test "(nginx-vhosts) nginx:set x-forwarded-proto-value" { + run deploy_app + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku nginx:build-config $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku nginx:show-config $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_output_contains "X-Forwarded-Proto \$scheme;" + + run /bin/bash -c "dokku nginx:set $TEST_APP x-forwarded-proto-value '\$http_x_forwarded_proto'" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku nginx:build-config $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku nginx:show-config $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_output_contains "X-Forwarded-Proto \$http_x_forwarded_proto;" } @test "(nginx-vhosts) nginx:validate-config" {