Can't force http over htaccess with cloudflare - .htaccess

I start to use cloudflare with their flexible SSL.
I made a page rule to auto rewrite the requests for the HTTPS(always use https) like that:
http://*example.com/*
But it keeps redirecting me as in the loop...
I don't have anything for this in my .htaccess or something like that.
I tried to force the HTTP from the origin to the cloudflare like that, but it didn't work(getting unavailble page instead):
RewriteRule ^/?(.*) http://%{SERVER_NAME}/$1 [R,L]
If you have specific to Cloudflare solution for this I would be more than glad to hear it, but if you know how to force HTTP via `.htaccess it will be good too.

Use this in your .htaccess file
RewriteEngine on
RewriteCond %{SERVER_NAME} =abc.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

Related

Https is not working properly. Few pages are not working with https [duplicate]

I'm trying to redirect all insecure HTTP requests on my site (e.g. http://www.example.com) to HTTPS (https://www.example.com). How can I do this in .htaccess file?
By the way, I'm using PHP.
The Apache docs recommend against using a rewrite:
To redirect http URLs to https, do the following:
<VirtualHost *:80>
ServerName www.example.com
Redirect / https://www.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName www.example.com
# ... SSL configuration goes here
</VirtualHost>
This snippet should go into main server configuration file, not into .htaccess as asked in the question.
This article might have come up only after the question was asked and answered, but seems to be the current way to go.
Update: Although this answer has been accepted a few years ago, note that its approach is now recommended against by the Apache documentation. Use a Redirect instead. See this answer.
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
I'd recommend with 301 redirect:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
As I was saying in this question, I'd suggest you avoid redirecting all HTTP requests to their HTTPS equivalent blindly, as it may cause you a false impression of security. Instead, you should probably redirect the "root" of your HTTP site to the root of your HTTPS site and link from there, only to HTTPS.
The problem is that if some link or form on the HTTPS site makes the client send a request to the HTTP site, its content will be visible, before the redirection.
For example, if one of your pages served over HTTPS has a form that says <form action="http://example.com/doSomething"> and sends some data that shouldn't be sent in clear, the browser will first send the full request (including entity, if it's a POST) to the HTTP site first. The redirection will be sent immediately to the browser and, since a large number of users disable or ignore the warnings, it's likely to be ignored.
Of course, the mistake of providing the links that should be to the HTTPS site but that end up being for the HTTP site may cause problems as soon as you get something listening on the HTTP port on the same IP address as your HTTPS site. However, I think keeping the two sites as a "mirror" only increases the chances of making mistakes, as you may tend to make the assumption that it will auto-correct itself by redirecting the user to HTTPS, whereas it's often too late. (There were similar discussions in this question.)
This is the html redirect approach it works but not the best.
<meta http-equiv="Refresh" content="0;URL=https://www.example.com" />
PHP approach
<?php
function redirectTohttps() {
if ($_SERVER['HTTPS']!="on") {
$redirect= "https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
header("Location:$redirect");
}
}
?>
.htaccess approch
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
copied from:
www.letuslook.org
I found out that the best way for https and www on domain is
RewriteCond %{HTTPS} off
RewriteCond %{HTTPS_HOST} !^www.example.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
I like this method of redirecting from http to https. Because I don't need to edit it for each site.
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
Using the following code in your .htaccess file automatically redirects visitors to the HTTPS version of your site:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
If you have an existing .htaccess file:
Do not duplicate RewriteEngine On.
Make sure the lines beginning RewriteCond and RewriteRule immediately follow the already-existing RewriteEngine On.
The best solution depends on your requirements. This is a summary of previously posted answers with some context added.
If you work with the Apache web server and can change its configuration, follow the Apache documentation:
<VirtualHost *:80>
ServerName www.example.com
Redirect "/" "https://www.example.com/"
</VirtualHost>
<VirtualHost *:443>
ServerName www.example.com
# ... SSL configuration goes here
</VirtualHost>
But you also asked if you can do it in a .htaccess file. In that case you can use Apache's RewriteEngine:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L]
If everything is working fine and you want browsers to remember this redirect, you can declare it as permanent by changing the last line to:
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
But be careful if you may change your mind on this redirect. Browsers remember it for a very long time and won't check if it changed.
You may not need the first line RewriteEngine On depending on the webserver configuration.
If you look for a PHP solution, look at the $_SERVER array and the header function:
if (!$_SERVER['HTTPS']) {
header("Location: https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
}
This is the proper method of redirecting HTTP to HTTPS using .htaccess according to GoDaddy.com. The first line of code is self-explanatory. The second line of code checks to see if HTTPS is off, and if so it redirects HTTP to HTTPS by running the third line of code, otherwise the third line of code is ignored.
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
https://www.godaddy.com/help/redirect-http-to-https-automatically-8828
Add the following code to the .htaccess file:
Options +SymLinksIfOwnerMatch
RewriteEngine On
RewriteCond %{SERVER_PORT} !=443
RewriteRule ^ https://[your domain name]%{REQUEST_URI} [R,L]
Where [your domain name] is your website's domain name.
You can also redirect specific folders off of your domain name by replacing the last line of the code above with:
RewriteRule ^ https://[your domain name]/[directory name]%{REQUEST_URI} [R,L]
Do everything that is explained above for redirection. Just add "HTTP Strict Transport Security" to your header. This will avoid man in the middle attack.
Edit your apache configuration file (/etc/apache2/sites-enabled/website.conf and /etc/apache2/httpd.conf for example) and add the following to your VirtualHost:
# Optionally load the headers module:
LoadModule headers_module modules/mod_headers.so
<VirtualHost 67.89.123.45:443>
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
</VirtualHost>
https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
To redirect all http requests to https , you can use :
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [NE,L,R]
If mod-rewrite isn't enabled and you are on apache 2.4, you can also use a Redirect inside if directive to redirect http requests to https .
Apache 2.4.
<if "%{HTTPS} !~ /on/">
Redirect / https://www.example.com/
</if>
If you are in a situation where your cannot access the apache config directly for your site, which many hosted platforms are still restricted in this fashion, then I would actually recommend a two-step approach. The reason why Apache themselves document that you should use their configuration options first and foremost over the mod_rewrite for HTTP to HTTPS.
First, as mentioned above, you would setup your .htaccess mod_rewrite rule(s):
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Then, in your PHP file(s) (you need to do this where ever it would be appropriate for your situation, some sites will funnel all requests through a single PHP file, others serve various pages depending on their needs and the request being made):
<?php if ($_SERVER['HTTPS'] != 'on') { exit(1); } ?>
The above needs to run BEFORE any code that could potentially expose secure data in an unsecured environment. Thus your site uses automatic redirection via HTACCESS and mod_rewrite, while your script(s) ensure no output is provided when not accessed through HTTPS.
I guess most people don't think like this, and thus Apache recommends that you don't use this method where possible. However, it just takes an extra check on the development end to ensure your user's data is secure. Hopefully this helps someone else who might have to look into using non-recommended methods due to restrictions on our hosting services end.
Unless you need mod_rewrite for other things, using Apache core IF directive is cleaner & faster:
<If "%{HTTPS} == 'off'">
Redirect permanent / https://yoursite.com/
</If>
You can add more conditions to the IF directive, such as ensure a single canonical domain without the www prefix:
<If "req('Host') != 'myonetruesite.com' || %{HTTPS} == 'off'">
Redirect permanent / https://myonetruesite.com/
</If>
There's a lot of familiarity inertia in using mod_rewrite for everything, but see if this works for you.
More info: https://httpd.apache.org/docs/2.4/mod/core.html#if
To see it in action (try without www. or https://, or with .net instead of .com): https://nohodental.com/ (a site I'm working on).
Redirect 301 / https://example.com/
(worked for me when none of the above answers worked)
Bonus:
ServerAlias www.example.com example.com
(fixed https://www.example.com not found)
take this code to you .htaccess file
Redirect HTTP to HTTPS automatically
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
The above things are for the Apache server only. What if running PHP at tomcat?
So you can use PHP code, whether it is Apache/tomcat/Nginx etc...
if (!((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
$_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'))){
$redirect = 'https://' . str_replace($_SERVER['SERVER_PORT'], 8443, $_SERVER['HTTP_HOST']) . $_SERVER['REQUEST_URI'];
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $redirect);
exit();
}
After lots of tries by considering without www and with www this works this
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} (www\.)?yourdomain.com
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Through .htaccess This will help.
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
Also, Refer this for More Detail. How To Redirect Http To Https?
I found a method to force all pages of my site redirect from http to analog of pages on https that work for me.
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
This redirects all the URLs to https and www
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTPS_HOST} !^www.example.com$ [NC,OR]
RewriteCond %{HTTP_HOST} !^www.example.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
If you want to do it from the tomcat server follow the below steps
In a standalone Apache Tomcat (8.5.x) HTTP Server, how can configure it so if a user types www.domain.com, they will be automatically forwarded to https(www.domain.com) site.
The 2 step method of including the following in your [Tomcat_base]/conf/web.xml before the closing tag
step 1:
<security-constraint>
<web-resource-collection>
<web-resource-name>HTTPSOnly</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
and setting the [Tomcat_base]/conf/server.xml connector settings:
step 2:
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="80" protocol="HTTP/1.1" redirectPort="443"/>
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="[keystorelocation]" type="RSA" />
</SSLHostConfig>
</Connector>
Note: If you already did the https configuration and trying to redirect do step 1 only.
Not only can you do this in your .htaccess file, you should be doing this period. You will also want to follow the steps here to get your site listed on the HSTS preload list after you implement this redirect so that any requests to the insecure http version of your website never make it past the user agent. Instead, the user agent checks the requested URI against a baked in list of https only websites and, if the requested URI is on that list, changes the protocol from http to https before transmitting the request to the server. Therefore, the insecure request never makes it out into the wild and never hits the server. Eventually when the internet changes over to https only the HSTS preload list will not be needed. Until then, every site should be using it.
In order to perform the redirect, we need to enable the rewrite engine and then redirect all traffic from the http port 80 to https.
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://yourwebsite.tld/$1 [L,R=301]
I tried all .htaccess configurations I could find on the internet but none worked.
Then, I realized Apache discourages using mod_rewrite.
My solution was to edit apache configuration files under the following folder:
/etc/apache2/sites-enabled
You will have one mandatory file named 000-default.conf and an ssl configuration file named 000-default-le-ssl.conf (if you have installed ssl certificate from letsencrypt/certbot). However, these files can be named differently depending on the file names you provided when setting up the site.
In 000-default.conf, I edited the following inside <VirtualHost *:80> as:
<VirtualHost *:80>
ServerName example.com
Redirect / https://example.com/
</VirtualHost>
In 000-default-le-ssl.conf, I edited the following inside <VirtualHost *:80> as:
<VirtualHost *:80>
ServerName example.com
Redirect / https://example.com/
</VirtualHost>
No other redirection is needed.
Save the file then restart the apache server using sudo service apache2 restart
I was actually trying to get this to work on an EC2 instance without a load balancer since that costs money. I've read everywhere that .htaccess isn't the "right" way to do it. Obviously, it will work, but I was trying to keep things by the book. I was following all of the examples to update the httpd.conf file and adding a lot of unnecessary stuff. It turns out the only line you really need is this:
Redirect permanent / https://www.yourdomain.com
My problem was that originally I had added this in a VirtualHost tag inside of httpd.conf, which is what a lot of posts tell you to do, but it wasn't working. It turns out there was a separate conf file stored in /etc/httpd/conf.d called yourdomain.conf which already had the VirtualHost tag and was overriding my httpd.conf settings. I just added the above line inside of it and voila, it instantly redirected to https. There is no need for the separate VirtualHost for port 443.
It's working now and the VirtualHost tag looks like this:
<VirtualHost *:80>
ServerName yourdomain.com
DocumentRoot /var/www/html
ServerAlias www.yourdomain.com
ErrorLog /var/www/error.log
CustomLog /var/www/requests.log combined
Redirect permanent / https://www.yourdomain.com
</VirtualHost>
Note: I already had TLS setup with a FREE certificate from certbot (Love those guys) and was just trying to redirect regular http calls to the working https site.
If you are using Apache, mod_rewrite is the easiest solution, and has a lot of documentation online how to do that. For example: http://www.askapache.com/htaccess/http-https-rewriterule-redirect.html
A different edge to this problem is when a Load Balancer comes into play.
The situation is as follows:
- Traffic from browser to Load Balancer, and back, is (should be) HTTPS
- Traffic between Load Balancer and actual WebServer is HTTP.
So, all server request variables in PHP or Apache show that the connection is just HTTP. And the HTTP and HTTPS directories on the Server are the same.
The RewriteCondition in the approved answer does not work.
It gives either a loop or it just doesn't work.
Question is: How to get this working on a Load Balancer.
(Or is the Load Balancer configured wrong. Which is what I'm hoping for because then I can move the problem over to the WebHosting company :-) )
If you're using an Amazon Web Services Elastic Load Balancer which accepts https traffic and routes it to your server(s) with http, the correct way to redirect all http traffic to https is described here: https://aws.amazon.com/premiumsupport/knowledge-center/redirect-http-https-elb
Use the X-Forwarded-Proto header (contains http or https) which is always included in http requests from the load balancer, as described here: https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html
In the httpd.conf file:
<VirtualHost *:80>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
</VirtualHost>
Or in your root .htaccess file:
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
Bonus: it will not try to redirect http traffic on your local development machine.
It works for me:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
and for example, http://server/foo?email=someone%40example.com redirects normally without any issues.
The file .htaccess located in the website root folder (for example named public_html).
It is possible to use
RewriteCond %{SERVER_PORT} !^443$ instead RewriteCond %{HTTPS} !on

.htaccess for MODx Evo site behind Cloudflare with https

Looks like a bit easy question but I can't done that right, so I'd ask you for a little help:
I have some small site made on MODx Evo. It is placed behind CloudFlare (free tariff, very basic features used), mainly for their free https. Now I try to set only one address as a base one:
http://example.org
https://example.org <-- this one should be base
http://www.example.org
https://www.example.org
I do use default MODx Evo .htaccess to provide nice URLs and some basic PHP settings, which looks like this:
AddDefaultCharset utf-8
RewriteEngine On
RewriteBase /
# Fix Apache internal dummy connections from breaking [(site_url)] cache
RewriteCond %{HTTP_USER_AGENT} ^.*internal\ dummy\ connection.*$ [NC]
RewriteRule .* - [F,L]
# Exclude /assets and /manager directories and images from rewrite rules
RewriteRule ^(manager|assets|js|css|images|img)/.*$ - [L]
RewriteRule \.(jpg|jpeg|png|gif|ico)$ - [L]
# For Friendly URLs
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
Here is everything but the part which does the redirect from www to non-www domain, and it is stock settings.
Now I need to do another two redirect conditions:
http -> https
www -> non-www
This is where I'm stuck. I can easily redirect non-www to www, but as I add http/https part, I'm getting 301 loop.
The site itself is on Apache (the Cloudflare adds their special Nginx version).
Please advice what should I add to the .htaccess shown above to have all 3 domain variants shown above redirected nicely to https://example.org one?
To my great surprise, this was possible to do with Page Rules on Cloudflare itself, which is the best solution as for me, since no backend (like my server behind the Cloudflare) involved.
Thanks Cloudflare!
.httacces may not work
I founded solution by edit config (https://gitlab.com/snippets/1906338)
To fix https thro cloudflare needs edit var $secured like this in manager/includes/config.inc.php - add checking cloudflare $_SERVER["HTTP_CF_VISITOR"]
$secured = (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') ||
(isset($_SERVER["HTTP_CF_VISITOR"]) && $_SERVER["HTTP_CF_VISITOR"] == '{"scheme":"https"}');

Redirect HTTPS to HTTP for one directory while ISAPI rewrite in place

I've got a site (example.com) and a blog (externalblog.com) which is hosted externally and reverse-proxied using ISAPI rewrite. So if you go to www.example.com/blog you're actually on externalblog.com, but the URL is masked.
I've got this working with a number of sites, but the issue is when the parent site uses HTTPS, whereas the blog is only HTTP. When visitors attempt to follow old links, the blog posts will show normally under the https version of the url, but the stylesheets are all broken and a "no certificate" warning is shown.
I need an htaccess rule that will do 2 things:
Forward anyone attempting to access an https version of a blog post only (ie anything within www.example.com/blog) to the http version instead.
Forward anyone attempting to visit example.com/blog (without the www) to http://www.example.com/blog instead of the https version, which it currently does.
However I've like the rules to only affect www.example.com/blog and nothing else on example.com. My current rule for ISAPI rewrite on example.com is as follows:
RewriteRule ^blog(.+)$ http://www.externalblog.com$1 [R=301,L]
This works correctly and is based on an article online called "using reverse proxying to pull a wordpress blog into your domain" – I can't add any more links here due to not having enough reputation.
Any help would be much appreciated.
EDIT: I tried the following
RewriteCond %{HTTPS} on
RewriteCond %{THE_REQUEST} ^[A-Z]+\s/blog [NC]
RewriteRule ^blog(.+)$ http://www.externalblog.com$1 [R=301,L]
This works as far as rewriting https to http – but reverse proxy URL masking no longer kicks in.
Your explanation is rather unclear, so sorry if my answer will be unrelated. I suppose you are trying to force everything under www.example.com/blog to be HTTPS, instead of HTTP? Then try this rule:
RewriteEngine On
# HTTP to HTTPS redirect rule
RewriteCond %{HTTPS} off [NC]
RewriteCond %{HTTP:Host} ^www\.example\.com$ [NC]
RewriteRule ^(blog/.*)$ https://www.example.com/$1 [NC, R=301, L]
# No www. to www. redirect rule
RewriteCond %{HTTP:Host} ^example\.com$ [NC]
RewriteRule ^(blog/.*)$ https://www.example.com/$1 [NC, R=301, L]
# Your proxy rule goes here, I suppose it looks like:
RewriteRule ^blog(/.*)$ http://www.externalblog.com$1 [NC, P]

How to redirect all HTTP requests to HTTPS using .htaccess rules?

I'm trying to redirect all insecure HTTP requests on my site (e.g. http://www.example.com) to HTTPS (https://www.example.com). How can I do this in .htaccess file?
By the way, I'm using PHP.
The Apache docs recommend against using a rewrite:
To redirect http URLs to https, do the following:
<VirtualHost *:80>
ServerName www.example.com
Redirect / https://www.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName www.example.com
# ... SSL configuration goes here
</VirtualHost>
This snippet should go into main server configuration file, not into .htaccess as asked in the question.
This article might have come up only after the question was asked and answered, but seems to be the current way to go.
Update: Although this answer has been accepted a few years ago, note that its approach is now recommended against by the Apache documentation. Use a Redirect instead. See this answer.
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
I'd recommend with 301 redirect:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
As I was saying in this question, I'd suggest you avoid redirecting all HTTP requests to their HTTPS equivalent blindly, as it may cause you a false impression of security. Instead, you should probably redirect the "root" of your HTTP site to the root of your HTTPS site and link from there, only to HTTPS.
The problem is that if some link or form on the HTTPS site makes the client send a request to the HTTP site, its content will be visible, before the redirection.
For example, if one of your pages served over HTTPS has a form that says <form action="http://example.com/doSomething"> and sends some data that shouldn't be sent in clear, the browser will first send the full request (including entity, if it's a POST) to the HTTP site first. The redirection will be sent immediately to the browser and, since a large number of users disable or ignore the warnings, it's likely to be ignored.
Of course, the mistake of providing the links that should be to the HTTPS site but that end up being for the HTTP site may cause problems as soon as you get something listening on the HTTP port on the same IP address as your HTTPS site. However, I think keeping the two sites as a "mirror" only increases the chances of making mistakes, as you may tend to make the assumption that it will auto-correct itself by redirecting the user to HTTPS, whereas it's often too late. (There were similar discussions in this question.)
This is the html redirect approach it works but not the best.
<meta http-equiv="Refresh" content="0;URL=https://www.example.com" />
PHP approach
<?php
function redirectTohttps() {
if ($_SERVER['HTTPS']!="on") {
$redirect= "https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
header("Location:$redirect");
}
}
?>
.htaccess approch
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
copied from:
www.letuslook.org
I found out that the best way for https and www on domain is
RewriteCond %{HTTPS} off
RewriteCond %{HTTPS_HOST} !^www.example.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
I like this method of redirecting from http to https. Because I don't need to edit it for each site.
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
Using the following code in your .htaccess file automatically redirects visitors to the HTTPS version of your site:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
If you have an existing .htaccess file:
Do not duplicate RewriteEngine On.
Make sure the lines beginning RewriteCond and RewriteRule immediately follow the already-existing RewriteEngine On.
The best solution depends on your requirements. This is a summary of previously posted answers with some context added.
If you work with the Apache web server and can change its configuration, follow the Apache documentation:
<VirtualHost *:80>
ServerName www.example.com
Redirect "/" "https://www.example.com/"
</VirtualHost>
<VirtualHost *:443>
ServerName www.example.com
# ... SSL configuration goes here
</VirtualHost>
But you also asked if you can do it in a .htaccess file. In that case you can use Apache's RewriteEngine:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L]
If everything is working fine and you want browsers to remember this redirect, you can declare it as permanent by changing the last line to:
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
But be careful if you may change your mind on this redirect. Browsers remember it for a very long time and won't check if it changed.
You may not need the first line RewriteEngine On depending on the webserver configuration.
If you look for a PHP solution, look at the $_SERVER array and the header function:
if (!$_SERVER['HTTPS']) {
header("Location: https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
}
This is the proper method of redirecting HTTP to HTTPS using .htaccess according to GoDaddy.com. The first line of code is self-explanatory. The second line of code checks to see if HTTPS is off, and if so it redirects HTTP to HTTPS by running the third line of code, otherwise the third line of code is ignored.
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
https://www.godaddy.com/help/redirect-http-to-https-automatically-8828
Add the following code to the .htaccess file:
Options +SymLinksIfOwnerMatch
RewriteEngine On
RewriteCond %{SERVER_PORT} !=443
RewriteRule ^ https://[your domain name]%{REQUEST_URI} [R,L]
Where [your domain name] is your website's domain name.
You can also redirect specific folders off of your domain name by replacing the last line of the code above with:
RewriteRule ^ https://[your domain name]/[directory name]%{REQUEST_URI} [R,L]
Do everything that is explained above for redirection. Just add "HTTP Strict Transport Security" to your header. This will avoid man in the middle attack.
Edit your apache configuration file (/etc/apache2/sites-enabled/website.conf and /etc/apache2/httpd.conf for example) and add the following to your VirtualHost:
# Optionally load the headers module:
LoadModule headers_module modules/mod_headers.so
<VirtualHost 67.89.123.45:443>
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
</VirtualHost>
https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
To redirect all http requests to https , you can use :
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [NE,L,R]
If mod-rewrite isn't enabled and you are on apache 2.4, you can also use a Redirect inside if directive to redirect http requests to https .
Apache 2.4.
<if "%{HTTPS} !~ /on/">
Redirect / https://www.example.com/
</if>
If you are in a situation where your cannot access the apache config directly for your site, which many hosted platforms are still restricted in this fashion, then I would actually recommend a two-step approach. The reason why Apache themselves document that you should use their configuration options first and foremost over the mod_rewrite for HTTP to HTTPS.
First, as mentioned above, you would setup your .htaccess mod_rewrite rule(s):
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Then, in your PHP file(s) (you need to do this where ever it would be appropriate for your situation, some sites will funnel all requests through a single PHP file, others serve various pages depending on their needs and the request being made):
<?php if ($_SERVER['HTTPS'] != 'on') { exit(1); } ?>
The above needs to run BEFORE any code that could potentially expose secure data in an unsecured environment. Thus your site uses automatic redirection via HTACCESS and mod_rewrite, while your script(s) ensure no output is provided when not accessed through HTTPS.
I guess most people don't think like this, and thus Apache recommends that you don't use this method where possible. However, it just takes an extra check on the development end to ensure your user's data is secure. Hopefully this helps someone else who might have to look into using non-recommended methods due to restrictions on our hosting services end.
Unless you need mod_rewrite for other things, using Apache core IF directive is cleaner & faster:
<If "%{HTTPS} == 'off'">
Redirect permanent / https://yoursite.com/
</If>
You can add more conditions to the IF directive, such as ensure a single canonical domain without the www prefix:
<If "req('Host') != 'myonetruesite.com' || %{HTTPS} == 'off'">
Redirect permanent / https://myonetruesite.com/
</If>
There's a lot of familiarity inertia in using mod_rewrite for everything, but see if this works for you.
More info: https://httpd.apache.org/docs/2.4/mod/core.html#if
To see it in action (try without www. or https://, or with .net instead of .com): https://nohodental.com/ (a site I'm working on).
Redirect 301 / https://example.com/
(worked for me when none of the above answers worked)
Bonus:
ServerAlias www.example.com example.com
(fixed https://www.example.com not found)
take this code to you .htaccess file
Redirect HTTP to HTTPS automatically
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
The above things are for the Apache server only. What if running PHP at tomcat?
So you can use PHP code, whether it is Apache/tomcat/Nginx etc...
if (!((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
$_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'))){
$redirect = 'https://' . str_replace($_SERVER['SERVER_PORT'], 8443, $_SERVER['HTTP_HOST']) . $_SERVER['REQUEST_URI'];
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $redirect);
exit();
}
After lots of tries by considering without www and with www this works this
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} (www\.)?yourdomain.com
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Through .htaccess This will help.
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
Also, Refer this for More Detail. How To Redirect Http To Https?
I found a method to force all pages of my site redirect from http to analog of pages on https that work for me.
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
This redirects all the URLs to https and www
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTPS_HOST} !^www.example.com$ [NC,OR]
RewriteCond %{HTTP_HOST} !^www.example.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
If you want to do it from the tomcat server follow the below steps
In a standalone Apache Tomcat (8.5.x) HTTP Server, how can configure it so if a user types www.domain.com, they will be automatically forwarded to https(www.domain.com) site.
The 2 step method of including the following in your [Tomcat_base]/conf/web.xml before the closing tag
step 1:
<security-constraint>
<web-resource-collection>
<web-resource-name>HTTPSOnly</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
and setting the [Tomcat_base]/conf/server.xml connector settings:
step 2:
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="80" protocol="HTTP/1.1" redirectPort="443"/>
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="[keystorelocation]" type="RSA" />
</SSLHostConfig>
</Connector>
Note: If you already did the https configuration and trying to redirect do step 1 only.
Not only can you do this in your .htaccess file, you should be doing this period. You will also want to follow the steps here to get your site listed on the HSTS preload list after you implement this redirect so that any requests to the insecure http version of your website never make it past the user agent. Instead, the user agent checks the requested URI against a baked in list of https only websites and, if the requested URI is on that list, changes the protocol from http to https before transmitting the request to the server. Therefore, the insecure request never makes it out into the wild and never hits the server. Eventually when the internet changes over to https only the HSTS preload list will not be needed. Until then, every site should be using it.
In order to perform the redirect, we need to enable the rewrite engine and then redirect all traffic from the http port 80 to https.
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://yourwebsite.tld/$1 [L,R=301]
I tried all .htaccess configurations I could find on the internet but none worked.
Then, I realized Apache discourages using mod_rewrite.
My solution was to edit apache configuration files under the following folder:
/etc/apache2/sites-enabled
You will have one mandatory file named 000-default.conf and an ssl configuration file named 000-default-le-ssl.conf (if you have installed ssl certificate from letsencrypt/certbot). However, these files can be named differently depending on the file names you provided when setting up the site.
In 000-default.conf, I edited the following inside <VirtualHost *:80> as:
<VirtualHost *:80>
ServerName example.com
Redirect / https://example.com/
</VirtualHost>
In 000-default-le-ssl.conf, I edited the following inside <VirtualHost *:80> as:
<VirtualHost *:80>
ServerName example.com
Redirect / https://example.com/
</VirtualHost>
No other redirection is needed.
Save the file then restart the apache server using sudo service apache2 restart
I was actually trying to get this to work on an EC2 instance without a load balancer since that costs money. I've read everywhere that .htaccess isn't the "right" way to do it. Obviously, it will work, but I was trying to keep things by the book. I was following all of the examples to update the httpd.conf file and adding a lot of unnecessary stuff. It turns out the only line you really need is this:
Redirect permanent / https://www.yourdomain.com
My problem was that originally I had added this in a VirtualHost tag inside of httpd.conf, which is what a lot of posts tell you to do, but it wasn't working. It turns out there was a separate conf file stored in /etc/httpd/conf.d called yourdomain.conf which already had the VirtualHost tag and was overriding my httpd.conf settings. I just added the above line inside of it and voila, it instantly redirected to https. There is no need for the separate VirtualHost for port 443.
It's working now and the VirtualHost tag looks like this:
<VirtualHost *:80>
ServerName yourdomain.com
DocumentRoot /var/www/html
ServerAlias www.yourdomain.com
ErrorLog /var/www/error.log
CustomLog /var/www/requests.log combined
Redirect permanent / https://www.yourdomain.com
</VirtualHost>
Note: I already had TLS setup with a FREE certificate from certbot (Love those guys) and was just trying to redirect regular http calls to the working https site.
If you are using Apache, mod_rewrite is the easiest solution, and has a lot of documentation online how to do that. For example: http://www.askapache.com/htaccess/http-https-rewriterule-redirect.html
A different edge to this problem is when a Load Balancer comes into play.
The situation is as follows:
- Traffic from browser to Load Balancer, and back, is (should be) HTTPS
- Traffic between Load Balancer and actual WebServer is HTTP.
So, all server request variables in PHP or Apache show that the connection is just HTTP. And the HTTP and HTTPS directories on the Server are the same.
The RewriteCondition in the approved answer does not work.
It gives either a loop or it just doesn't work.
Question is: How to get this working on a Load Balancer.
(Or is the Load Balancer configured wrong. Which is what I'm hoping for because then I can move the problem over to the WebHosting company :-) )
If you're using an Amazon Web Services Elastic Load Balancer which accepts https traffic and routes it to your server(s) with http, the correct way to redirect all http traffic to https is described here: https://aws.amazon.com/premiumsupport/knowledge-center/redirect-http-https-elb
Use the X-Forwarded-Proto header (contains http or https) which is always included in http requests from the load balancer, as described here: https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html
In the httpd.conf file:
<VirtualHost *:80>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
</VirtualHost>
Or in your root .htaccess file:
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
Bonus: it will not try to redirect http traffic on your local development machine.
It works for me:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
and for example, http://server/foo?email=someone%40example.com redirects normally without any issues.
The file .htaccess located in the website root folder (for example named public_html).
It is possible to use
RewriteCond %{SERVER_PORT} !^443$ instead RewriteCond %{HTTPS} !on

Why do my forms break when using an .htaccess redirect?

During development, I used subdomain.domain.com and everything worked.
Moving to live, the files are under www, but I wanted to use domain.com, and that's making certain functionalities not work as follows.
I got a dedicated SSL certificate for domain.com, so I have this in my htaccess, and my SSL works fine:
# Redirect www.domain.com to domain.com
RewriteCond %{HTTP_HOST} ^www.domain.com [NC]
RewriteRule ^(.*)$ http://domain.com/$1 [L,R=301]
However for some reason that breaks some other functionality where a form gets reposted and I can't figure out why. But if I change htaccess to this:
# Redirect domain.com to www.domain.com
RewriteCond %{HTTP_HOST} ^domain.com [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [L,R=301]
then the broken functionality works, but the SSL doesn't.
Before I go invest in an SSL for www.domain.com, I wanted to check with the experts here to see if there is something simple I can do to my htaccess file to make both scenarios work.
Many thanks in advance!
A visible 301 redirect is losing its POST data. From RFC 2616:
If the 301 status code is received in
response to a request other than GET
or HEAD, the user agent MUST NOT
automatically redirect the request
unless it can be confirmed by the
user, since this might change the
conditions under which the request was
issued.
So, you have to fix the forms, not the .htaccess.

Resources