DNS64: Why is it good, but not always help

Posted on

This artice will explain you how to setup DNS64 on your VPS. You will also know why it may not help in some cases.

Quick guide

First of all – short how-to for those, who just forgot how to use it.

Trex – http://www.trex.fi/2011/dns64.html
Public NAT64 Service – https://nat64.net/
Google – https://developers.google.com/speed/public-dns/docs/dns64
Cloudflare – https://developers.cloudflare.com/1.1.1.1/infrastructure/ipv6-networks/

You need to take IPv6 addresses and put them into /etc/resolv.conf file like this:

# Example with Trex DNS64
nameserver 2001:67c:2b0::4
nameserver 2001:67c:2b0::6

Use any text editor to do this, like nano, vi, micro or any other. Or you can use command below:

echo -e "nameserver 2001:67c:2b0::4\nnameserver 2001:67c:2b0::6" > /etc/resolv.conf

It will print Trex DNS64 servers into into /etc/resolv.conf file.

What does DNS64 do for you

In short – it let you reach domains which has only IPv4 address. Yes, similar to proxy or VPN (more closer to proxy), but there’s difference.

Usually proxy is universal: you can use same instance to achieve multiple resources. Unlike that, DNS64 acts like DNS+proxy:

  • if domain has any IPv6 address, it will just return it’s addresses as is
  • if domain doesn’t have IPv6 addresses, then DNS64 perform next steps:
    • take IPv4 address from domain
    • generate synthetic IPv6 address based on it
    • return this address in DNS response

Important conclusion: DNS64 generate IPv6 for your target and then your VPS able to reach resource, because it have IPv6. So on your side connection still goes over IPv6 and your VPS doesn’t have IPv4 connectivity.

It’s very important thing to understand, because while some software work with both IPv4 and IPv6 out of the box, some another part of software may require additional configuration to support IPv6, or even just doesn’t support it.

Actually that’s the reason of “not always help” mentioned in title. So please, if you’re using DNS64 and can’t reach some resource via your program/library/bot/anything else, check their docs/wikis to know if they support IPv6 and if yes – how to enable it.

See also  How to use acme.sh for issue ssl cert with ipv6

The reason why is it a good solution: DNS64 is the most easy way to reach IPv4 resource with domain from IPv6-only machine. It doesn’t have any requirements for you – you don’t need to make accounts, install something, or learning how to configure “something” to make your VPS reach IPv4 resources. You’re just saying to system “Hey, I wanna use these DNS servers” (by writing them into related file) and you can reach your target right after this.

But what if my target doesn’t have any domain? It has only IPv4 address

Well, in this case DNS64 doesn’t help you directly. The reason is that when you specify IP address, then your system trying to reach it directly. If you familiar with DNS topic in general, then you can scroll down to the next section.

Domains are just comfortable way for people to remember the resource address. For example, what does says to you IP address 140.82.121.4? I’m pretty sure that absolutely nothing. But it’s Github 😀

When you put domain anywhere (in browser, in terminal for ping, or in any other software for some usage) the domain itself doesn’t mean anything to your device. It still need an IP address to reach. So when you’re trying to reach the domain in any way, your device firstly ask configured DNS server “Which IP address has this domain?” and after receiving response the connection actually happens.

So, as you see, especially on this step the magic of DNS64 happens. And that’s why DNS64 won’t help you if you want to ping 8.8.8.8 for example.

In order to use DNS64 way, you will need to do some manual work.

Manual IPv4 translation

Prerequisites

Before starting manual translation we need to do 2 steps:

  1. install “dnsutils” package into your system, we will need “nslookup” tool from it
  2. use “nslookup” to find out a DNS64 prefix

If step 1 is obvious – just run installation command related to your OS, then step 2 need some explanation.

We need to use it like this:

nslookup github.com 2001:67c:2b0::4

P.S.: The syntax for this run is “nslookup <target domain> <address of DNS server>”. I’ve used Trex DNS64 server, you may use whichever you want.

Result will look like:

Server:         2001:67c:2b0::4
Address:        2001:67c:2b0::4#53

Non-authoritative answer:
Name:   github.com
Address: 140.82.121.4
Name:   github.com
Address: 2001:67c:2b0:db32:0:1:8c52:7904

Notice the IPv6 shown here (which is 2001:67c:2b0:db32:0:1:8c52:7904) – it’s the synthetic IPv6 for github, which was generated by DNS64 service.

The prefix we’re looking for is first 6 segments of this IP. So it is “2001:67c:2b0:db32:0:1:”

Translation itself

Let’s use Github IPv4 address again in this step, so it will be easier for you to verify result. To translate IPv4 address, we need to take it segments and convert them from decimal to hexadecimal numbers. Let’s do it:

  • 140 (decimal) turns into 8c (hexadecimal)
  • 82 (decimal) turns into 52 (hexadecimal)
  • 121 (decimal) turns into 79 (hexadecimal)
  • 4 (decimal) turns into 4 (hexadecimal)

Now join 2 segments of IPv4 into one segment of IPv6:

  • 140.82 turns into 8c52
  • 121.4 turns into 7904

You may get the question “but why 04?” and that’s why: normally segment of IPv6 address consist from 4 hexadecimal numbers. You can shorten only non-significant zeros of whole segment. Numbers before 4 (which are 7 and 9) in this segment are not zeros, so we can’t shorten them. However 794 is still a valid segment of IPv6, it means 0794, but not 7904 which we need. That’s why we add non-significant zero before 4, to make it consist from 2 hexadecimal numbers.

See also  How to install aaPanel for ipv6 vps

Now add these 2 IPv6 segments to DNS64 pefix you acquired. Result is 2001:67c:2b0:db32:0:1:8c52:7904. And it’s exactly IP address which we received from DNS64 server.

One more example

You probably seen that in some guides about VPN/Proxy configuration there were used ipinfo.io resource as IP checker to see that you detected from country where your VPS is.

If you will check, it has only IPv4 too:

Server:  dns.google
Address:  8.8.8.8

Non-authoritative answer:
Name:    ipinfo.io
Address:  34.117.59.81

Let’s translate it:

  • 34 (decimal) turns into 22 (hexadecimal)
  • 117 (decimal) turns into 75 (hexadecimal)
  • 59 (decimal) turns into 3b (hexadecimal)
  • 81 (decimal) turns into 51 (hexadecimal)

By joining them into IPv6 segments we’re getting 2001:67c:2b0:db32:0:1:2275:3b51

Now save it into /etc/hosts file like this:

# Some other records are above, we add our record to the end of file
2001:67c:2b0:db32:0:1:2275:3b51 ipinfo.io

And finally check with cURL:

# fetch page via curl
curl ipinfo.io
# response
{
  "ip": "195.140.194.147",
  "hostname": "pool147.nat64.trex.fi",
  "city": "Tampere",
  "region": "Pirkanmaa",
  "country": "FI",
  "loc": "61.4991,23.7871",
  "org": "AS29432 TREX Regional Exchanges Oy",
  "postal": "33100",
  "timezone": "Europe/Helsinki",
  "readme": "https://ipinfo.io/missingauth"
}#

Results

After translation you can either use your synthetic IPv6 directly (if previously you used IPv4 directly) or add it as record into hosts file with any domain. Hosts file has higher priority over any other DNS resolvers (including the system one), so you will be able to override IP address of specified domain.