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" {