This is the 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 with 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 webserver 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.