" Web Design "

Laravel Forge Screenshot

Fixing the nginx $_SERVER[‘HTTPS’] issue on a Laravel Forge Load Balancer

Recently I’ve been experimenting with Laravel Forge and Linode to build a new server platform for the new CloudMonitor app I’m currently building (http://www.rockandscissor.com), and after a couple of attempts and quite a few support tickets to Taylor Otwell, Creator of Laravel and Forge, I’ve finally managed to configure a Load Balancer and 2 servers running a MySQL Master-Master sync, and using Unison to keep the web directories synced.

However I came across a problem which is fairly common on Load Balanced or Reverse Proxy setups that use SSL. The Load Balancer itself terminates the SSL connection on port 443 and the traffic is sent from the Load Balancer to the servers across the local network on port 80. The problem arises with any software that uses the $_SERVER[‘HTTPS’] = ‘on’ global variable such as WordPress, Magento, OpenCart etc due to this global variable not being set, this is because traffic comes to the server through HTTP (port 80) instead of HTTPS (port 443).

So how do we fix this? Well even though this isn’t technically a bug (please excuse my title on this article) as the traffic isn’t coming to the server in a secure fashion, and the $_SERVER[‘HTTP_X_FORWARDED_PROTO’] global variable is set to indicate which protocol is being used to the server. Unfortunately for reasons I’ve yet to discover, and I’m sure there are technical reasons, the software mentioned above doesn’t look at this additional variable to do SSL detection. The most common solution for this problem is to modify your source code to look at this global variable, or to install a plugin/module that incorporates the workaround. Whilst this would fix the problem I wanted to find a way to add this fix that would work for any application I decided to install without having to modify the core source code or add additional plugins/modules. On each of the servers you will need to edit your nginx configuration files and change the following code section from this:

location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}

to this (add in the red lines to the existing code):

set $my_http "http";
set $my_ssl "off";
set $my_port "80";

if ($http_x_forwarded_proto = "https") {
set $my_http "https";
set $my_ssl "on";
set $my_port "443";
}

location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param HTTPS $my_ssl;
include fastcgi_params;
}

Many thanks to Taylor Otwell for responding to my continuous questions and Sonassi.com for their great article which pointed me in the right direction for my Nginx Reverse Proxy/Nginx setup: Magento HTTPS Re-direct Loop.