force SSL and no WWW on Apache - apache

I'm having trouble coming up with the proper syntax to accomplish both forcing the SSL and no WWW.
EDIT
I've been able to accomplish each task separately but when combining the two i find myself stuck in a redirection loop.
working syntax to force no WWW:
RewriteCond %{HTTP_HOST} !^domain\.com$
RewriteRule (.*) http://domain.com/$1 [R=301,L]
My attempt to force no WWW and SSL
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{HTTP_HOST} !^domain\.com$
RewriteRule (.*) https://domain.com/$1 [R=301,L]
Thanks for any suggestions!

For SSL you could use something like:
Redirect / https://domain.com/
Place this only in the section of your virtual host you configure for HTTP, not HTTPS, to not run clients into endless loops.

Here's what I'm using on one of my sites - it seems to work a little better than most of the other methods I've seen:
# The code below tells apache to always require secure (ssl/tls) connections
# to the website. If a client tries connecting over port 80 (http://),
# then the client will be redirected to https:// (over port 443).
RewriteCond %{REMOTE_ADDR} !127\.0\.0\.0
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.com/$1 [R,L]
For the no-www rule, check out the .htaccess files on any open-source CMS, like Drupal or Wordpress, to see some of the best practices.

By 'no WWW' I assume you mean you want to remove any 'WWW.' prefix of the hostname? Try this:
RewriteCond "%{HTTP_HOST}" "^(?:www\.)?(.*)" [NC]
RewriteCond "%{HTTPS}" "=on"
RewriteRule "(.*)" "https://%1$1" [R=301,L]
If you're doing this in a .htaccess file, change that last line to
RewriteRule "(.*)" "https://%1/$1" [R=301,L]
If you want to be able to remove the 'WWW.' prefix regardless of SSL-ness or not, try this:
RewriteCond "%{HTTP_HOST}" "^(?:www\.)?(.*)" [NC]
RewriteCond "%{HTTPS}" "=on"
RewriteRule "(.*)" "https://%1/$1" [R=301,L]
RewriteCond "%{HTTP_HOST}" "^(?:www\.)?(.*)" [NC]
RewriteRule "(.*)" "http://%1/$1" [R=301,L]

I found this to work for a couple of my client sites:
# Force SSL
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule (.*) https://%1%{REQUEST_URI} [L,R=301]
# Rewrite all http to https
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

Related

I install a ssl on my vps,but the domain still has not https [duplicate]

I'm having trouble coming up with the proper syntax to accomplish both forcing the SSL and no WWW.
EDIT
I've been able to accomplish each task separately but when combining the two i find myself stuck in a redirection loop.
working syntax to force no WWW:
RewriteCond %{HTTP_HOST} !^domain\.com$
RewriteRule (.*) http://domain.com/$1 [R=301,L]
My attempt to force no WWW and SSL
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{HTTP_HOST} !^domain\.com$
RewriteRule (.*) https://domain.com/$1 [R=301,L]
Thanks for any suggestions!
For SSL you could use something like:
Redirect / https://domain.com/
Place this only in the section of your virtual host you configure for HTTP, not HTTPS, to not run clients into endless loops.
Here's what I'm using on one of my sites - it seems to work a little better than most of the other methods I've seen:
# The code below tells apache to always require secure (ssl/tls) connections
# to the website. If a client tries connecting over port 80 (http://),
# then the client will be redirected to https:// (over port 443).
RewriteCond %{REMOTE_ADDR} !127\.0\.0\.0
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.com/$1 [R,L]
For the no-www rule, check out the .htaccess files on any open-source CMS, like Drupal or Wordpress, to see some of the best practices.
By 'no WWW' I assume you mean you want to remove any 'WWW.' prefix of the hostname? Try this:
RewriteCond "%{HTTP_HOST}" "^(?:www\.)?(.*)" [NC]
RewriteCond "%{HTTPS}" "=on"
RewriteRule "(.*)" "https://%1$1" [R=301,L]
If you're doing this in a .htaccess file, change that last line to
RewriteRule "(.*)" "https://%1/$1" [R=301,L]
If you want to be able to remove the 'WWW.' prefix regardless of SSL-ness or not, try this:
RewriteCond "%{HTTP_HOST}" "^(?:www\.)?(.*)" [NC]
RewriteCond "%{HTTPS}" "=on"
RewriteRule "(.*)" "https://%1/$1" [R=301,L]
RewriteCond "%{HTTP_HOST}" "^(?:www\.)?(.*)" [NC]
RewriteRule "(.*)" "http://%1/$1" [R=301,L]
I found this to work for a couple of my client sites:
# Force SSL
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule (.*) https://%1%{REQUEST_URI} [L,R=301]
# Rewrite all http to https
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

