DEV Community

Roger Campos
Roger Campos

Posted on • Originally published at rogercampos.com

Everything you need to know about DNS as a web developer

This article aims to be a practical summary of concepts, tools and details regarding DNS and domains. Many of them will not be news for experienced developers, but could be useful for people who has to work with this kind of thing for the first time. You will not find here a technical description of the protocols involved, but more an entry-level and approachable description of the concepts and how everything fits together.

Registrars

How they work

DNS would be nothing without domains, and the first step to get a domain is to buy it from a registrar. Those companies are in charge of officially keeping track of who owns what, they're the first step in the trust chain about domains. When you buy a domain, you're asked for some contact information like name, email and address. This will part of the whois record for that domain. That's just the official information about that domain and registrars are required to have it and also have it correct. That's why sometimes you can receive an email from your registrar asking to check if their info about your domain is correct or not (your name, address, etc.). This information, however, is not required to be public, just the registrar needs to have it. This is important because some super-cheap registrars will offer you to buy domains without telling you, for example, that your info will be made public! If you, later on, want to make it private, you'll find that that's sold as a separated product. That's a typical trick of those companies, I recommend you to keep this data private.

When you purchase a domain you do it for a certain number of years and when it expires, you still have a "grace period" (40 days normally) when you can re-buy it even after expiration. Registrars will always notify you about expiration in the email you give them.

It's possible to transfer a domain into another registrar, however, to do that you'll have to buy the domain in the new registrar, pay for it, and then say it's a transfer of an existing domain. You just need to provide some auth codes that your old registrar must give you to prove ownership, but as you'll have to pay again, normally you'll want to do this when the current registration is about to expire.

I'd like to clarify, just in case, that by "domain" we understand "something.com", "foobar.gov", etc. Just a name, followed by a dot, followed by "com" or whatever. Once you have purchased a domain, you're able to use any number of subdomains you want, even nested ("foo.bar.something.com"). Subdomains are not entities by themselves at the registrar level, it's assumed that you also own all of them and respond for all of them. So, always use subdomains for things related to the root domain (there're also technical security concerns we'll see later) and that you control.

TLD regulations

One important thing to know is that regulation about domains change depending on the TLD (top-level domain, the last part in any domain after the dot, like ".com", ".es", etc.). While many TLDs are open (like ".com") for anyone to purchase, some others are restricted TLDs, meaning they impose additional verifications for the buyer to satisfy. For example, ".nyc" (for New York City) can only be purchased if you can prove you have a valid address within NYC, or ".gov" domains can only be purchased by federal, state, local and tribal government organizations within the United States. Given such variations and restrictions, this also means that not all registrars will operate in all TLDs.

In the recent years there has been an explosion of more specific tlds. Many curious and extravagant ones like ".blackfriday" or ".beer", but also some that now belong to one company in specific, like ".apple" domains that can only be owned by Apple. Arguments about security are being used to justify this, but really that's nothing more than one more example of abuse in the Internet. Other conflicts about TLD assignation have occurred in the past, for example it seems like Amazon will finally own the .amazon TLD instead of it being open to represent the Amazonia region.

Settings at the registrar level

Technically, there're only a couple of things that you must manage in the registrar. The first and most important is the nameservers of the domain, or NS records. These fields must point to a DNS server that will actually be the first authority to manage all your DNS records for that domain. You must enter at least 2 names here, just for redundancy as stated by RFC 1304. Don't worry, all DNS servers will provide you with at least 2 names.

You have many free choices available for a DNS server: Netlify, Cloudflare, and many more. You could even use your self-hosted DNS server using bind for example, but I would really recommend to use something already available for anything internet-facing.

Configuring the nameservers can be really confusing sometimes, because all the registrars are usually also DNS servers, and by default they'll configure your new domain with their DNS servers. They will probably show you an interface to configure "DNS records" as if that's all to be done, and the actual NS records configuration may be somewhat hidden. Look for it, it's normally called "DNS servers". Usually the DNS servers on the registrar are not very good, so my recommendation would be to change them and point it to something you trust and offers all the features we'll see later.

