Website Setup & Info

ID #1063

How do I adjust my SSL site to work with GeekISP's loadbalancer?

GeekISP's loadbalancer configuration affects certain attributes the HTTP connection, since the loadbalancer acts as proxy between the end user and the backend web servers. The loadbalancer impacts 2 commonly used items - the client's IP and the server port.

Since the LB acts as a proxy, all web connections appear to come from the loadbalancer's internal IP address, rather than from the end user's IP. The loadbalancer does add the 'X-Forwarded-For' header to all requests so that you can still retrieve the client's IP.

For Apache users, this can be ignored since we are using the mod_rpaf module to fix up the REMOTE_ADDR variable. Users of lighttpd or Mongrel will need to adjust their applications.

The loadbalancer also handles SSL traffic, leaving the backend web server to concentrate exclusively on serving web pages, and remaining agnostic about certificates and encryption. Since it is useful to know if a particular request was made to a SSL-protected site, the LB adds the 'X-Forwarded-Proto' header to any request that was served over SSL.

In short, when you want the client's remote IP, use the 'X-Forwarded-For' header, and when you want to know if a connection is secure, check for the 'X-Forwarded-Proto' header.

The following examples show how you might use these techniques in PHP to update your application. An example using only mod_rewrite is at the end.

1) Redirect to the secure version of your site:

<?
$headers = apache_request_headers();

$isSecure = 0;
# be sure we've got the SSL offload header
if (isset($headers['X-Forwarded-Proto']) && $headers['X-Forwarded-Proto'] == 'https') {
# be sure the remote end is the load balancer (only necessary if using lighttpd/mongrel)
if (preg_match('/192\.168\.4\.4(2|3)/', $_SERVER['REMOTE_ADDR'])) {
$isSecure = 1;
}
}

if (! $isSecure) {
header('Location: https://www.example.com/');
}
?>

This is a secure connection.


2) Determine the SSL status and the remote user's IP:
<?
$headers = apache_request_headers();
if (isset($headers['X-Forwarded-For'])){
$remoteIP = $headers['X-Forwarded-For'];
} else{
$remoteIP = $_SERVER['REMOTE_ADDR'];
}

if (! isset($headers['X-Forwarded-Proto'])) {
$isSecure = 0;
} elseif ($headers['X-Forwarded-Proto'] == 'https' && preg_match('/192\.168\.4\.4(2|3)/', $_SERVER['REMOTE_ADDR'])) {
$isSecure = 1;
}
?>

SSL: <? echo $isSecure ?><br />
Remote addr: <? echo $remoteIP ?><br />

3) Redirect to secure version of a page, using mod_rewrite and a .htaccess file (be sure to copy the top chunk verbatim):

RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =https
RewriteRule .* - [L]

# otherwise redirect to SSL
RewriteRule .* https://www.example.com%{REQUEST_URI} [R,L]

Tags: -

Related entries:

Last update: 2007-04-10 10:48
Author: Dave Steinberg
Revision: 1.1

Digg it! Print this record Send to a friend Show this as PDF file
Propose a translation for Propose a translation for
Please rate this entry:

Average rating: 3.5 out of 5 (2 Votes )

completely useless 1 2 3 4 5 most valuable

You cannot comment on this entry

Comment of Brian:
How does one do a redirect to HTTPS prior to HTTP basic authentication? Right now, a HTTPS site will do HTTP authentication twice: once before redirecting to HTTPS, once after. Cheers!
Added at: 2008-10-15 20:09