Redirect loops on cloudflare - .htaccess

I am using cloudflare to manage my domain.
Considering the following:
type = A, name = [mydomain].me, value = xx.xx.xx.xx.xx, TTL = automatic
type = A, name = www, value = xx.xx.xx.xx.xx, TTL = automatic
With the following page RULE:
https://[mydomain].me -> (301) http://[mydomain].me
The site is wordpress based and each configuration (wp-config, DB or otherwise) is stating [mydomain].me.
Still, while both chrome and safari on mobile works perfectly ok, safari (MAC) is saying too many redirects.
Any ideas? how can I debug the redirect that is happening? Or anything else?

Redirecting away from HTTPS isn't a great idea; but you should make sure that you have no conflicting rules in your .htaccess file and that HSTS (strict transport security) is turned off in CloudFlare. HSTS uses aggressive caching, there are instructions on how to clear this here.
Someone had some luck by deleting in /library/Cookies all files with "safari" in its name and the "HSTS.plist". Make sure you're happy deleting the relevent cache files before you do this though.

Make sure the "http" protocol is used in wordpress for the site's base url.

Related

Do I need to enable HSTS in addition to forcing HTTPS in .htaccess?

I know nothing about this stuff so please ELI5 in your replies.
Following the instructions from my provider, Dreamhost, I installed an SSL certificate and then added these lines to my .htaccess file to force HTTP requests to be rewritten to HTTPS requests.
# Redirect http requests to https
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Everything seems to be working correctly, ie: every time I try to access a page under that domain with HTTP, it is rewritten to HTTPS and the "Secure" icon shows in the address bar.
My question is, do I need to also enable HSTS? Reading about it, it seems to do the exact same thing as the previous changes to the .htaccess file. Here's an excerpt from A2 Hosting (not my provider):
Enabling HSTS
When HSTS is enabled for a site, web browsers automatically change any
insecure requests (http://) to secure requests (https://). All you
need to do to enable HSTS is add a header to your site's .htaccess
file. Web browsers recognize this header, and then take care of the
rest without any further intervention on your part.
They suggest adding this to .htaccess:
Header set Strict-Transport-Security "max-age=31536000" env=HTTPS
Another tutorial, this time specific to Dreamhost, says to enable HSTS along with forcing HTTPS in the .htaccess file, but doesn't really say why. This page suggests something slightly different:
Header set Strict-Transport-Security "max-age=31415926; includeSubDomains; preload" env=HTTPS
Do I need the "https rewrite" code snippet AND HSTS? Or is having only the "https rewrite" code snippet good enough? Do I need the HSTS code at all, and if so, what's the difference between the two lines of HSTS code in my post?
HSTS lets the browser know to only connect over https by default but each one of the different flags does something a bit different:
includeSubdomains
That means that if your site is on mydomain.com, the policy will apply to all subdomains (i.e. foo.mydomain.com, bar.mydomain.com, etc). Without this included. the policy only applies for the exact domain in question.
preload
While HSTS is great conceptually, the first time someone types mydomain.com the browser will try to contact your site on http scheme since it doesn't know that you have your site on https which gives a MITM attacker room to serve you malicious version of the site (aka TOFU problem).
To work around this, there is a centralized list for browsers for sites that should be contacted on https by default but to be able to get yourself on that list, you have to have the preload flag in that header. You can see more about this here.
The default, if a scheme (http or https) is not explicitly specified, is http.
Therefore a redirect is necessary to redirect it to your preferred https version since most visitors who type the URL will not include the scheme and so go to http version.
HTTP Strict-Transport-Security (HSTS) is a security method, to ensure you always stay on https. It is not really intended to do away with the need for the redirect. In particular HSTS works by sending your web browser a message (using a HTTP response header) to say "please only use https for this site, for the next X amount of time". This message should only be sent when visiting the site over https. Therefore if you do not redirect in the first place, then a lot of visitors may not even realise you have a https site and so will not get the HSTS instruction.
HSTS is mostly used as a way to change the default of a website to https, and to prevent man in the middle (MITM) attacks which might attempt to keep you on http: e.g. if you connect to a hacker's wifi network and go to your bank website, they will not be able to hijack this connection if it's done over https but will be able to if it's done over http, so attackers will intercept the http request and stop the redirect happening, to keep you on http and intercept all messages to and from your bank.
You can "preload" the HSTS instruction in web browser's code, which gives even more security, as you don't need to visit the site over https first to get the HSTS instruction. This should be caveated that there is basically no way back from this and this should only be considered if you really understand HSTS. There are many, many, many requests to remove sites from Preload list which takes a minimum of 3 months for Chrome (no guarantees for other browsers) and makes your site completely inaccessible during that time if you are not on https. So there is a real danger here! Particularly if some of your site is served over https (e.g. www.example.com) but some of it is not (e.g. intranet.example.com). This is a danger of HSTS as well but even more dangerous with preloading.
The other point to note is that many web agents will not use HSTS and especially not preload lists (e.g. Search Engine Crawlers, older browsers... etc). So again HSTS should be used on top of, instead of as a replacement to, a redirect.
HSTS is a great security measure and should be used by all sites (once they have stopped using http completely) but, like most security measures, does come with its own risks. So make sure you understand it before deploying it. I hate sites and tutorials that say turn it on without explaining it and the risks. In theory a site using HSTS may no longer need to redirect, but in practice it still will need to for the first visit and agents that don't understand or implement HSTS.
To summarise:
Always use redirects.
Strongly consider HSTS, but read up on it first, and start with a low max-age, and without includesubdomains and preload - until you truly understand what they mean.
if running a high risk site, then consider submitting your site to HSTS preload list as a high level of security, but again be aware of risks here. Only do this if you really understand HSTS and feel like you need this level of security.

Cloudflare Flexible SSL not working with vanilla Joomla site

I'm testing Flexible SSL on a newly installed Joomla site in preparation for the production site. However it doesn't seem to work.
Using default Joomla configuration: website loads, but content like CSS files and images are not loading, even though all the paths are relative. It's interesting to note that if I access the CSS files directly (with https) they show up fine.
If I configure Joomla for Force SSL, then the notorious redirect loop occurs.
What I've done so far:
- Set up Cloudflare page rule for http://mysub.domain.com/* to redirect to https, and making sure the subdomain mysub is routing through Cloudflare. This part is working, so the redirection works.
Installed and enabled the Cloudflare Joomla plugin
.htaccess file is NOT used in this case
When Joomla's Force SSL is set to No, the Joomla constant JURI::root() returns http://mysub.domain.com, even though the site is accessed via https://mysub.domain.com. This means that internally, Joomla still views this as a http site. The only way to change this is to enable Force SSL, but that will result in the redirection loop.
I have searched everything, from Cloudflare's FAQ to Stackoverflow and Stackexchange, so I'm really out of ideas. Any assistance will be greatly appreciated, thanks!
It is probably best if you contact support for this issue so we can help figure it out. We've seen a similar issue with WordPress that can be resolved by various plugins available in WordPress.
Someone also wrote something up on redirect loops and fixing in .htaccess (don't know if this will help).
To do this, add the following code to your .htaccess
#FileETag none
############################################
## FOR NGINX, LIGHTTPD, VARNISH OR ANY OTHER REVERSE PROXY TO APACHE
SetEnvIf X-Forwarded-Proto https HTTPS=on
Save.
You're done.
:D

Website requires www. prefix?

This isn't really code related, but at the same time it seems like the right place to ask. It's not happened to me for a while but a friend mentioned it in conversation earlier and now I need to know because it's bugging me!!
There are certain websites that require you to put in a www. prefix to actually visit their site. so as an example if I typed in domain.com the page wouldn't be found, but www.domain.com works perfectly fine. I can't think of any real examples which is frustrating me, but it happens every so often! I also see www1.domain.com occasionally... Not sure what that means either!
Could anybody explain these to me as I cant make any sense of it!
Thanks!!
This is because the dns or host files are configured that way.
If you configure the dns to only respond to www it will ignore all other requests for your domain.
If you configure the host files without a "catch all" you will have the same behavior.
I usually use a global dns record to redirect all requests without a specified domain prefix to a default server.
And on my servers I usually have a "catch all" rule to redirect unfamiliar requests to the root of the main website.
That always depends on how the name was configured - you can configure DNS-names pretty freely.

#font-face not working without www

When I load my site with WWW.example.com the custom fonts will load.
But if I just enter domain.com (without www) the fonts wont load in IE or Firefox but will in Chrome.
All my CSS files links are absolute.
Has anyone else faced this issue?
Be careful of XSS restrictions. Since you didnt say I'm assuming your links go to www.example.com instead of example.com. Browsers are wary of requesting files from other domains. You can set it to request from /path/to/css.css instead of an absolute link.
This is because of CORS (which basically means that browsers will not request resources from a server b that did not send the original document (which instead came from a server a) specifying the request, UNLESS b specifies that it will take requests that originate from a resources).
See http://www.w3.org/TR/cors/ and http://enable-cors.org/

Is there a way to always require or force the 'www' subdomain on a site?

I want to prevent users from going to say example.com and only go to www.example.com, we are using IIS 6. So say they go to example.com it could tack on the www.example.com, etc.
Is this a setting somewhere or will I have to code it to check for the subdomain when they land and redirect accordingly?
EDIT: I know the best way is to move away from the www prefix but for whatever reason if the user launches a course (this is an LMS) without the www in the URL the tracking does not work for the .asmx file, that is why I am trying to force the 'www' because if some people don't have it then they wonder why the tracking does not work.
If you're using ASP.NET create an HttpModule, handle the BeginRequest event and add this code inside your handler:
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
if (context.Request.Url.Host == "example.com")
{
context.Response.Clear();
context.Response.Status = "301 Moved Permanently";
context.Response.AddHeader("Location", "http://www.example.com" + context.Request.RawUrl);
}
Note that I didn't use Response.Redirect(), this is done for the sake of SEO, as Response.Redirect() always returns status 302 which means the object was moved temporarily while status 301 means the object was moved permanently, this will keep the PageRank of your pages from being divided between the www and the non-www versions (if search engine crawlers can access the page using both the www and the non-www URLs, they will divide your PageRank between the two, hence is the use of 301 which search engine crawlers understand and will keep your PageRank to only the www version of your site).
As both records already point to the correct server...
...you could simply set up a new website in IIS (server version needed) and have it respond only to example.com (the host header setting) and have it redirect to the wanted url (check redirect to url in Home Directory tab and enter www.example.com). The original site should then handle it (you could set it's host header to answer to www.example.com to be more specific).
If you can't do that on the web server, your publishing firewall should be able to, or you might consider replacing it. Your DNS provider might also provide (pun not intended) a redirect service (doing basically the same thing as above for you I guess).
As per other responses, arrange for a 301 redirect from the unadorned domain name to the site with the www. prefix.
Given that I actually work in the DNS industry, I'd like to share my views on the www. debate:
For now, at least, IMHO, the preferred version of URLs should be with the www. prefix. The hostname part of a URL is exactly that, it is a hostname. The only DNS resource records that your browser will search for are A (and possibly AAAA for IPv6) records, and the resulting IP address is that which it'll connect to.
It is not a web site address - only the full URL (with the http:// prefix) specifies that this host is expecting to receive HTTP connections on port 80.
The whole reason for the www. prefix in the first place was to allow for the separation of different protocols to different hosts. As Verisign showed when they (briefly) introduced their "SiteFinder" service several years ago, assuming that every request for an A record is for the use of the HTTP protocol is a massive mistake.
Having the canonical version of your URL be the one with the www. prefix also makes cookie handling easier, and allows for easier splitting of static content to content delivery networks (as recommended by Yahoo!, Google, etc).
Now, there is a DNS record type (SRV, see RFC 2782) which uses a service and transport prefix to allow a single domain name to dispatch different protocols to different hosts (and hence IP addresses).
The ideal DNS set up would be a record that looks like:
_http._tcp.example.com IN SRV 10 0 80 www.example.com.
This says that all requests for HTTP URIs over TCP/IP should be addressed to TCP port 80 on the hostname www.example.com. Note that with this syntax you could also have HTTP services automatically server from ports other than port 80 without the port number being part of the URL.
The SRV record is a required part of SIP, and is commonly used for Jabber (XMPP). However AFAIK no browser uses it. :(
Contact your host (or your domain registrar) and have them set it up to work with or without www. It should however work both ways or only one way if you so wanted. I'm assuming you have a host and are not running your own web server/domain name registration, lol.
This is how it works, regardless of whether or not you should.
This is handled by DNS. Usually, example.com and www.example.com will point to the same server, but they don't have to. If www.example.com isn't explicitly registered, then the request gets sent to the example.com server, and that server gets to decide what www.example.com means, as well as mail.example.com, ftp.example.com, home.example.com, users.example.com, and so on.
Edit: I realize this story is sort of incomplete, as these days Apache gets handed the URL that you used to get in with, and it may interpret a subdomain from that, and direct the request to a virtual site. But this shouldn't be a factor at the "www" level.
The typical way this is done by web sites is to do an HTTP redirect from example.com to www.example.com. You do this by returning either HTTP Status code 301 (permanent redirect) or 302 (temporary redirect) when user goes to example.com, and setting the HTTP location: field in the response to http://www.example.com. Google for "301 versus 302" to see when you should use either.
Note that this is an HTTP feature, not something provided by DNS... some domain name providers however do provide HTTP redirect facility for you if you use their name servers.
Note you can test this out for yourself. Go to http://web-sniffer.net and type yahoo.com (or microsoft.com or any major web site). You'll see that they respond to a redirect with the www version of the name (in less common cases some web sites go the other way, redirect www to the non-www version of the name).
When I had the misfortune to work on Microsoft's web stack, I used ISAPI_Rewrite to force www. prefixing (among other things).
At my web site I just put the following into the .htaccess file:
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^tafkas\.net$ [NC]
RewriteRule ^(.*)$ http://www.tafkas.net/$1 [L,R=301]
For Apache based server you can use this code
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.yourdomain\.com$ [NC]
RewriteRule (.*) http://www.yourdomain.com/$1 [R=301,L]
Explanation: The first line just turns the rewrite engine on. The second line of code is to check the url entered by the user. The bash sign (!) means not equal to. The carrot sign (^) means the beginning of the statement to be checked. Backslash dot (.) refers to the special character of dot, which when used without backslash means 'anything'. The dollar sign at the end of the statement refers to the end of the url. The third statement states that if the input given by the users is not the one as given in statement two, then proceed as follows. (.*) means that anything and any number of times. This is used so as the save anything written by the user after yourdomain.com/ gets stored in the variable $1. R=301 refers to the permanent redirection, and L states that this is the last in the series of status codes.
As stated adding the WWW is the opposite direction to be going. WWW is a redundancy these days.
You can check out http://no-www.org/ for further information.
This is actually backwards. It was how they did it in 1998, but now you're supposed to if anything drop the www.
Also, example.com is specifically reserved for posting example urls. Someone probably actually owns and uses the one you provided. How do you know you're not pointing someone to a porn or malware site with that random example?

Resources