Redirect Loop in PHP behind a load balancer with SSL

I have a situation where I get stuck in an endless redirect loop when I try to switch from SSL encrypted pages to unencrypted (https -> http) pages. Our current configuration is set behind a load balancer that creates a header: HTTP_X_FORWARDED_PROTO

When configured for SSL it returns "https" while it always returns "http"

The following code I used on the site before the SSL certificate was moved to the load balancer instead of the node website, the site works. (HTTP_X_FORWARDED_PROTO) have been added to update the script accordingly.

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])){
    $redirect = '';
    if (!isset($sslPage)){
        $sslPage = false;
    }
    switch($_SERVER['HTTP_X_FORWARDED_PROTO']){
        case 'http' :
            if ($sslPage)
                $redirect = 'location: https://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
            break;  

        case 'https' :
            if (!$sslPage)
                //$redirect = 'location: http://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
            break;
    }
    if (!empty($redirect)){
        header ($redirect); 
    }
}

      

Every page that requires ssl has a preset variable $ sslPage = true;

So the redirect from http to https works great .. no problem. But if I try to go back, it doesn't work. I'm stuck in an endless loop. I'm starting to think itโ€™s because of the Apache. Since the web node no longer terminates SSL, all traffic to it is started on port 80. When php does a redirect via header (), I believe what happens when the server picks up the request, since it is local, and tries to parse it, Because HTTP_X_FORWARDED_PROTO never is not updated because it did not hit the load balancer again, the redirect can never be successful.

My question is, does this make sense or was I wrong thinking about it? Will this call, regardless, always be redirected back to the load balancer? If it stays inside this node website, how can I get it to fall back to the load balancer so that it can write new headers for the page it was trying to get?

It turned out to be disappointing ....

Thanks for your help in advance.

+3


source to share


2 answers


You can simply disable Apache think protocol by setting an environment variable (in PHP logic $_SERVER['HTTPS']

)

SetEnvIf X-Forwarded-Proto https HTTPS=On

      



This should allow your legacy code to work without the need to change.

+6


source


We just ran into something similar and found our Zeus load balancer tampering with the response header. We found that any 301/302 headers sent back were modified by the load balancer if the original request was made on https and the return was on an unsecured page.

For example, if a client requested https://site.com and we redirected to http://site.com from 302, the client-side result would be "Location: https://site.com " because the load balancer ( instead of expected): http://site.com ")



This was resolved by disabling this feature in the load balancer.

Hope this helps someone - it's an annoying problem to try and figure it out!

+2


source







All Articles