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.