htaccess rewrite from http to https

Currently I redirect all http users (www or non-www) of upscfever.com to http://upscfever.com/upsc-fever/index.html
using
RewriteEngine on
RewriteCond %{HTTP_HOST} ^upscfever\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.upscfever\.com$
RewriteRule ^/?$ "http\:\/\/upscfever\.com\/upsc\-fever\/index\.html" [R=301,L]
Now I want all users to shift to https so I modified as follows:
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^upscfever\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.upscfever\.com$
RewriteRule ^/?$ "https\:\/\/upscfever\.com\/upsc\-fever\/index\.html" [R=301,L]
So that all who type upscfever.com OR www.upscfever.com should go to
https://upscfever.com/upsc-fever/index.html - instead
Plus all links should be https. But its not working I get Page not found.
Your server has to setup the https first, depend on hosting vendor, if your hosting is vps you need to setup https for apache, install cert also.
You can find some instruction like this:
https://manual.seafile.com/deploy/https_with_apache.html
https://www.digicert.com/csr-ssl-installation/apache-openssl.htm
I think you want to make 3 different changes:
Change your .htaccess file to redirect requests to root to your custom index irrespective of the HTTPS or HTTP for the original request
RewriteEngine on
RewriteCond %{HTTP_HOST} ^upscfever\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.upscfever\.com$
RewriteRule ^/?$ "https://%{SERVER_NAME}/upsc-fever/index.html" [R,L]
There is no R=301 part here because I'm not sure it is really wise to make permanent such a redirect to an obscure inner URL.
Redirect all other non-HTTPS requests to HTTPS (preserving the rest of the URL):
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^upscfever\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.upscfever\.com$
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L]
Making this redirect permanent seems pretty safe.
Change all internal links in all of your HTML pages (or whatever backend generates them) to use protocol-relative // prefix or explicitly https:// instead of current http://. Preserve the protocol for the external links as is.
As for troubleshooting, you may use the Network tab of the Chrome DevTools (F12) to see exact server reply (note: enabling "Preserve log" and "Disable cache" flags is useful in such context)
You can do that using a single rule as follows in your site root .htaccess:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(?:www\.)?upscfever\.com$ [NC]
RewriteRule ^/?$ /upsc-fever/index.html [R=301,L]
This will redirect both http and https URLs.
You may try something like this:
RewriteEngine On
RewriteCond %{HTTP_HOST} !=""
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
I hope below code will do the work for you
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://famebooking.net/$1 [R,L]
just simply add above code in .htaccess below authorization header condition is written under RewriteEngine On
Let me know if that helps.

.htaccess rewrite to ssl with browser language detection and subdomain removal

I'm trying to rewrite any request to my ssl domain:
https://domain.com/
I got that working with the following rules:
# Remove any subdomain
RewriteCond %{HTTP_HOST} !^domain\.com$ [NC]
RewriteRule (.*) https://domain.com [R=301,L]
# Force ssl connection
RewriteCond %{SERVER_PORT} ^80$
RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
In addition I want to detect the browser language and if detected I want the redirect to the detected language but the first rule (remove subdomain and rewrite to ssl) should still match.
I've tried something like this to detect the browser language:
RewriteCond %{HTTP_HOST} =www.domain.com [NC]

