In the most common case, when running your web app behind Elastic Load Balancing (ELB)
of Amazon Web Service (AWS) with on both HTTP and HTTPS requests.
The ports configuration is 80 => 80
and 443 => 80
. Sometimes, you may want to rewrite
all HTTP requests to HTTPS.
The most common ELB configuration with both HTTP and HTTPS
The ELB supports a HTTP header called X-FORWARDED-PROTO
. All the HTTPS requests
going through the ELB will have the value of X-FORWARDED-PROTO
equal to https
.
For the HTTP requests, you can force HTTPS by adding a simple rewrite rule follows this header.
In your web server, setting up a rewrite rule:
In your nginx site config file check if the value of X_FORWARDED_PROTO
is https
,
if not, rewrite it:
1
2
3
4
5
6
7
8
9
10
11
server {
listen 80;
#....
location / {
if ($http_x_forwarded_proto != 'https') {
return 301 https://$server_name$request_uri;
}
try_files $uri $uri/ /index.php?$args;
#....
}
}
Same goes for Apache, add this rewrite rule to your site’s config file:
1
2
3
4
5
6
7
<VirtualHost *:80>
#...
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [NE]
#...
</VirtualHost>
Install IIS Url-Rewrite module, using the configuration GUI add these settings:
1
2
3
4
5
6
7
8
9
10
11
<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>
Sometimes, your ELB health check request is HTTP (port 80), you must exclude it from rewrite rule or make other port for health check request. Eg with NGINX:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server {
listen 80 default_server;
server_name "";
location /health {
access_log off;
return 200;
}
}
server {
listen 80;
server_name app.yourdomain.com;
#....
location / {
if ($http_x_forwarded_proto != 'https') {
return 301 https://$server_name$request_uri;
}
try_files $uri $uri/ /index.php?$args;
}
#....
}
Goodluck!
Comments