The other technical configuration you can only do in the registrar is the setup of DNSSEC. That's a more recent addition to the DNS spec that serves the purpose to validate the authority of the DNS server. We said before that the registrar is the only one that can prove you're the owner of a given domain, by this mechanism, the registrar also validates that the DNS server of your choice is the only one authorized to provide DNS entries for your domain. See a more complete explanation here about DNSSEC.

The whois tool

To know all the information relative to a domain, you can use the command line program whois, for example:

~ > whois microsoft.com
   Domain Name: MICROSOFT.COM
   Registry Domain ID: 2724960_DOMAIN_COM-VRSN
   Registrar WHOIS Server: whois.markmonitor.com
   Registrar URL: http://www.markmonitor.com
   Updated Date: 2014-10-09T16:28:25Z
   Creation Date: 1991-05-02T04:00:00Z
   Registry Expiry Date: 2021-05-03T04:00:00Z
   Registrar: MarkMonitor Inc.
   Registrar IANA ID: 292
   Registrar Abuse Contact Email: abusecomplaints@markmonitor.com
   Registrar Abuse Contact Phone: +1.2083895740
   Domain Status: clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited
   Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
   Domain Status: clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited
   Domain Status: serverDeleteProhibited https://icann.org/epp#serverDeleteProhibited
   Domain Status: serverTransferProhibited https://icann.org/epp#serverTransferProhibited
   Domain Status: serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited
   Name Server: NS1.MSFT.NET
   Name Server: NS2.MSFT.NET
   Name Server: NS3.MSFT.NET
   Name Server: NS4.MSFT.NET
   DNSSEC: unsigned
   URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/

   [...]

We can see some dates, like creation and expiration as the more important, and some info about who is the owner. That's one thing we talked about before, if your registrar offers "private whois", you won't see your name and email here. Otherwise, your email will be exposed, so... you can get some extra spam.

We can also see here, under "Name Server", the DNS server this domain is using. In this case 4, all of them do the same thing, it's just for redundancy.

As we said before, since the actual regulations about domains depends on each TLD, some information or all of it can be unavailable. For example ".es" TLDs don't show anything at all:

~ > whois google.es

    Conditions of use for the whois service via port 43 for .es domains

    Access will only be enabled for  IP addresses  authorised  by Red.es.  A maximum of one  IP address per
    user/organisation is permitted.

    [...]

DNS

What is it?

First, the basic definition everybody probably knows, DNS is a way to store information associated with a domain. The most typical example is to search for websites. Any website is hosted in a server (yes, even with serverless) and your browser must know the IP address of that server to connect to it and ask for that web page. To know that, previously, it uses DNS to discover that, for example, "microsoft.com" translates to 40.76.4.15 (right now, and from my location specifically).

This is an example of DNS storing, in the domain "microsoft.com", the information that its website can be found at 40.76.4.15.

The DNS system consists in thousands of DNS servers distributed in the world, it's essentially a globally distributed database. It's out of the scope of this article to explain exactly how this works, but it's certainly an interesting read. What you should know about this is that, being a database as big as that, it takes time for new information to spread across all the network. In practice, when you do some change in a domain of yours you can actually see the change taking effect after ~1 hour max, but to be safe, always wait 24-48 hours before considering the change as globally done.

DNS to identify the server? or the website?

Some may think that, based on what we just said, the resolution mechanism DNS offers to convert a domain to an IP address is what's used to also identify the website hosted in that server. In other words, that we need a domain for a website to work. That's not true, websites work just fine independently of DNS, they're separated systems.

If a server (machine with ip = 40.76.4.15) is hosting 2 different websites, deciding which one to serve as a response to an HTTP request will depend exclusively on the HTTP request itself.

This decision is based on the Host HTTP header the client must send, and its purpose is precisely to identify for what website the client is asking for. This header is mandatory and cannot be omitted.

We can check this with a simple experiment, using curl -I to only show headers. First we check the normal response:

~ > curl -I http://microsoft.com
HTTP/1.1 301 Moved Permanently
Date: Fri, 14 Jun 2019 18:58:42 GMT
Server: Kestrel
Location: https://www.microsoft.com/

We see microsoft responds with a 301 to the https version. Now if we ask directly to the IP:

~ > curl -I http://40.76.4.15
HTTP/1.1 404 Not Found
Date: Fri, 14 Jun 2019 18:58:51 GMT
Server: Kestrel

It's a 404. Their webserver knows we haven't send a Host header and the logical response in this case is a 404. Now we can try again with the IP again but providing the Host header manually:

~ > curl -I http://40.76.4.15 -H "Host: microsoft.com"
HTTP/1.1 301 Moved Permanently
Date: Fri, 14 Jun 2019 18:58:59 GMT
Server: Kestrel
Location: https://www.microsoft.com/

And we get the same initial response, good!.

The trick here is that http clients, like curl, will automatically set the Host header with the same value as the domain. We can check this by enabling more verbosity:

~ > curl -v -I http://microsoft.com
* Rebuilt URL to: http://microsoft.com/
*   Trying 40.76.4.15...
* TCP_NODELAY set
* Connected to microsoft.com (40.76.4.15) port 80 (#0)
> HEAD / HTTP/1.1
> Host: microsoft.com
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
HTTP/1.1 301 Moved Permanently
< Date: Fri, 14 Jun 2019 18:59:08 GMT
Date: Fri, 14 Jun 2019 18:59:08 GMT
< Server: Kestrel
Server: Kestrel
< Location: https://www.microsoft.com/
Location: https://www.microsoft.com/

<
* Connection #0 to host microsoft.com left intact

This is typically a detail easy to forget. If you don't configure it explicitly, many webservers will by default serve one "random" website when accessed via direct IP. This can also lead to google and search engines in general to consider it duplicated content, as the same website would be served by two different domains.

This problem is, however, removed if your website works only with https (and it should). Because if we try this experiment with https, we'll see curl complaining with the message:

curl: (51) SSL: no alternative certificate subject name matches target host name '40.76.4.15'

The server does not have an SSL cert issued for the IP. This is to be expected, the Common Name in the SSL cert must match exactly the domain we're connecting to, not the http host. Fist reason is because otherwise it would be an incredible security issue (anybody would be able to fake it) and second, more technically, is that it's not possible. The actual HTTP protocol is "inside" the TLS connection that goes first. That's the purpose of https, to encrypt the connection, so the server cannot see anything about the actual HTTP request until the TLS negotiation has successfully finished. It's one protocol inside another.

It's technically possible to issue a SSL cert for an IP address, but it's not something any sane person would do.

DNS as an information store

The first concept we should talk about is that information attached to a domain in a DNS system is always classified with record types. You cannot store "anything", it must be one of the allowed record types, and each type has an special format and serves an specific purpose. We say we store "records" in DNS, and every record if of one record type. You can have many records of the same record type, no problem with this.

Second, every record in a DNS system must also have a "Host" property. Some providers call this "Host", others "Name", and some others even more imaginative names. Maybe you've heard that naming things is one of the hardest problems ever in this profession, and it's absolutely true, here we have yet another example. Whatever the name it has in you provider, you must know that this represents the subdomain (or root domain) to which this record will be attached. Each subdomain (or root domain) have its own records.

If the record belongs to a subdomain, just introduce the name of the subdomain, but if it's for the root domain there's a special syntax you must use, it cannot be left blank. Many providers use "@" to refer to the root domain, but others will use ".", you'll have to look at your provider's documentation or examples.

Apart from this, depending on the record type you'll have to enter more or less information and some extra validations will apply.

How to visualize DNS records

One of the most important things when debugging and experimenting is to have a quick and reliable feedback loop. Something you can rely on, that you can trust. And when checking up DNS records, dig is your friend. It's a simple command line tool, use it like:

~ > dig google.es

; <<>> DiG 9.8.3-P1 <<>> google.es
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8004
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;google.es.         IN  A

;; ANSWER SECTION:
google.es.      155 IN  A   172.217.16.227

;; Query time: 23 msec
;; SERVER: 80.58.61.254#53(80.58.61.254)
;; WHEN: Fri Jun 14 20:59:21 2019
;; MSG SIZE  rcvd: 43

This is telling us that "google.es" has a record of type "A" pointing to 172.217.168.163. To make things more concise, there's an option called "+short" you can use to make dig display only the useful response and nothing more, we'll use that from now on:

~ > dig google.es +short  
172.217.168.163

One interesting trick is that you can force dig to ask one DNS server in specific about your question. If you just changed some DNS information in your DNS server, ask directly that server to verify the information has been updated. Your DNS server address is the same you used in your registrar. For example, using whois we can discover that microsoft.com is managed by NS1.MSFT.NET. We can ask directly then:

~ > dig @NS1.MSFT.NET microsoft.com +short
13.77.161.179
40.76.4.15
40.112.72.205
40.113.200.201
104.215.148.63

This way you don't need to wait for the DNS information to propagate to verify your changes!

What record types are available?

Let's quickly review the different record types we can use with DNS. The most used ones are only 4: A, CNAME, TXT and MX. Other types have existed since the beginning like SOA and NS, but they're purely technical and we won't cover them here. Same happens with many more that have been added with the years for different purposes, you can see a complete list here.

A

"A" record types are the most basic ones, they translate names to IP addresses. The "name" to translate will be the "Host" property we talked before, for the root domain usually "@" and anything if you want to create a subdomain. The actual data in this case will be just the IP to point to. We have two variants, "A" for ipv4 and "AAAA" for ipv6. Even if you don't give an explicit "AAAA" version, normally the DNS server will automatically handle this with a conversion from the "A" record.

We said before that many different records can be created of the same type, and normally this is true for "A" records of big companies. It's used as a way to distribute load between machines (but it's not a load balancer, we'll see that later).

~ > dig amazon.com +short
176.32.98.166
176.32.103.205
205.251.242.103

For some reason google has only 1, but we can see amazon has 3 defined.

This mechanism serves two purposes mainly, first for us humans it's easier and preferable to remember brand names (or products, services, whatever) rather than remembering a series of numbers (and even more with IPv6, but that's another story). One could argue that nowadays you can just search for the brand name in google (or any other search engine for that purpose) and access the website through that, so the domain and entire url are useless. Some years ago Google tried to do this but was quickly reverted due to security concerns, mainly phishing attacks. I think we'll still have domains and full urls for quite some years.

The second purpose is technical, using domains to access resources means using an extra abstraction layer, so the real place where the resource can be found (the server) can be replaced without the rest of the world knowing.

MX

"MX" records are the equivalent of "A" records but for email.

In case of "A" we have:

  1. [A web browser] is asked to visit "google.es"
  2. It asks the DNS system: ["What is the A record for google.es?"]
  3. Gets an IP as a response
  4. Browser connects to that IP and keeps going.

In case of "MX" we have:

  1. [An email client] is asked to send an email to "jon@google.es"
  2. It asks the DNS system: ["What is the MX record for google.es?"]
  3. Gets an IP address or domain as a response
  4. Connects to that (maybe with an extra A resolution here if the response has been a domain) and keeps going with email delivery.

There are some extra technical differences, but's essentially this is it. Why not mix both then? Well, just so that we are not forced to use the same server for web hosting and for email hosting. It's pretty common that the website is hosted in a server managed by us (or in a platform like Netlify) but the email is managed by Google for example.

CNAME

Cnames are interesting, they're like aliases. A CNAME record has only one value as information, and that must be another domain, not an IP. But it can be anything, not necessarily another "subdomain" from the same domain, anything. It's mean to say: this domain you're looking for actually refers to this other domain, and the client then must keep searching. It's useful for situations when you want to use publicly one domain, but internally that's associated to another domain. You can change this "other domain" and the rest of the world will not be affected.

One typical use case is handling the "www" version of a website. You setup your website directly under the root domain (with an A record), then the "www" subdomain is assigned a CNAME to the root domain. It's important to say here that we're only talking about the DNS resolution mechanism, nothing to do with HTTP or anything else. After setting up the "www" CNAME, ping www.mywebsite.com will work, but that's all. If you, additionally, configure your webserver to also listen for the www version of your domain, then you'll be able to browse your website also from the subdomain. In this situation, however, both mywebsite.com and www.mywebsite.com will work fine and show the same website, but then you'll have a SEO problem of duplicated content. In general, you don't want your content to be available at different URLs in the internet. To finally fix this, you'll need to create a 301 redirect from the www version to the root domain.

