How to always remove WWW from a url with mod_rewrite? - apache

I'm using the following to try and remove WWW from the url:
RewriteCond %{HTTP_HOST} ^example.com$ [NC]
RewriteRule (.*) http://example.com$1 [R=301]
But for some reason it doesn't work. Any suggestions?

Here’s a more generalized solution:
RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [L,R=301]

Try:
RewriteCond %{HTTP_HOST} ^www\.example\.com$
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]
And without mod_rewrite:
<VirtualHost 10.0.0.1:80>
ServerName www.example.com
Redirect permanent / http://example.com/
</VirtualHost>
Virtual hosts can be used by completing the steps in the following URL: Setting Up A Virtual Host in Apache.

As a minor tweak of Kyle's answer, I'd put a / in the RewriteRule match condition, like
RewriteCond %{HTTP_HOST} ^www\.example\.com$
RewriteRule ^/(.*)$ http://example.com/$1 [R=301,L]
Otherwise, you get a double slash as a result.
http://www.example.com/smth -> http://example.com//smth

I would always use 307 (temporary redirect) first because if you get it wrong some browsers cache it permanently. I ended up installing Google Chrome just because I couldn't get my Firefox to forget a bad redirect even when I deleted the whole cache.

Here is a solution if you don't want a hard coded domain name. Don't forget to start the rewrite engine or this won't work!
# Start rewrite engine
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine On
</IfModule>
# Rewrite "www.example.com -> example.com"
<IfModule mod_rewrite.c>
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
</IfModule>

Related

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

.htaccess redirect http to https

