Fixing infinite redirects when HTTPS is enabled on WordPress behind an AWS Elastic Load Balancer

As part of the ongoing infrastructure updates and upgrades I’m performing these days I’ve been trying to enable HTTPS on my websites. Some went well, some not so much....

As part of the ongoing infrastructure updates and upgrades I’m performing these days I’ve been trying to enable HTTPS on my websites. Some went well, some not so much. One of the biggest problems I’ve encountered was with WordPress which went into an infinite redirect loop after I’ve enabled HTTPS. This blog currently resides on an Amazon EC2 instance and it’s behind an Elastic Load Balancer. SSL termination happens on the load balancer and from there the request is sent towards the EC2 instance as a plain HTTP request on port 80. And basically this is the reason why WordPress thinks that it’s still on HTTP because it’s unaware that HTTPS is being terminated on the load balancer. And it redirects until the browser throws an error.

This can be easily fixed once you know what the problem is. The fix is adding the following line to either your httpd.conf or your .htaccess file:

SetEnvIfNoCase X-FORWARDED-PROTO "^https$" HTTPS

 

This tells PHP scripts (so WordPress too) that we are already running in HTTPS. Basically it’s translating the header that the AWS Elastic Load Balancer sends (X-Forwarder-Proto: https).

BONUS: How do you redirect all incoming HTTP requests to HTTPS?

Now that you can load HTTPS pages you also need to redirect all incoming HTTP requests into HTTPS requests because you might have incoming links from search engines or referrers which still link to your old HTTP pages. We do that with the following rewrites in either httpd.conf or .htaccess file

RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=301]

 

Translated to human language this means that if the server finds no HTTPS header from the AWS Elastic Load Balancer (X-Forwarded-Proto is not HTTPS) then it will do a 301 redirect to HTTPS preserving the server name and the incoming request URI.

Well, that’s it. This is how i fixed my problems today.

No Comments

Leave a Reply

*

*