Friday 16 August 2013

302 redirects behind SSL reverse proxy

Problem

You have a web server running plain http behind an Apache reverse proxy running https. Your application uses 302 redirects to announce new URLs or whatever the reason is for doing so.

The client will be redirected a plain http url.

Solution

You can create a Vhost listenig for plain http and all that it does is redirect the clients to https, like this:
NameVirtualHost *:80
<VirtualHost *:80>
   ServerName www.example.com
   Redirect permanent / https://secure.example.com/
</VirtualHost>
This way, the client is redirected to the plain http by the proxied server and then redirected back to https by the proxy server.

Another solution is to use mod_rewrite:
RewriteEngine On
# This will enable the Rewrite capabilities
RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
# This rule will redirect users from their original location, to the same location but using HTTPS.
# i.e.  http://www.example.com/foo/ to https://www.example.com/foo/
# The leading slash is made optional so that this will work either in httpd.conf
# or .htaccess context
This does the same as the previous solution.
But what if there is some firewall or load balancer that prevents plain http packets from reaching your server?
Since Apache version 2.2.4 mod_headers is able to rewrite response headers. Just add the following to your https vhost that is serving as reverse proxy to your application:
Header edit Location ^http://(.*)$ https://$1
This configuration statement will solve your problem. Redirects triggered by your back end web servers will be re-rewritten to comply with your SSL terminating reverse proxy/load balancer.

Example:
Listen a.b.c.d:443
<VirtualHost a.b.c.d:443>
    ServerName example.org
    # …SSL configuration…
    ProxyRequests off
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/
    RequestHeader set X-Forwarded-Protocol "https"
    Header edit Location ^http://(.*)$ https://$1
</VirtualHost>
<VirtualHost a.b.c.d:80>
    ServerName example.org
    ProxyRequests off
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/
    RequestHeader set X-Forwarded-Protocol "http"
</VirtualHost>

Possibly Related Posts

No comments:

Post a Comment