HTTPS redirect from root domain (i.e. apex or 'naked') to 'www' subdomain without browser throwing up?

Solution 1:

There are two separate but interdependent levels of indirection to consider here. The first is what IP address a DNS name ultimately resolves to. The second is what the server on that IP address does.

Remember that when you type a URL into a browser, the first thing that happens is a DNS lookup. Usually, that's handled by the operating system – not the browser itself.

So your browser will ask the OS, "what is the address of example.com?" The OS will look up the record, and if it gets a CNAME, will look up that record, until it finds an A record. The OS then responds to the browser with an answer.

Your browser then opens a TCP connection to that IP address:

  • If a http:// URL, it connects to port 80, then issues a HTTP request.
  • If a https:// URL, it connects to port 443, establishes a TLS/SSL connection (which means validating certificates), then issues a HTTP request over the secure channel.

Only at this point can HTTP redirection happen. The browser sends a request (GET /, and the server can respond with a 301 to any other URL.

Understand that "subdomain redirection" services offered by registrars are nothing more than a regular HTTP server that issues 301s. When you opt for a registrar's redirection option, they just set the A record of your domain's apex to a server they control, and that server tells browsers to go to www.example.com.

Since most registrars don't allow you upload a SSL certificate to their redirection server, browsers cannot establish the necessary secure connection to the server, and therefore they never issue a HTTP request. Thus, requests for https​://example.com fail.

So why can't you just CNAME the apex? It is forbidden.

The domain system provides such a feature using the canonical name (CNAME) RR [Record Resource]. A CNAME RR identifies its owner name as an alias, and specifies the corresponding canonical name in the RDATA section of the RR. If a CNAME RR is present at a node, no other data should be present; this ensures that the data for a canonical name and its aliases cannot be different. This rule also insures that a cached CNAME can be used without checking with an authoritative server for other RR types.

The spec requires that a CNAME record be the only record for a given (sub)domain. This is at odds with the requirement of having a SOA record on the apex. (There are some efforts out there to change the specs to allow CNAME and SOA to coexist, but there are still many broken SMTP implementations that will be confused by the CNAME on a domain.)

You have the following options to get SSL working on the apex:

  • Use a third-party service that supports SSL on the redirect server. You'll likely pay for this. Here's one service. I would not recommend this route, since it takes the control of reliability out of your hands, and requires you to hand over the keys to your SSL certificate to someone who may or may not be trustworthy.
  • Run your own redirection server. Since the apex requires an A record, you'll need a static IP, which services like Heroku and AWS' ELB do not provide. So if you're in a cloud environment, it will be very difficult (if not impossible) to guarantee reliability. On the plus side, you retain control of your SSL keys.
  • Use a DNS host that allows you to set an alias. Point the alias to your Heroku domain/ELB/whatever. This is most likely the best option.

An alias is not technically a type of DNS record. Instead, it is a special configuration on the DNS host side that returns an A record from the result of another lookup. In other words:

  1. Your OS issues a DNS request for example.com to your DNS host.
  2. Your DNS host reads the internal alias configuration, and issues a DNS request for that domain. So if you have an alias set up for example.herokuapp.com, it would look up the A record of that domain.
  3. The DNS host returns a simple A record with the IP(s) it got from the alias lookup.

With an alias record, you could point your apex to the same cloud load balancer that your www domain is CNAMEd to. Assuming you've set up SSL on the www domain, the naked domain will work just fine. At this point, it's your choice whether your app issues a redirect, or just serves your content directly over the naked domain.

Solution 2:

You need a certificate that secures both www.example.com and example.com.

Solution 3:

NOTE: I have not tried this with Heroku app. I am still sharing this solution here as this is the first stackoverflow page that shows up for 'redirection from naked domain to www version' search. It may help others who are looking for an answer to generic redirection.

I have successfully redirected naked domain to www version. In addition, I also redirected the HTTP version to HTTPS version using google domains DNS settings in synthetic records.

  1. Delete any 'A' records for '@' in your DNS.
  2. Add a synthetic record with subdomain = '@' and redirect it to www version of your website.
  3. After addition, edit this same record and change the default 'http://www.example.com' to 'https://www.example.com' . Note the 's' in http here. Click Save.
  4. That's it. Your redirection is now taken care of by DNS settings.

Detail steps are documented here: https://www.am22tech.com/redirect-naked-domain-www-http-https-google-domains/