From 2583f8050a9fa4b07bce22b22f983672811e67d4 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 21 Aug 2015 09:25:10 +0100 Subject: [PATCH] Enable Tomcat RemoteIpValve by default Fixes gh-3782 --- .../autoconfigure/web/ServerProperties.java | 13 +++++--- spring-boot-docs/src/main/asciidoc/howto.adoc | 31 ++++++++++++++----- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java index 1909e2c2fa..526b159b8c 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java @@ -283,7 +283,7 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer, Ord } if (container instanceof TomcatEmbeddedServletContainerFactory) { getTomcat() - .customizeTomcat((TomcatEmbeddedServletContainerFactory) container); + .customizeTomcat((TomcatEmbeddedServletContainerFactory) container); } if (container instanceof UndertowEmbeddedServletContainerFactory) { getUndertow().customizeUndertow( @@ -496,13 +496,13 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer, Ord /** * Name of the HTTP header used to override the original port value. */ - private String portHeader; + private String portHeader = "x-forwarded-port"; /** * Name of the http header from which the remote ip is extracted. Configured as a * RemoteIpValve only if remoteIpHeader is also set. */ - private String remoteIpHeader; + private String remoteIpHeader = "x-forwarded-for"; /** * Tomcat base directory. If not specified a temporary directory will be used. @@ -691,13 +691,16 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer, Ord String remoteIpHeader = getRemoteIpHeader(); String protocolHeader = getProtocolHeader(); if (StringUtils.hasText(remoteIpHeader) - || StringUtils.hasText(protocolHeader)) { + && StringUtils.hasText(protocolHeader)) { RemoteIpValve valve = new RemoteIpValve(); valve.setRemoteIpHeader(remoteIpHeader); valve.setProtocolHeader(protocolHeader); + // The internal proxies default to a white list of "safe" internal IP + // addresses valve.setInternalProxies(getInternalProxies()); valve.setPortHeader(getPortHeader()); valve.setProtocolHeaderHttpsValue(getProtocolHeaderHttpsValue()); + // ... so it's safe to add this valve by default. factory.addContextValves(valve); } } @@ -1012,7 +1015,7 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer, Ord * configuration. */ private static class SessionConfiguringInitializer implements - ServletContextInitializer { + ServletContextInitializer { private final Session session; diff --git a/spring-boot-docs/src/main/asciidoc/howto.adoc b/spring-boot-docs/src/main/asciidoc/howto.adoc index 758efa1a51..c9ef19d56b 100644 --- a/spring-boot-docs/src/main/asciidoc/howto.adoc +++ b/spring-boot-docs/src/main/asciidoc/howto.adoc @@ -525,11 +525,24 @@ HTTPS connector: [[howto-use-tomcat-behind-a-proxy-server]] === Use Tomcat behind a front-end proxy server -Spring Boot will automatically configure Tomcat's `RemoteIpValve` if you enable it. This -allows you to transparently use the standard `x-forwarded-for` and `x-forwarded-proto` -headers that most front-end proxy servers add. The valve is switched on by setting one or -both of these properties to something non-empty (these are the conventional values used by -most proxies, and if you only set one the other will be set automatically): +Your app might need to send 302 redirects, or render UI templates with +absolute links to itself, or hypermedia links back to itself in the +case of a RESTful service. If the app is behind a proxy, the caller +wants a link to the proxy not to the physical address of the app, so +something has to be done in the backend. Typically this is handled via +a contract with the proxy, which will add headers to tell the back end +how to construct links to itself. If the proxy adds conventional +headers (most do this out of the box) the absolute links should be +rendered correctly by default using the Tomcat server. + +Spring Boot using Tomcat automatically adds a `RemoteIpValve`. This +transparently takes the standard `x-forwarded-for` and +`x-forwarded-proto` headers and uses them to change local URLs created +in the `HttpServletRequest`. You can configure the header names in +Spring Boot and the valve is switched on unless one or both of these +properties is empty. These values are the defaults and are the +conventional values used by most proxies, so you don't need to set +them unless you need different values: [indent=0] ---- @@ -560,8 +573,12 @@ NOTE: The double backslashes are only required when you're using a properties fi configuration. If you are using YAML, single backslashes are sufficient and a value that's equivalent to the one shown above would be `192\.168\.\d{1,3}\.\d{1,3}`. -Alternatively, you can take complete control of the configuration of the `RemoteIpValve` -by configuring and adding it in a `TomcatEmbeddedServletContainerFactory` bean. +NOTE: You can trust all proxies by setting the `internal_proxies` to empty (but don't do this in production). + +You can take complete control of the configuration of the +`RemoteIpValve` by switching the automatic one off (i.e. set one of +the headers to empty) and adding a new valve instance in a +`TomcatEmbeddedServletContainerFactory` bean.