diff --git a/docs/guides/server/reverseproxy.adoc b/docs/guides/server/reverseproxy.adoc index 4d47306cdec..fd546d35190 100644 --- a/docs/guides/server/reverseproxy.adoc +++ b/docs/guides/server/reverseproxy.adoc @@ -28,7 +28,7 @@ You only need to proxy port `8443` (or `8080`) even when you use different host {project_name} will parse the reverse proxy headers based on the `proxy-headers` option which accepts several values: -* By default if the option is not specified, no reverse proxy headers are parsed. +* By default if the option is not specified, no reverse proxy headers are parsed. This should be used when no proxy is in use or with https passthrough. * `forwarded` enables parsing of the `Forwarded` header as per https://www.rfc-editor.org/rfc/rfc7239.html[RFC7239]. * `xforwarded` enables parsing of non-standard `X-Forwarded-*` headers, such as `X-Forwarded-For`, `X-Forwarded-Proto`, `X-Forwarded-Host`, and `X-Forwarded-Port`. @@ -38,7 +38,7 @@ For example: <@kc.start parameters="--proxy-headers forwarded"/> -WARNING: If either `forwarded` or `xforwarded` is selected, make sure your reverse proxy properly sets and overwrites the `Forwarded` or `X-Forwarded-*` headers respectively. To set these headers, consult the documentation for your reverse proxy. Misconfiguration will leave {project_name} exposed to security vulnerabilities. +WARNING: If either `forwarded` or `xforwarded` is selected, make sure your reverse proxy properly sets and overwrites the `Forwarded` or `X-Forwarded-*` headers respectively. To set these headers, consult the documentation for your reverse proxy. Do not use `forwarded` or `xforwarded` with https passthrough. Misconfiguration will leave {project_name} exposed to security vulnerabilities. Take extra precautions to ensure that the client address is properly set by your reverse proxy via the `Forwarded` or `X-Forwarded-For` headers. If this header is incorrectly configured, rogue clients can set this header and trick {project_name} into thinking the client is connected from a different IP address than the actual address. This precaution can be more critical if you do any deny or allow listing of IP addresses. @@ -146,7 +146,7 @@ For example: == PROXY Protocol -The `proxy-protocol-enabled` option controls whether the server should use the HA PROXY protocol when serving requests from behind a proxy. When set to true, the remote address returned will be the one from the actual connecting client. +The `proxy-protocol-enabled` option controls whether the server should use the HA PROXY protocol when serving requests from behind a proxy. When set to true, the remote address returned will be the one from the actual connecting client. The value cannot be `true` when using the `proxy-headers` option. This is useful when running behind a compatible https passthrough proxy because the request headers cannot be manipulated. diff --git a/quarkus/config-api/src/main/java/org/keycloak/config/ProxyOptions.java b/quarkus/config-api/src/main/java/org/keycloak/config/ProxyOptions.java index 56c14f97754..419dfef4b2d 100644 --- a/quarkus/config-api/src/main/java/org/keycloak/config/ProxyOptions.java +++ b/quarkus/config-api/src/main/java/org/keycloak/config/ProxyOptions.java @@ -13,10 +13,10 @@ public class ProxyOptions { .category(OptionCategory.PROXY) .description("The proxy headers that should be accepted by the server. Misconfiguration might leave the server exposed to security vulnerabilities. Takes precedence over the deprecated proxy option.") .build(); - + public static final Option PROXY_PROTOCOL_ENABLED = new OptionBuilder<>("proxy-protocol-enabled", Boolean.class) .category(OptionCategory.PROXY) - .description("Whether the server should use the HA PROXY protocol when serving requests from behind a proxy. When set to true, the remote address returned will be the one from the actual connecting client.") + .description("Whether the server should use the HA PROXY protocol when serving requests from behind a proxy. When set to true, the remote address returned will be the one from the actual connecting client. Cannot be enabled when the `proxy-headers` is used.") .defaultValue(Boolean.FALSE) .build(); @@ -34,7 +34,7 @@ public class ProxyOptions { .category(OptionCategory.PROXY) .defaultValue(Boolean.FALSE) .build(); - + public static final Option> PROXY_TRUSTED_ADDRESSES = OptionBuilder.listOptionBuilder("proxy-trusted-addresses", String.class) .category(OptionCategory.PROXY) .description("A comma separated list of trusted proxy addresses. If set, then proxy headers from other addresses will be ignored. By default all addresses are trusted. A trusted proxy address is specified as an IP address (IPv4 or IPv6) or Classless Inter-Domain Routing (CIDR) notation.") diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/ProxyPropertyMappers.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/ProxyPropertyMappers.java index 111b7c813d1..6886aa17a24 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/ProxyPropertyMappers.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/ProxyPropertyMappers.java @@ -21,6 +21,11 @@ final class ProxyPropertyMappers { .build(), fromOption(ProxyOptions.PROXY_PROTOCOL_ENABLED) .to("quarkus.http.proxy.use-proxy-protocol") + .validator(v -> { + if (Boolean.parseBoolean(v) && Configuration.getOptionalKcValue(ProxyOptions.PROXY_HEADERS).isPresent()) { + throw new PropertyException("proxy protocol cannot be enabled when using the `proxy-headers` option"); + } + }) .build(), fromOption(ProxyOptions.PROXY_FORWARDED_HOST) .to("quarkus.http.proxy.enable-forwarded-host") @@ -42,7 +47,7 @@ final class ProxyPropertyMappers { .build() }; } - + private static void validateAddress(String address) { if (Inet.parseCidrAddress(address) != null) { return; diff --git a/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/cli/PicocliTest.java b/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/cli/PicocliTest.java index 3b013580334..c659e187e14 100644 --- a/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/cli/PicocliTest.java +++ b/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/cli/PicocliTest.java @@ -573,4 +573,11 @@ public class PicocliTest extends AbstractConfigurationTest { nonRunningPicocli = pseudoLaunch("start-dev", "--log=syslog", "--log-syslog-output=json", "--log-syslog-json-format=ecs"); assertEquals(CommandLine.ExitCode.OK, nonRunningPicocli.exitCode); } + + @Test + public void proxyProtolNotAllowedWithProxyHeaders() { + NonRunningPicocli nonRunningPicocli = pseudoLaunch("start-dev", "--proxy-headers=forwarded", "--proxy-protocol-enabled=true"); + assertEquals(CommandLine.ExitCode.USAGE, nonRunningPicocli.exitCode); + assertThat(nonRunningPicocli.getErrString(), containsString(" protocol cannot be enabled when using the `proxy-headers` option")); + } } diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelp.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelp.approved.txt index 20113471aa6..fde353d2d3e 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelp.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelp.approved.txt @@ -265,7 +265,8 @@ Proxy: --proxy-protocol-enabled Whether the server should use the HA PROXY protocol when serving requests from behind a proxy. When set to true, the remote address returned will be the - one from the actual connecting client. Default: false. + one from the actual connecting client. Cannot be enabled when the + `proxy-headers` is used. Default: false. --proxy-trusted-addresses A comma separated list of trusted proxy addresses. If set, then proxy headers from other addresses will be ignored. By default all addresses are trusted. diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelpAll.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelpAll.approved.txt index ff3195eb0b0..65bdafe8da0 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelpAll.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelpAll.approved.txt @@ -316,7 +316,8 @@ Proxy: --proxy-protocol-enabled Whether the server should use the HA PROXY protocol when serving requests from behind a proxy. When set to true, the remote address returned will be the - one from the actual connecting client. Default: false. + one from the actual connecting client. Cannot be enabled when the + `proxy-headers` is used. Default: false. --proxy-trusted-addresses A comma separated list of trusted proxy addresses. If set, then proxy headers from other addresses will be ignored. By default all addresses are trusted. diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelp.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelp.approved.txt index 58d9b86c1c0..3b7a414f1e3 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelp.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelp.approved.txt @@ -272,7 +272,8 @@ Proxy: --proxy-protocol-enabled Whether the server should use the HA PROXY protocol when serving requests from behind a proxy. When set to true, the remote address returned will be the - one from the actual connecting client. Default: false. + one from the actual connecting client. Cannot be enabled when the + `proxy-headers` is used. Default: false. --proxy-trusted-addresses A comma separated list of trusted proxy addresses. If set, then proxy headers from other addresses will be ignored. By default all addresses are trusted. diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelpAll.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelpAll.approved.txt index 15ed2313ed3..8b1caff231f 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelpAll.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelpAll.approved.txt @@ -317,7 +317,8 @@ Proxy: --proxy-protocol-enabled Whether the server should use the HA PROXY protocol when serving requests from behind a proxy. When set to true, the remote address returned will be the - one from the actual connecting client. Default: false. + one from the actual connecting client. Cannot be enabled when the + `proxy-headers` is used. Default: false. --proxy-trusted-addresses A comma separated list of trusted proxy addresses. If set, then proxy headers from other addresses will be ignored. By default all addresses are trusted. diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelp.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelp.approved.txt index 85f916a6de4..2069d28d963 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelp.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelp.approved.txt @@ -222,7 +222,8 @@ Proxy: --proxy-protocol-enabled Whether the server should use the HA PROXY protocol when serving requests from behind a proxy. When set to true, the remote address returned will be the - one from the actual connecting client. Default: false. + one from the actual connecting client. Cannot be enabled when the + `proxy-headers` is used. Default: false. --proxy-trusted-addresses A comma separated list of trusted proxy addresses. If set, then proxy headers from other addresses will be ignored. By default all addresses are trusted. diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelpAll.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelpAll.approved.txt index 0c34b035d75..207a5d27c3f 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelpAll.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelpAll.approved.txt @@ -267,7 +267,8 @@ Proxy: --proxy-protocol-enabled Whether the server should use the HA PROXY protocol when serving requests from behind a proxy. When set to true, the remote address returned will be the - one from the actual connecting client. Default: false. + one from the actual connecting client. Cannot be enabled when the + `proxy-headers` is used. Default: false. --proxy-trusted-addresses A comma separated list of trusted proxy addresses. If set, then proxy headers from other addresses will be ignored. By default all addresses are trusted. diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testUpdateCompatibilityCheckHelp.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testUpdateCompatibilityCheckHelp.approved.txt index 95bfe8b6cf4..61d287504ee 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testUpdateCompatibilityCheckHelp.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testUpdateCompatibilityCheckHelp.approved.txt @@ -271,7 +271,8 @@ Proxy: --proxy-protocol-enabled Whether the server should use the HA PROXY protocol when serving requests from behind a proxy. When set to true, the remote address returned will be the - one from the actual connecting client. Default: false. + one from the actual connecting client. Cannot be enabled when the + `proxy-headers` is used. Default: false. --proxy-trusted-addresses A comma separated list of trusted proxy addresses. If set, then proxy headers from other addresses will be ignored. By default all addresses are trusted. diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testUpdateCompatibilityCheckHelpAll.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testUpdateCompatibilityCheckHelpAll.approved.txt index 39329e7796e..1ccf1985122 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testUpdateCompatibilityCheckHelpAll.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testUpdateCompatibilityCheckHelpAll.approved.txt @@ -316,7 +316,8 @@ Proxy: --proxy-protocol-enabled Whether the server should use the HA PROXY protocol when serving requests from behind a proxy. When set to true, the remote address returned will be the - one from the actual connecting client. Default: false. + one from the actual connecting client. Cannot be enabled when the + `proxy-headers` is used. Default: false. --proxy-trusted-addresses A comma separated list of trusted proxy addresses. If set, then proxy headers from other addresses will be ignored. By default all addresses are trusted. diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testUpdateCompatibilityMetadataHelp.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testUpdateCompatibilityMetadataHelp.approved.txt index 1af7a644b4b..3d635fefe28 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testUpdateCompatibilityMetadataHelp.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testUpdateCompatibilityMetadataHelp.approved.txt @@ -269,7 +269,8 @@ Proxy: --proxy-protocol-enabled Whether the server should use the HA PROXY protocol when serving requests from behind a proxy. When set to true, the remote address returned will be the - one from the actual connecting client. Default: false. + one from the actual connecting client. Cannot be enabled when the + `proxy-headers` is used. Default: false. --proxy-trusted-addresses A comma separated list of trusted proxy addresses. If set, then proxy headers from other addresses will be ignored. By default all addresses are trusted. diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testUpdateCompatibilityMetadataHelpAll.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testUpdateCompatibilityMetadataHelpAll.approved.txt index 65b34c8ec49..ca3bbde79ab 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testUpdateCompatibilityMetadataHelpAll.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testUpdateCompatibilityMetadataHelpAll.approved.txt @@ -314,7 +314,8 @@ Proxy: --proxy-protocol-enabled Whether the server should use the HA PROXY protocol when serving requests from behind a proxy. When set to true, the remote address returned will be the - one from the actual connecting client. Default: false. + one from the actual connecting client. Cannot be enabled when the + `proxy-headers` is used. Default: false. --proxy-trusted-addresses A comma separated list of trusted proxy addresses. If set, then proxy headers from other addresses will be ignored. By default all addresses are trusted.