RewriteCond %{HTTP:Accept-Language} ^de [NC]
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{REQUEST_URI} ^/$
RewriteRule .* http://www.domain.com/de/ [L,R=301]
How can I get this to work (at best with one redirect only)?

Redirect http to https via .htaccess not working

I've seen a few questions like this on here, but no answer seems to work. I just can't seem to figure this out. Here is my code:
# enable basic rewriting
RewriteEngine on
# enable symbolic links
Options +FollowSymLinks
# Primary Domain - Force the use of "https"
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
# Primary Domain - Force the use of "www"
RewriteCond %{http_host} ^example.org [nc]
RewriteRule ^(.*)$ https://www.example.org/$1 [r=301,nc]
# Primary Domain - .com to .org
RewriteCond %{HTTP_HOST} ^example.com$ [NC]
RewriteRule ^(.*)$ https://www.example.org/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^www.example.com$ [NC]
RewriteRule ^(.*)$ https://www.example.org/$1 [R=301,L]
# Primary Domain - .net to .org
RewriteCond %{HTTP_HOST} ^example.net$ [NC]
RewriteRule ^(.*)$ https://www.example.org/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^www.example.net$ [NC]
RewriteRule ^(.*)$ https://www.example.org/$1 [R=301,L]
So whenever I go to www.example.org or http://www.example.org it will NOT redirect. This is what is frustrating me. If I go to example.org or any of the other redirects, it works though. Am I setting this up wrong?
Also, where it says "HTTP_HOST", do I leave it as is? Like do I replace it with my http host?
Amie if you want to force www and https both you can check for the absence of www. or check if https is not On then redirect. So either way it will redirect. example.
# Primary Domain - Force the use of "https" and www
RewriteCond %{HTTP_HOST} !^www\. [OR]
RewriteCond %{HTTPS} !^on$
RewriteRule ^(.*)$ https://www.mydomain.org/$1 [R=301,L]
Replace mydomain.org with your domain.
Then you can have a htaccess file like this. I took the last two rules and combined them so you have a smaller htaccess file.
# enable basic rewriting
RewriteEngine on
# enable symbolic links
Options +FollowSymLinks
# Primary Domain - Force the use of "https" and www
RewriteCond %{HTTP_HOST} !^www\. [OR]
RewriteCond %{HTTPS} !^on$
RewriteRule ^(.*)$ https://www.mydomain.org/$1 [R=301,L]
# Primary Domain - .com to .org Or .net to .org
RewriteCond %{HTTP_HOST} ^(www\.)?mydomain\.(net|com)$ [NC]
RewriteRule ^(.*)$ https://www.mydomain.org/$1 [R=301,L]
Also, where it says "HTTP_HOST", do I leave it as is? Like do I
replace it with my http host?
%{HTTP_HOST} is a variable that contains the host sent with Http headers from the browser. So if someone requests http://mydomain.org/somepage.php that variable %{HTTP_HOST} will contain mydomain.org. You don't change it. You can use it to match things or set conditions like in the rules. Hope that answers your question.

htaccess redirect to https://www

