2
votes

I have a couple of questions in regards to HAProxy (1.5.2) and Tomcat (7.0.54). Both I am a newbie in.

In Tomcat I have an application that on login (https://my.tomcat.host:8080/access) will redirect a user (via a 303 code) to another web page (http://my.tomcat.host:8080/access/sessionId=1234567). Setting up HAProxy I set the frontend engine (my-frontend-https) to receive https requests and send them to the backend (my-backend-https) - which in turn then sends it to the tomcat server as http requests.

This is what haproxy.cfg (for my.haproxy.host) looks like:

frontend my-frontend-https
   bind *:8443 ssl crt /my/certs/server.pem
   mode http
   option httplog
   default_backend my-backend-https

backend my-backend-https
  balance roundrobin
  mode http
  option httplog
  option forwardfor
  server my-tomcat-srv my.tomcat.host:8080 check

On sending the following query (https://my.haproxy.host:8443/access) I found that the Location flag being returned from tomcat was of the form: http://my.haproxy.host:80/access/sessionId=1234567. Looking at the tomcat server I found that I had to enable RemoteIPValve class in server.xml and set the httpsServerPort to 8443 (as protocolHeaderHttpsValue - may not have needed to do this bit though since it's a default). This seems to work and I will add more servers to the backend.

So that seems well but I have a couple of questions:

  1. I noticed that the problem doesn't seem to exist when the frontend engine is http rather than https. That is, the Location field comes back how I would expect to be. Any ideas of the discrepancy?
  2. Without the settings in the server.xml file it would seem that tomcat knows that I am using a proxy in between my web browser and tomcat. How does it know this? Is there a directive that is being passed to tomcat that tells it is a proxy or is it simpler than that.
  3. If I want another front-end/back-end engine in the same haproxy.cfg file pointing to the same tomcat instance (i.e. lets says the above was load balancing across multiple servers including this one and I want an entry point for just this one) can it be done? i.e. the haproxy would have the following lines in it. frontend my-frontend-https1 bind *:9443 ssl crt /my/certs/server.pem mode http option httplog default_backend my-backend-https1

    backend my-backend-https1 balance roundrobin mode http option httplog option forwardfor server my-tomcat-srv my.tomcat.host:8080 check

    Would the Location field come back as http://my.haproxy.host:8443/access/sessionId=1234567 since that is what is defined in server.xml. Thanks

Harold.

1

1 Answers

0
votes

This is not specific to Tomcat, but unless haproxy tells it, your Tomcat backend won't know haproxy is the frontend.

Were you running nginx, here's directly from my config:

proxy_set_header X-Forwarded-Proto https; # Obviously, differentiate based on whether you're serving an HTTP or HTTPS endpoint.
proxy_set_header Host $host; # Or hardcode a value.
proxy_set_header X-Real-IP  $remote_addr; # Alternative to X-Forwarded-For.
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

While I haven't done it for haproxy, as I'm putting nginx in front of haproxy, according to a tutorial, you'll want to do something like this:

# defaults section
option forwardfor

# frontend definition
frontend www-http
   bind haproxy_www_public_IP:80
   reqadd X-Forwarded-Proto:\ http
   default_backend www-backend

frontend www-https
   bind haproxy_www_public_IP:443 ssl crt /etc/ssl/private/example.com.pem
   reqadd X-Forwarded-Proto:\ https
   default_backend www-backend

# backend definition
backend www-backend
   redirect scheme https if !{ ssl_fc }
   server www-1 www_1_private_IP:80 check
   server www-2 www_2_private_IP:80 check

This is under the assumption that Tomcat will reference the standard-ish fields X-Forwarded-Proto and X-Forwarded-For.