I have an old url (www1.test.net) and I would like to redirect it to https://www1.test.net
I have implemented and installed our SSL certificate on my site.
This is my old file .htaccess:
RewriteEngine On
RewriteRule !\.(js|gif|jpg|png|css|txt)$ public/index.php [L]
RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^(.*)$ public/$1 [L]
How can I configure my .htaccess file so that url auto redirect to https?
Thanks!
I use the following to successfully redirect all pages of my domain from http to https:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Note this will redirect using the 301 'permanently moved' redirect, which will help transfer your SEO rankings.
To redirect using the 302 'temporarily moved' change [R=302,L]
Update 2016
As this answer receives some attention, I want to hint to a more recommended way on doing this using Virtual Hosts: Apache: Redirect SSL
<VirtualHost *:80>
ServerName mysite.example.com
Redirect permanent / https://mysite.example.com/
</VirtualHost>
<VirtualHost _default_:443>
ServerName mysite.example.com
DocumentRoot /usr/local/apache2/htdocs
SSLEngine On
# etc...
</VirtualHost>
Old answer, hacky thing
given that your ssl-port is not set to 80, this will work:
RewriteEngine on
# force ssl
RewriteCond %{SERVER_PORT} ^80$
RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
Note that this should be your first rewrite rule.
Edit: This code does the following. The RewriteCond(ition) checks wether the ServerPort of the request is 80 (which is the default http-port, if you specified another port, you would have to adjust the condition to it). If so, we match the whole url (.*) and redirect it to a https-url. %{SERVER_NAME} may be replaced with a specific url, but this way you don't have to alter the code for other projects. %{REQUEST_URI} is the portion of the url after the TLD (top-level-domain), so you will be redirected to where you came from, but as https.
This is the best for www and for HTTPS, for proxy and no proxy users.
RewriteEngine On
### 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]
### WWW & HTTPS
I force the https with following code:
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
Add this code at the end of your .htaccess file
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
In cases where the HTTPS/SSL connection is ended at the load balancer and all traffic is sent to instances on port 80, the following rule works to redirect non-secure traffic.
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Ensure the mod_rewrite module is loaded.
Searching for the best way to redirect, i've found this (coming from html5boilerplate) :
# ----------------------------------------------------------------------
# | HTTP Strict Transport Security (HSTS) |
# ----------------------------------------------------------------------
# Force client-side SSL redirection.
#
# If a user types `example.com` in their browser, even if the server
# redirects them to the secure version of the website, that still leaves
# a window of opportunity (the initial HTTP connection) for an attacker
# to downgrade or redirect the request.
#
# The following header ensures that browser will ONLY connect to your
# server via HTTPS, regardless of what the users type in the browser's
# address bar.
#
# (!) Remove the `includeSubDomains` optional directive if the website's
# subdomains are not using HTTPS.
#
# http://www.html5rocks.com/en/tutorials/security/transport-layer-security/
# https://tools.ietf.org/html/draft-ietf-websec-strict-transport-sec-14#section-6.1
# http://blogs.msdn.com/b/ieinternals/archive/2014/08/18/hsts-strict-transport-security-attacks-mitigations-deployment-https.aspx
Header set Strict-Transport-Security "max-age=16070400; includeSubDomains"
Maybe it will help someone in 2017 ! :)
Insert this code in your .htaccess file. And it should work
RewriteCond %{HTTP_HOST} yourDomainName\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://yourDomainName.com/$1 [R,L]
This makes sure that redirects work for all combinations of intransparent proxies.
This includes the case client <http> proxy <https> webserver.
# behind proxy
RewriteCond %{HTTP:X-FORWARDED-PROTO} ^http$
RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=301,L]
# plain
RewriteCond %{HTTP:X-FORWARDED-PROTO} ^$
RewriteCond %{REQUEST_SCHEME} ^http$ [NC,OR]
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=301,L]
I had a problem with redirection also. I tried everything that was proposed on Stackoverflow. The one case I found by myself is:
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP:SSL} !=1 [NC]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
Adding the following to the top of the .htaccess
RewriteEngine On
RewriteCond %{ENV:HTTPS} !=on
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
This is what ended up working for me
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
Forcing HTTPS with the .htaccess File
==> Redirect All Web Traffic :-
To force all web traffic to use HTTPS, insert the following lines of code in the .htaccess file in your website’s root folder.
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
==> Redirect Only Specified Domain :-
To force a specific domain to use HTTPS, use the following lines of code in the .htaccess file in your website’s root folder:
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
If this doesn’t work, try removing the first two lines.
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
Make sure to replace example.com with the domain name you’re trying
force to https. Additionally, you need to replace www.example.com with
your actual domain name.
==> Redirect Specified Folder :-
If you want to force SSL on a specific folder, insert the code below into a .htaccess file placed in that specific folder:
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} folder
RewriteRule ^(.*)$ https://www.example.com/folder/$1 [R=301,L]
Make sure you change the folder reference to the actual folder name.
Then be sure to replace www.example.com/folder with your actual domain
name and folder you want to force the SSL on.
Replace your domain with domainname.com , it's working with me .
RewriteEngine On
RewriteCond %{HTTP_HOST} ^domainname\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.domainname.com/$1 [R,L]

generic non-www to www, and non-http to https