I have the following htaccess code:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond !{HTTPS} off
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
I want my site to be redirected to https://www. with HTTPS, and enforcing the www. subdomain,
but when I access http://www. (without HTTPS), it does not redirect me to https://www with HTTPS.
To first force HTTPS, you must check the correct environment variable %{HTTPS} off, but your rule above then prepends the www. Since you have a second rule to enforce www., don't use it in the first rule.
RewriteEngine On
RewriteCond %{HTTPS} off
# First rewrite to HTTPS:
# Don't put www. here. If it is already there it will be included, if not
# the subsequent rule will catch it.
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Now, rewrite any request to the wrong domain to use www.
# [NC] is a case-insensitive match
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
About proxying
When behind some forms of proxying, whereby the client is connecting via HTTPS to a proxy, load balancer, Passenger application, etc., the %{HTTPS} variable may never be on and cause a rewrite loop. This is because your application is actually receiving plain HTTP traffic even though the client and the proxy/load balancer are using HTTPS. In these cases, check the X-Forwarded-Proto header instead of the %{HTTPS} variable. This answer shows the appropriate process
Michals answer worked for me, albeit with one small modification:
Problem:
when you have a single site security certificate, a browser that tries to access your page without https:// www. (or whichever domain your certificate covers) will display an ugly red warning screen before it even gets to receive the redirect to the safe and correct https page.
Solution
First use the redirect to the www (or whichever domain is covered by your certificate) and only then do the https redirect. This will ensure that your users are not confronted with any error because your browser sees a certificate that doesn't cover the current url.
#First rewrite any request to the wrong domain to use the correct one (here www.)
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
#Now, rewrite to HTTPS:
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
If you are using CloudFlare or a similar CDN you will get an infinite loop error with the %{HTTPS} solutions provided here. If you're a CloudFlare user you'll need to use this:
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
BAD SOLUTION AND WHY!
Don't ever use the solution below because when you are using their code that is something like:
RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.example.com%{REQUEST_URI} [L,R=301]
The browser goes to:
http://example.com
Then redirects to:
https://example.com
Then redirects to:
https://www.example.com
This is too much request to the server.
Most of the answers even accepted one has this problem.
BEST SOLUTION AND THE ANSWER
This code has an [OR] condition to prevent dual changes at url!
RewriteEngine on
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule (.*) https://www.example.com%{REQUEST_URI} [R=301,L]
This is the best way I found for Proxy and not proxy users
RewriteEngine On
### START WWW & HTTPS
# ensure www.
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# ensure https
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
### END WWW & HTTPS
There are a lot of solutions out there. Here is a link to the apache wiki which deals with this issue directly.
http://wiki.apache.org/httpd/RewriteHTTPToHTTPS
RewriteEngine On
# This will enable the Rewrite capabilities
RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
# This rule will redirect users from their original location, to the same location but using HTTPS.
# i.e. http://www.example.com/foo/ to https://www.example.com/foo/
# The leading slash is made optional so that this will work either in httpd.conf
# or .htaccess context
To redirect http:// or https:// to https://www you can use the following rule on all versions of apache :
RewriteEngine on
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ https://www.example.com%{REQUEST_URI} [NE,L,R]
Apache 2.4
RewriteEngine on
RewriteCond %{REQUEST_SCHEME} http [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ https://www.example.com%{REQUEST_URI} [NE,L,R]
Note that The %{REQUEST_SCHEME} variable is available for use since apache 2.4 .
If you are on CloudFlare, make sure you use something like this.
# BEGIN SSL Redirect
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
# END SSL Redirect
This will save you from the redirect loop and will redirect your site to SSL safely.
P.S. It is a good idea to if check the mod_rewrite.c!
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R]
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
Notes: Make sure you have done the following steps
sudo a2enmod rewrite
sudo service apache2 restart
Add Following in your vhost file, located at /etc/apache2/sites-available/000-default.conf
<Directory /var/www/html>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
Require all granted
</Directory>
Now your .htaccess will
work and your site will redirect to http:// to https://www
Similar to Amir Forsati's solution htaccess redirect to https://www but for variable domain name, I suggest:
RewriteEngine on
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%2%{REQUEST_URI} [R=301,L]
Set in your .htaccess file
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
I used the below code from this website, it works great https://www.freecodecamp.org/news/how-to-redirect-http-to-https-using-htaccess/
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.yourdomain.com/$1 [R,L]
Hope it helps
I try first answer and it doesnt work...
This work:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{ENV:HTTPS} !=on
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress