So I have a relatively straight forward server stack utilizing a SSL offloading and an HTTP load balancer. The setup looks something like this:
(client) -> (SSL offload - stud) -> (balancer - haproxy) -> (http server - apache)
My question isn't about plugging all this up. It works great, and I'm honestly blown away at how straight forward it has been to set this up. I'll also add that HTTP clients connect directly to haproxy, thereby bypassing the SSL offloaded. And for the record, there are redundant partners for each of the above pieces.
The problem is somewhat abstract. I'll start with a demonstration. The client makes a request through the setup to https://myserver.tld/scp
(some headers removed to keep things clear)
GET /scp HTTP/1.1
Host: myserver.tld
(headers added by haproxy)
X-Forwarded-For: [original::client:ip]
X-Forwarded-Proto: https
And the server responds with
HTTP/1.1 301 Moved Permanently
Date: Wed, 03 Jul 2013 03:16:25 GMT
Server: Apache/2.2.15 (CentOS)
Location: http://myserver.tld/scp/
Content-Length: 344
Content-Type: text/html; charset=iso-8859-1
So Apache mod_dir
is sending a redirect to the same URL with a trailing slash. It's proper to do so. That isn't the issue. The issue is that the HTTPS protocol was lost. Again, I think Apache is correct to redirect to an HTTP URL, after all, the connection it received from the aforementioned stack is a regular HTTP connection.
So from the perspective of Apache, the client requested a regular HTTP connection. The HTTPS flag is off, along with all other SSL information, because the SSL part of the session is handled by stud.
Although (inside Apache) I have a valid X-Forwarded-Proto
header, I cannot find a way to tell Apache that the original client connection was HTTPS and that the directory slash redirect by mod_dir
should use the https://
protocol. What am I missing?
The only thing I've come up with is to rewrite the Location
header inside haproxy for the HTTPS forwarded connections to replace http://
with https://
, but I really don't think that approach is very elegant. I would prefer for Apache (and (don't hurt me) PHP further down the chain) to be informed and treat the connection like a normal HTTPS connection.
Please help!
PS - I've heard it said before if you have to ask, then you're doing it wrong. Perhaps that's the root issue here, but this seems like such a simple dilemma and I feel like the only one ever to have arrived here.
You can do this by including the protocol in the ServerName directive:
ServerName https://my-server-name
According to the Apache docs:
Sometimes, the server runs behind a device that processes SSL, such as a reverse proxy, load balancer or SSL offload appliance. When this is the case, specify the https:// scheme and the port number to which the clients connect in the ServerName directive to make sure that the server generates the correct self-referential URLs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With