I have a Java 8 Spring Boot (1.5.13) web server, behind an AWS Application Load Balancer. The ALB performs TLS termination.
The web server redirects users for various reasons (for eg. to a login page). As described in docs, I've set server.use-forward-headers
to true
in application.properties
so the redirection happens correctly to the external (https) url, using the X-Forwarded-Proto
and Host
headers.
This setup works on Host 1, but a (near) identical setup doesn't work on Host 2. On Host 2, I've narrowed it down to the below. Things work if I curl localhost
, but not if I curl 172.32.1.1
(host 2's ip).
Both commands below were run on Host 2. Any ideas on what could be causing the difference in response? (http vs https)
[ec2-user@ip-172-32-1-1 ~]$ curl -v localhost:8080 -H "X-Forwarded-Proto: https" -H "X-Forwarded-Port: 443" -H "Host: example.com"
* Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: example.com
> User-Agent: curl/7.79.1
> Accept: */*
> X-Forwarded-Proto: https
> X-Forwarded-Port: 443
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 302
< Set-Cookie: SESSION=6a9d14f0-07f6-4f73-ae31-8232f2d9de5d; Path=/; Secure; HttpOnly
< Location: https://example.com/login
< Content-Length: 0
< Date: Wed, 21 Dec 2022 21:43:28 GMT
<
* Connection #0 to host localhost left intact
[ec2-user@ip-172-32-1-1 ~]$ curl -v 172.32.1.1:8080 -H "X-Forwarded-Proto: https" -H "X-Forwarded-Port: 443" -H "Host: example.com"
* Trying 172.32.1.1:8080...
* Connected to 172.32.1.1 (172.32.1.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: example.com
> User-Agent: curl/7.79.1
> Accept: */*
> X-Forwarded-Proto: https
> X-Forwarded-Port: 443
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 302
< Set-Cookie: SESSION=cbf4800a-15a8-460a-a3db-d6e3c21c046e; Path=/; HttpOnly
< Location: http://example.com/login
< Content-Length: 0
< Date: Wed, 21 Dec 2022 21:42:50 GMT
<
* Connection #0 to host 172.32.1.1 left intact
Host 1 and Host 2 are using the same VM Image, and WAR file. On Host 1, the 2 commands above both respond with https as expected.
CodePudding user response:
It could be so many different things. Here is where I would look off the top of my head.
- Firewall
- /etc/hosts
- Certificates
- Look at the nics, are the apps bound the same (0.0.0.0)
CodePudding user response:
The issue was the IP difference between Host1's VPC (172.31.x.x) and Host2's VPC (172.32.x.x)
The default for server.tomcat.internal-proxies
matched 172.31.*, but not 172.32.* - causing X-Forwarded
headers to be ignored in Host 2. Updating the property fixed it.
Default
server.tomcat.internal-proxies=10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|169\.254\.\d{1,3}\.\d{1,3}|127\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.1[6-9]{1}\.\d{1,3}\.\d{1,3}|172\.2[0-9]{1}\.\d{1,3}\.\d{1,3}|172\.3[0-1]{1}\.\d{1,3}\.\d{1,3}
Updated
server.tomcat.internal-proxies=(127\.\d{1,3}\.\d{1,3}\.\d{1,3})|(172.32.\d{1,3}\.\d{1,3})
A few things I came across which were helpful: there's a handy properties reference here. Also, all properties actually in use (including defaults) can be checked via the actuator link in your app /actuator/configprops.json