Spring Boot with embedded Tomcat behind Apache proxy
Solution 1:
I had the same problem the other day. After some debugging of Spring Boot 1.3 I found the following solution.
1. You have to setup the headers on your Apache proxy:
<VirtualHost *:443>
ServerName www.myapp.org
ProxyPass / http://127.0.0.1:8080/
RequestHeader set X-Forwarded-Proto https
RequestHeader set X-Forwarded-Port 443
ProxyPreserveHost On
... (SSL directives omitted for readability)
</VirtualHost>
2. You have to tell your Spring Boot app to use these headers. So put the following line in your application.properties (or any other place where Spring Boots understands properties):
server.use-forward-headers=true
If you do these two things correctly, every redirect your application sends will not go to http://127.0.0.1:8080/[path] but automatically to https://www.myapp.com/[path]
Update 1. The documentation about this topic is here. You should read it at least to be aware of the property server.tomcat.internal-proxies
which defines the range of IP-addresses for proxy servers that can be trusted.
Update 2021 The documentation is moved to here. The Spring Boot configuration is a litte different now.
Solution 2:
Your proxy looks fine, and so does the backend app, up to a point, but it doesn't seem to be seeing the RemoteIpValve
modified request. The default behaviour of the RemoteIpValve
includes a pattern match for the proxy IP address (as a security check) and it only modifies requests that it thinks are from a valid proxy. The pattern defaults in Spring Boot to a well-known set of internal IP addresses like 10.*.*.*
and 192.168.*.*
, so if your proxy isn't on one of those you need to explicitly configure it, e.g.
server.tomcat.internal-proxies=172\\.17\\.\\d{1,3}\\.\\d{1,3}|127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}
(using properties file format, which means you have to double escape the backslashes).
You can see the what is happening in the RemoteIpValve
if you set
logging.level.org.apache.catalina.valves.RemoteIpValve=DEBUG
or set a breakpoint in it.