diff --git a/docs/configuration/nginx.md b/docs/configuration/nginx.md index 1966715f5..27a2cd6dd 100644 --- a/docs/configuration/nginx.md +++ b/docs/configuration/nginx.md @@ -61,6 +61,20 @@ The following options are also available via the `nginx:set` command: Beware that if you enable the header and a subsequent deploy of your application results in an HTTP deploy (for whatever reason), the way the header works means that a browser will not attempt to request the HTTP version of your site if the HTTPS version fails until the max-age is reached. +#### Globally disabling the HSTS Header + +HSTS Header can be disabled for all apps by setting the `hsts` property to false after passing the `--global` flag to `nginx:set`. Changing this value globally or on a per-app basis will require rebuilding the nginx config via the `nginx:build-config` command. + +```shell +dokku nginx:set --global hsts false +``` + +Once the HSTS setting is disabled globally, it can be re-enabled on a per-app basis by setting the `hsts` property as normal. + +```shell +dokku nginx:set node-js-app hsts true +``` + ### Checking access logs You may check nginx access logs via the `nginx:access-logs` command. This assumes that app access logs are being stored in `/var/log/nginx/$APP-access.log`, as is the default in the generated `nginx.conf`. diff --git a/plugins/nginx-vhosts/command-functions b/plugins/nginx-vhosts/command-functions index 1f190c4f5..4a78838a2 100755 --- a/plugins/nginx-vhosts/command-functions +++ b/plugins/nginx-vhosts/command-functions @@ -45,6 +45,8 @@ cmd-nginx-report-single() { "--nginx-client-max-body-size: $(fn-plugin-property-get-default "nginx" "$APP" "client-max-body-size" "")" "--nginx-disable-custom-config: $(fn-plugin-property-get-default "nginx" "$APP" "disable-custom-config" "false")" "--nginx-error-log-path: $(fn-nginx-error-log-path "$APP")" + "--nginx-global-hsts: $(fn-plugin-property-get-default "nginx" "--global" "hsts" "true")" + "--nginx-applied-hsts: $(fn-plugin-property-get-default "nginx" "$APP" "hsts" "$(fn-plugin-property-get-default "nginx" "--global" "hsts" "true")")" "--nginx-hsts: $(fn-plugin-property-get-default "nginx" "$APP" "hsts" "true")" "--nginx-hsts-include-subdomains: $(fn-plugin-property-get-default "nginx" "$APP" "hsts-include-subdomains" "true")" "--nginx-hsts-max-age: $(fn-plugin-property-get-default "nginx" "$APP" "hsts-max-age" "15724800")" diff --git a/plugins/nginx-vhosts/internal-functions b/plugins/nginx-vhosts/internal-functions index 0c5dcd807..f969a00de 100755 --- a/plugins/nginx-vhosts/internal-functions +++ b/plugins/nginx-vhosts/internal-functions @@ -13,9 +13,21 @@ fn-nginx-vhosts-last-visited-at() { fi } +fn-nginx-hsts-is-applied() { + declare APP="$1" + # if hsts is disabled globally then only apply it if an app has it set explicitly + if [[ "$(fn-plugin-property-get-default "nginx" "--global" "hsts" "true")" == "false" ]] && \ + [[ "$(fn-plugin-property-get-default "nginx" "$APP" "hsts" "false")" == "false" ]]; then + echo "false"; + return; + fi + # if app has explicitly turned it off else it is default on + echo $(fn-plugin-property-get-default "nginx" "$APP" "hsts" "true"); +} + fn-nginx-vhosts-manage-hsts() { declare APP="$1" SSL_ENABLED="$2" - local HSTS="$(fn-plugin-property-get-default "nginx" "$APP" "hsts" "true")" + local HSTS="$(fn-nginx-hsts-is-applied "$APP")" local HSTS_INCLUDE_SUBDOMAINS="$(fn-plugin-property-get-default "nginx" "$APP" "hsts-include-subdomains" "true")" local HSTS_MAX_AGE="$(fn-plugin-property-get-default "nginx" "$APP" "hsts-max-age" "15724800")" local HSTS_PRELOAD="$(fn-plugin-property-get-default "nginx" "$APP" "hsts-preload" "false")" diff --git a/tests/unit/nginx-vhosts_6.bats b/tests/unit/nginx-vhosts_6.bats index 1e49fa352..824d142ea 100644 --- a/tests/unit/nginx-vhosts_6.bats +++ b/tests/unit/nginx-vhosts_6.bats @@ -107,6 +107,44 @@ teardown() { assert_failure } +@test "(nginx-vhosts) nginx:set --global hsts" { + setup_test_tls wildcard + local HSTS_CONF="/home/dokku/${TEST_APP}/nginx.conf.d/hsts.conf" + + run deploy_app + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "Enabling HSTS" + + # disable hsts globally + run /bin/bash -c "dokku nginx:set --global hsts false" + # check it is now not applied + run /bin/bash -c "dokku nginx:build-config $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "Enabling HSTS" 0 + + # apply on app + run /bin/bash -c "dokku nginx:set $TEST_APP hsts true" + # check it is now applied + run /bin/bash -c "dokku nginx:build-config $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "Enabling HSTS" 1 + + # disable globally + run /bin/bash -c "dokku nginx:set --global hsts" + # check it is still applied + run /bin/bash -c "dokku nginx:build-config $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "Enabling HSTS" 1 +} + @test "(nginx-vhosts) nginx:set bind-address" { run deploy_app echo "output: $output"