Prevent SSL redirect loop using WordPress and HAProxy

This is a first post in a series on how to use HAProxy in front of WordPress. I’m using HAProxy to offload SSL connections to a WordPress site. The site itself runs on an internal IP address on port 80 while HAProxy listens on incoming connections on *:80 and *:443. Connections to *:443 will be presented the correct certificate using HAProxy’s SNI-based certificate matching algorithm. I’ll write more about that SNI-based configuration in a future post. In this post I’m going to focus on the SSL redirect loop which is happening if you use
define('FORCE_SSL_ADMIN', true);
and/or
define('FORCE_SSL_LOGIN', true);
in wp-config.php. Since HAProxy offloads the SSL connection, the web server running the WordPress site has no way to know the connection was SSL-based initially. Edit wp-config.php and add the following lines:
 define('FORCE_SSL_ADMIN', true);
define('FORCE_SSL_LOGIN', true);
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
  $_SERVER['HTTPS']='on';
We’re telling WordPress that if an X-Forwarded-Proto header is present with the value https, the connection was initially based on SSL. Obviously, the X-Forwarded-Proto header has to be injected into the HTTP header of the request by HAProxy in the first place:
frontend ft_web_ssl
  mode http
  bind 0.0.0.0:443 ssl crt /etc/haproxy/certs.d
  reqadd X-Forwarded-Proto:\ https
  ...
  ...
Make sure to use option http-server-close as well or the reqadd setting might not work as expected.

Post a Comment