How to force HTTPS behind an Amazon Web Services Elastic Load Balancer
Recently I have been learning the Amazon Web Services (AWS) platform and have created a setup with two web servers running NGINX and PHP behind an Elastic Load Balancer (ELB). Later I added HTTPS support and I came across an issue where HTTPS requests were getting redirected to HTTP. Luckily the ELB supports the HTTP header X-FORWARDED-PROTO and using a simple rewrite rule, HTTPS can be enforced. To serve as a reference for myself and to help others out, below is the code required to achieve this on the most popular HTTP server software:
NGINX
server {
listen 80;
location / {
if ($http_x_forwarded_proto != 'https') {
rewrite ^ https://$host$request_uri? permanent;
}
}
Apache
<VirtualHost *:80>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI}
</VirtualHost>
IIS
<rewrite xdt:Transform="Insert">
<rules>
<rule name="HTTPS rewrite behind ELB rule" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions>
<add input="{HTTP_X_FORWARDED_PROTO}" pattern="^http$" ignoreCase="false" />
</conditions>
<action type="Redirect" redirectType="Found" url="https://{SERVER_NAME}{URL}" />
</rule>
</rules>
</rewrite>
Note: When configuring the ELB health check, it is important to configure this to check HTTP on port 80 (assuming SSL terminates at the ELB).