Redirect loop when forcing HTTPS
Solution 1
Thanks to HBruijn's comment, I understood why I was getting the redirect loop.
The traffic from the ELB will always be HTTP as it handles the HTTPS traffic to the user but to the server it's HTTP, so my previous rule will result in a loop.
After some research I found that the load balancer forwards a few userful headers like X-Forwarded-Proto
. This can be used to determine if the client is using HTTP or HTTPS like so:
### Force HTTPS
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
I hope the above helps someone else when trying to force HTTPS behind Amazon Web Services Load balancer.
Solution 2
Rather than doing so in a .htaccess
file, simply set the SSL Redirect in the non-SSL VirtualHost entry of your Apache configuration:
NameVirtualHost *:80
<VirtualHost *:80>
ServerName www.example.com
Redirect permanent / https://www.example.com/
</VirtualHost>
<VirtualHost _default_:443>
ServerName www.example.com
DocumentRoot /usr/local/apache2/htdocs
SSLEngine On
# etc...
</VirtualHost>
which is much more efficient.
Additionally: my pet peeve, quoted from from the manual on .htaccess files:
You should avoid using .htaccess files completely if you have access to httpd main server config file. Using .htaccess files slows down your Apache http server. Any directive that you can include in a .htaccess file is better set in a
Directory
block in the main Apache configuration file(s), as it will have the same effect with better performance.
Related videos on Youtube
Abs
Updated on September 18, 2022Comments
-
Abs over 1 year
I am using the following to force HTTPS on my main website.
### Force SSL RewriteCond %{HTTPS} !=on RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
If you want to view the full htaccess file, I have placed it below:
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / ### Blacklist via Referrers RewriteCond %{HTTP_REFERER} removed\.net [NC,OR] RewriteCond %{HTTP_REFERER} removed\.com [NC,OR] RewriteCond %{HTTP_REFERER} removed\.removed\.com [NC,OR] RewriteCond %{HTTP_REFERER} removed\.com [NC,OR] RewriteCond %{HTTP_REFERER} removed\.net [NC,OR] RewriteCond %{HTTP_REFERER} removed\.sx [NC,OR] RewriteCond %{HTTP_REFERER} removed\.com [NC,OR] RewriteCond %{HTTP_REFERER} removed\.com [NC,OR] RewriteCond %{HTTP_REFERER} removed\.com [NC,OR] RewriteCond %{HTTP_REFERER} removed\.com [NC,OR] RewriteCond %{HTTP_REFERER} removed\.org [NC] RewriteRule ^(.*)$ - [F,L] ### Force SSL #RewriteCond %{HTTPS} !=on #RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] ### Canonicalize codeigniter URLs # If your default controller is something other than # "welcome" you should probably change this RewriteRule ^(welcome(/index)?|index(\.php)?)/?$ / [L,R=301] RewriteRule ^(.*)/index/?$ $1 [L,R=301] # Removes trailing slashes (prevents SEO duplicate content issues) RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.+)/$ $1 [L,R=301] # Enforce NO www RewriteCond %{HTTP_HOST} ^www [NC] RewriteRule ^(.*)$ https://removed.com/$1 [L,R=301] # Removes access to the system folder by users. # Additionally this will allow you to create a System.php controller, # previously this would not have been possible. # 'system' can be replaced if you have renamed your system folder. RewriteCond %{REQUEST_URI} ^system.* RewriteRule ^(.*)$ /index.php/$1 [L] # Checks to see if the user is attempting to access a valid file, # such as an image or css document, if this isn't true it sends the # request to index.php RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php/$1 [L] </IfModule> <IfModule !mod_rewrite.c> # Without mod_rewrite, route 404's to the front controller ErrorDocument 404 /index.php </IfModule>
I am struggling to figure how the redirect loop is happening.
Update
I did not make it clear that my web server (Apache) is only configured with one virtual host on port 80 that gets HTTP and HTTPS traffic directed to it by the load balancer. The load balancer handles the SSL connection.
-
Abs about 9 yearsDoes the above solution mean all pages that are not SSL will redirect to the homepage? That is not ideal to be honest. We use htaccess files as it's easier for deployments to multiple environments as we swap htaccess files for each environment.
-
HBruijn about 9 yearsI included the link so you could Read The Fine Manual and you would have seen that
http://www.example.com/something?else=true
will be redirected tohttps://www.example.com/something?else=true
and NOT to the homepage. - With regards to.htaccess
all I'm going to say is: to many people use them and continue to copy them without actually understanding either their use-case or their impact. -
Abs about 9 yearsThe above solution won't work for us as we make use of the
AWS ELB
that routes SSL traffic to our Apache server that is only configured for port 80. It results in a redirect loop when I put the above statement in our config file as bothHTTP
andHTTPS
hit the same virtual host. Any idea why our htaccess results in a redirect loop? -
Tania Rascia over 8 yearsThank you! This was the only one that didn't cause a rewrite loop for me.
-
Gruber about 8 yearsSame thing for me on CloudFlare using the given HTML5BP .htacess file enabling the rule to force
https
-
Josh Woodcock over 7 yearsOh my gosh. I can't believe that AWS was screwing me up. I couldn't figure out why every single example didn't work until I came across this answer. Thanks!