I have the following code for my .htaccess file that I've picked up from here and tried adapting it as I understand from .htaccess, yet I can't seem to get it to work (or maybe the browser has cached it but I can't seem to clear it).
Options -Indexes
Options +FollowSymlinks
<IfModule mod_rewrite.c>
########## FORCE SSL ##########
RewriteEngine On
RewriteBase /
# Non-secure requests to www.domain.com should redirect to https://www.domain.com
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^www\.%{HTTP_HOST} [NC]
RewriteRule ^(.*)$ https://www\.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# All secure (HTTPS) traffic should redirect to https://www.domain.com
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} !^www\.%{HTTP_HOST} [NC]
RewriteRule ^(.*)$ https://www\.%{HTTP_HOST}/$1 [L,R=301]
</IfModule>
I want to make it as generic a possible so I can simply copy and paste it to any site I make so no need to edit it each time - I guess I could also do this in PHP but I think it would be good if .htaccess is also there.
Another point is, can .htaccess be read if i were to go to www.domain.com/.htaccess or do I need to cover that in a 'deny all' kind of thing?
The second argument to the RewriteCond must be a regex, so it cannot contain a variable.
Try adding the following to your .htaccess file in place of the rules you had
#capture top level domain (.com or .co.uk)
RewriteCond %{HTTP_HOST} ([-_a-zA-Z0-9]+\.([a-zA-Z]{2,5}|co\.uk))$ [NC]
RewriteCond %{HTTP_HOST} (www\.)?(.+)$ [NC]
RewriteRule ^ - [E=MY_TLD:%2]
# Non-secure requests to www.domain.com should redirect to https://www.domain.com
RewriteCond %{HTTPS} off
RewriteRule ^ https://www\.%{ENV:MY_TLD}%{REQUEST_URI} [L,R=301]
# All secure (HTTPS) traffic should redirect to https://www.domain.com
RewriteCond %{HTTPS} on
#if host does not start with www
RewriteCond %{HTTP_HOST} !^www\.[-_a-zA-Z0-9]+\.([a-zA-Z]{2,5}|co\.uk)$ [NC]
RewriteRule ^ https://www\.%{ENV:MY_TLD}%{REQUEST_URI} [L,R=301]
Shortest version would be:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTP_HOST} (www\.)?(.+)$ [NC]
RewriteRule ^ https://www\.%2%{REQUEST_URI} [L,R=301]
Only (somewhat) downside would be that subdomain.example.com gets redirected to www.subdomain.example.com

need to remove www from 2nd level subdomain generically in Apache (using rewrite)

I have the problem but with many subdomains: E.g..
sub1.domain.com and new.domain.com and xsub.domain.com and many many more like this.
How do I remove the www from in front of any of these with one generic rule.
E.g. if someone types www..domain.com or http://www..domain.com to change it to
http://.domain.com
Thanks
You may use the rewrite module to remove the www. when it precedes a sub-domain. In this way, an address like: www.sub1.domain.com would be redirected to sub1.domain.com:
<IfModule mod_rewrite.c>
Options +FollowSymLinks
Options +Indexes
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !www.domain.com$ [NC]
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,NC,L]
</IfModule>
Modified tested solution but for http only.
#Allow domain of the form www.domain.com
RewriteCond %{HTTP_HOST} !^www\.([^\..]*)\.([^\..]*)$ [NC]
#Otherwise any other form must be rewritten to remove www
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
#Substitue the complete domain using group %1 in the parentheses of the above condition
RewriteRule ^(.*)$ http://%1/$1 [R=301,NC,L]
This will do the job, and return with http://
RewriteCond %{HTTP_HOST} ^www\.(.*)
RewriteRule ^(.*) http://%1/$1 [R,L]
For https, just add the s, as so:
RewriteCond %{HTTP_HOST} ^www\.(.*)
RewriteRule ^(.*) https://%1/$1 [R,L]
Note that this can be done in httpd.conf as well. Using .htaccess is popular but actually slows down the site, especially if there are nested directories.
You do need:
Options +FollowSymLinks
But you do not need Indexes.

Apache ssl redirect using mod_rewrite

I want to do this: if they do https://example.com I want to redirect them to https://www.example.com (add the www.). I have tried oodles of things to no avail.
Redirect https://example.com/<anything> to https://www.example.com/<anything>
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteCond %{SERVER_PORT} =443
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
This code is in httpd.conf but has been tried in .htaccess and ssl.conf.
Can anyone help?
Have you turned on Rewriting via RewriteEngine On or is mod_rewrite installed? Otherwise, your code should work.
The Redirect directive does only work on the URL path. But it’s possible with mod_rewrite. This rule will work in any configuration file:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.com$
RewriteCond %{SERVER_PORT} =443
RewriteRule ^ https://www.example.com%{REQUEST_URI} [L,R=301]
And don’t forget the obligatory RewriteEngine on like (Residuum already said)(1278432#1278432).
Use this:
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]
Of course, don't forget to replace "www.example.com" with your own domain.