173
votes

How do you redirect HTTPS to HTTP?. That is, the opposite of what (seemingly) everyone teaches.

I have a server on HTTPS for which I paid an SSL certification for and a mirror for which I haven't and keep around for just for emergencies so it doesn't merit getting a certification for.

On my client's desktops I have SOME shortcuts which point to http://production_server and https://production_server (both work). However, I know that if my production server goes down, then DNS forwarding kicks in and those clients which have "https" on their shortcut will be staring at https://mirror_server (which doesn't work) and a big fat Internet Explorer 7 red screen of uneasyness for my company.

Unfortunately, I can't just switch this around at the client level. These users are very computer illiterate: and are very likely to freak out from seeing HTTPS "insecurity" errors (especially the way Firefox 3 and Internet Explorer 7 handle it nowadays: FULL STOP, kind of thankfully, but not helping me here LOL).

It's very easy to find Apache solutions for http->https redirection, but for the life of me I can't do the opposite.

Ideas?

11
DO NOT do that ! HTTPS redirects from HTTP are extremely dangerous (and in fact will be blocked by all browsers soon due to abuse), espacially if this is node via silent HTTP status (but the same is true if this is done by javascript), unless either : - (1) there's a transient HTTPS parking page inviting users to fllow a link by clicking it actively; or : - (2) the HTTPS redirects to HTTP on exactly the SAME domain AND the redirects does not change the content type requested. Allowing it in browsers has allowed lot of malwares to pass isolation. Such redirects are very deceptive. - verdy_p
This looks like an internal site, where the OP knows whats going on with it, and thus not dangerous... If this was a web facing server, I'd agree with you, but a internal, local only webserver, a redirect in this fashion would not be an issue. - Stese
@verdy_p I am working on HTTPS to HTTP 302 redirects, the case of captive portals. Can you point me to documentation that you are referring to? - jprusakova
For your captive portal, never ever perform any HTTPS to HTTP 302 redirect except if this is exactly to the same domain (not even a subdomain). And as there's a high risk of information disclosure, beware of session tokens and cookies passed transparently with the redirect ! You should know that HTTP targets can be tweaked and information taken by malware transparent proxies and even by malicious DNS: your custoer mayu not even know that yur HTTP-only target will be unreachable and will actually go to a blackhat! So never do that on HTTPS links that contain private session/cookies/requests. - verdy_p
Such HTTPS 302 redirect are always security hole in your HTTPS site. The huge risk is having sessions stolen and your authenticated users having their private accounts harvested. And in all case, NEVER do such redirects for loading javascripts, or active multimedia: this is an open door in the HTTPS "sandbox" realm. Really consider doing something the reverse: redirect HTTP to HTTPS (notably your main portal or static public pages that don't need private data/sessions/cookies) and use HTTPS for everelse. If you ever need to get from HTTPS to HTTP, use standard links (in distinct requests) - verdy_p

11 Answers

134
votes

This has not been tested but I think this should work using mod_rewrite

RewriteEngine On
RewriteCond %{HTTPS} on
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI}
73
votes

Keep in mind that the Rewrite engine only kicks in once the HTTP request has been received - which means you would still need a certificate, in order for the client to set up the connection to send the request over!

However if the backup machine will appear to have the same hostname (as far as the client is concerned), then there should be no reason you can't use the same certificate as the main production machine.

12
votes

Based on ejunker's answer, this is the solution working for me, not on a single server but on a cloud enviroment

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{ENV:HTTPS} on
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
11
votes

For those that are using a .conf file.

<VirtualHost *:443>
    ServerName domain.com
    RewriteEngine On
    RewriteCond %{HTTPS} on
    RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI}

    SSLEngine on
    SSLCertificateFile /etc/apache2/ssl/domain.crt
    SSLCertificateKeyFile /etc/apache2/ssl/domain.key
    SSLCACertificateFile /etc/apache2/ssl/domain.crt

</VirtualHost>
8
votes

If none of the above solutions work for you (they did not for me) here is what worked on my server:

RewriteCond %{HTTPS} =on
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [L,R=301]
5
votes

all the above did not work when i used cloudflare, this one worked for me:

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

and this one definitely works without proxies in the way:

RewriteCond %{HTTPS} on
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
3
votes

It is better to avoid using mod_rewrite when you can.

In your case I would replace the Rewrite with this:

    <If "%{HTTPS} == 'on'" >
            Redirect permanent / http://production_server/
    </If>

The <If> directive is only available in Apache 2.4+ as per this blog here.

2
votes

this works for me.

<VirtualHost *:443>
    ServerName www.example.com
    # ... SSL configuration goes here
    Redirect "https://www.example.com/" "http://www.example.com/"
</VirtualHost>

<VirtualHost *:80>
    ServerName www.example.com
    # ... 
</VirtualHost>

be sure to listen to both ports 80 and 443.

0
votes

None of the answer works for me on Wordpress website but following works ( it's similar to other answers but have a little change)

RewriteEngine On
RewriteCond %{HTTPS} on
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
0
votes

If you are looking for an answer where you can redirect specific url/s to http then please update your htaccess like below

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{THE_REQUEST} !/(home/panel/videos|user/profile) [NC] # Multiple urls
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{HTTPS} on
RewriteCond %{THE_REQUEST} /(home/panel/videos|user/profile) [NC] # Multiple urls
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

It worked for me :)

-7
votes

As far as I'm aware of a simple meta refresh also works without causing errors:

<meta http-equiv="refresh" content="0;URL='http://www.yourdomain.com/path'">