You can see another example of how CNAMEs are used in companies like Netlify, Zendesk, Heroku and many more. All those companies have in common the fact that they need to offer their customers with a website as part of their service.

If you create a new Heroku website, they'll offer you the URL https://<my_name>.herokuapp.com/, a new Netlify app will be found under https://zen-shockley-<whatever>.netlify.com and something very similar will happen in Zendesk. That's the "canonical" domain they're giving you. If you want to use your own domain with those websites, you usually have to setup a CNAME to point to them (warning: see later about CNAME flattening before doing this).

Finally we should also mention that CNAMEs have nothing to do with SSL!. Following the previous example, if your netlify website is zen-shockley-1412a2.netlify.com and you setup a CNAME in www.mywebsite.com pointing to that, the webserver will have to have an SSL cert covering www.mywebsite.com. Netlify and others will handle this automatically after you're configured the domain you want to use, but maybe other services will force you to upload the SSL cert yourself.

If you are the one creating some app that has this feature, then you'll need to manage automatic SSL issuing with Let's encrypt, for example. Take a moment to appreciate how lucky we are to have something like Let's encrypt!. Some years ago, this was a real pain that always needed manual intervention.

TXT

This kind of DNS record is nothing more than a plain text information. There are some technologies that will ask you to use one (like setting up DKIM for email delivery, we'll see that later), and it's also typically used as a way to prove domain ownership.

Google analytics, for example, or any other service that works with a domain will normally ask you to validate you're the owner of a domain. One of the ways they can prove that is having you create a new CNAME or TXT record. Long ago the normal way to do this was to add an special html file they gave you. That worked fine for static websites, but for a dynamic website it's normally better to use TXT or CNAME to validate this kind of thing.

ALIAS or CNAME flattening

After looking at the most common DNS record types, now we'll talk about a kind of "virtual type". This concept can be found in some DNS servers as an "ALIAS record type", or "ANAME", or other times it's referred to as "cname flattening", but it's the same concept.

It's like a CNAME record, but directly resolved. We saw that CNAMEs act as an alias, referring one domain to another. But that only works at the DNS level. When a program is resolving "foo.bar.com" the DNS server will respond that's actually the same as 'bar.com', then the program will ask again for "bar.com". In other words, all client software know about CNAMEs.

With this ALIAS type, however, the client will receive directly the IP address (if it's an A record). The client will think it's a normal A record, it's the DNS server the one that does the trick. It manually short-circuits the alias, it's the dns server who resolves the destination and gives back to the user the final information.

Why is this useful? Because it's not allowed to have a CNAME record in the root domain, so this solution was invented instead. This is what you should do if you're hosting in Netlify, Heroku, etc. and you want your website in your custom root domain. Can't use a CNAME, use an ALIAS instead.

But why it's not allowed to have a CNAME in the root domain? Interesting thing. We've seen before that any DNS record must belong to a subdomain or root domain, including any CNAME declaration. And we've seen that CNAME act like an alias the client software must follow. This is actually a contradiction, imagine you have two domains:

foo.website.com has two DNS entries:

  • A TXT record with the value "alice"
  • A CNAME record with the value "www.bar.com"

www.bar.com has one DNS entry:

  • A TXT record with the value "bob"

When a client asks about TXT records in "foo.website.com", what should be the response? There's a TXT record, but also a CNAME, should the client follow the CNAME or keep the TXT on the first domain?

To fix this incoherence the DNS standard added a rule:

CNAME records can only exist as single records and can not be combined with any other resource record ( DNSSEC SIG, NXT, and KEY RR records excepted)

So if there's a CNAME for a given subdomain or root domain, no other DNS record can be added there. However, there are two special DNS record types, named NS and SOA, that the spec forces to be present at the root domain! We're not gonna enter in details about those, but that means that both things cannot be true at the same time, so a CNAME cannot be at the root domain.

Not long ago I encountered a DNS server that will actually let you do so, but please don't. This caused incoming email to be lost when they came from certain providers, extravagant problems can happen if you don't follow this rule.

Caching and TTL

You have to consider that DNS resolution happens all the time, very very frequently. And resolving the IP address of a name it's not free. DNS uses UDP which is very fast, but still, some time is required. If the entire resolution would have to be done each time, internet would not be feasible. To solve this, DNS responses are cached at many different levels. In your browser, in your domestic router, and also in intermediary networking hardware. This is the only way to make it fast.

And if there's caching, there's also a way to expire the cache, and that's the TTL (time to live). Any DNS record will have an associated TTL value, and that's how much time their value can be stored (cached) by any involved party. You can change this at any time from the DNS server. A typical value is 1 hour, but you can set longer times for MX or CNAME records (normally they're the most stable).

DNS information being cached obviously means that the TTL you set will be the minimum time you can expect to wait when changing something. If you want to migrate your website to another server and you have to change an A record, if that A record has 1 hour as TTL, you'll have to keep the old server alive for at the very least 1 hour (I would still wait 24h). This is important to check beforehand just in case you have an unusually large value. You can check this with dig:

~ > dig google.es                                                                                                                                                                                    

; <<>> DiG 9.8.3-P1 <<>> google.es
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46680
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;google.es.         IN  A

;; ANSWER SECTION:
google.es.      272 IN  A   172.217.17.3

;; Query time: 28 msec
;; SERVER: 80.58.61.254#53(80.58.61.254)
;; WHEN: Sun Jun 16 17:49:27 2019
;; MSG SIZE  rcvd: 43

The TTL is that "272" number in the ANSWER section (can't use +short this time).

If you have a too large TTL, just change it to 1 hour and wait for the previous TTL time to expire.

DNS as a load balancer

We've seen before that you can set many DNS records of the same type, and that's also usually done for A records, like here:

~ > dig microsoft.com +short                                                                                                                                                                                    
104.215.148.63
13.77.161.179
40.76.4.15
40.112.72.205
40.113.200.201

In such case the dns server, when asked, will return one or another IP address in a round robin fashion.

Seeing this, some people may argue that you can just use DNS as a load balancer because different clients will receive different IPs for your servers, effectively distributing the load evenly. But please don't:

  • The DNS resolution will be cached by intermediary resolvers and the client itself, so in time, you won't have a good load split as clients will continue to reuse its previous server for as long as the TTL says.

  • It's not a failover. In case some of your servers stop responding, it will still show up in the DNS response. Even if you manually configure it to remove that IP from rotation after detecting the failure, clients and intermediary resolvers won't pick up the change until the TTL has expired, which usually is, at the minimum, 5 minutes.

For load balancing you can use HAProxy, or use some kind of infrastructure as a service that already provides it (Amazon, Linode, and many more.).

As a final note, this mechanism can actually work in a controlled environment. If DNS is used internally as a mechanism for service discovery, then it makes sense to use there a very short TTL to have almost real time DNS responses. This works because performance is not an issue here, everything is in local network. For example, consul is an example of service management that uses DNS for discovery.

Ownership within the DNS server provider, how they know it's me?

At the beginning we saw how to set the DNS server you want to use for your domain. You have to go to your registrar and change the NS records there, pointing them to the DNS server you want to use. If you want to use linode, for example, you'll set them up as ns1.linode.com and ns2.linode.com. Then go to linode.com, login, and click "add new domain".

But now... How does Linode know that you are the owner of that domain? It doesn't!. Can someone else, at that moment, go to linode and add your domain? Yes! And will it work? Yes!

So this can happen. It's not managed, all DNS server providers will simply trust the first one to add a domain in their service. All them have "customer support policies" to resolve conflicts in case this happens to you, but that will only be after the fact. What's more, anybody can simply register hundreds or thousands of domains in Linode now, just waiting for the moment any of them gets pointed there and they gain management capabilities!

Is this really an issue? Not so much. If this ever happens to you you just need to go back to your registrar and change the NS records to another DNS server provider, or set the default ones (your registrar surely will offer you this) until the conflict gets resolved.

The attack surface is also complex to setup, the attacker should know that you're about to get "this exact" domain and also that you're gonna point it to "that exact" DNS server. Can happen if they know all this specific data, but it's too generic for a general attack: Too many domain names to try, too many DNS servers to try.

Also, DNSSEC will avoid this to become an actual issue for anyone using your domain.

As we saw initially, DNSSEC is a security mechanism by which the registrar (something only you control) authorizes only and only one DNS server to provide DNS records for that domain. Without access to the registrar, the attacker will not be able to correctly setup DNSSEC. Please, always configure DNSSEC for your domains!. If this "domain management hijack" happens to you but your domain has DNSSEC enabled, any client will see that the DNS server giving the records is not authorized by the registrar and will abort the connection.

Local resolution

There are other ways to resolve names to IPs, "A" DNS record types. All operating systems have an special file called hosts, in Linux and MacOs it's found at /etc/hosts and in Windows in C:\Windows\System32\Drivers\etc\hosts. It contains something like this:

##
127.0.0.1   localhost
255.255.255.255 broadcasthost
::1             localhost

Each line starts with an IP address and after that you can write domains that will resolve to it, one or more separated by spaces. If a domain is listed here, this will take precedence and the normal DNS mechanism wil not kick in.

This is a great way to check your new server without changing anything publicly, just edit this file and manually set your domain to point to the IP address of your new server, and you'll be able to test it for real with a browser.

There are some special situations where this will not work, for example if you're using Cloudflare on top of your custom server. In this situation, cloudflare acts as a reverse proxy as well as a DNS server. If you set an A record pointing to your server (ex: 213.24.1.1), then the IP resolved publicly will not be that one! It will be another IP belonging to a Cloudflare's server. They receivec all the traffic, add features like SSL cert management, and proxy all requests to your real sever. Youre server is only accessed from Cloudflare.

In this scenario you can point your local hosts file to your new server but you won't have SSL, for example, if that's a feature you depend on Cloudflare to provide.

It's also worth mentioning the special TLD .localhost. It's reserved (cannot be purchased) and will always resolve to localhost. It's an easy way to use any custom domain you want for local development when the host of the requests is important to you.

Email and DNS

Email is another big topic that will require modifications in your DNS entries to get it working properly.

We've seen that to receive emails in your custom domain (ex: "my_name@my_branding.com") you only need to configure MX records. That's easy, like A records those will be only used to know where to address incoming emails.

To correctly send outgoing emails, that's more complex. The email standard is open, meaning anybody can send emails, and that's a good thing. You could install an email server locally and use it to deliver any number of emails. What's more, you could make it so that it would appear the email is sent from any address you want.

Naturally this is a big security concern. To mitigate it, it's the responsibility of the servers hosting your email to put measures to minimize unwanted spam. Unfortunately however this is a problem that cannot be solved, because you never know if the user is really expecting to receive an email from a new contact.

To fight spam, email providers use a lot of techniques to try to predict if the email you just got is "legit" or not. Analysis of the contents, checking senders against known blacklists, etc.

But one important thing that can be known is, at least, if the person who sent you the email is really the owner of the domain he's using. That is, if the email you got from "jon@google.com" is really coming from google.

Thi is analogous to what we said before about DNSSEC, where the registrar "validates" the DNS server serving dns records for your domain. Here, the technique consist on validating that the email sent matches a configuration present in some DNS entries. The technologies you should be using to enable this are called DKIM and SPF, you can get a grasp on them in this help article from Fastmail.

Tools

To finish this long post about DNS, here are some free tools you can use to checkup your configuration:

The tool from sslabs is the most comprehensive one I've ever found. You should aim for an A+ grade. It will also report vulnerabilities you may have related to ciphers used, TLS versions, etc.

Dnsspy is more focused on security only. It will likely report that your DNS records are only server by 1 server, but that's pretty standard.

Top comments (1)

Collapse
 
ferricoxide profile image
Thomas H Jones II

Small quibble on the assertion:

This decision is based on the Host HTTP header the client must send,

Even on a server configured to serve up multiple sites bound to a single IP, whether a client needs to send the Host HTTP header depends on the HTTP server's configuration (and the content the client wishes to receive). If I have an HTTP daemon configured with a default site with named virtuals piled on top, I only need to specify the Host HTTP header in my request if I want content from one of the piled-on virtuals. Absent the Host HTTP header, the default-site's content will get served out.