Hash-based AAAA records

hash.metans.net provides auto-generated AAAA records based on a hash of the terminal labels of a name.

$ dig +short hello-world-1.20010db8.48.hash.metans.net AAAA
2001:db8:0:2888:42b3:2cd1:9221:10ac
$ dig +short hello-world-2.20010db8.48.hash.metans.net AAAA
2001:db8:0:f44e:cb9d:7024:5a18:e1df

Note: This is an experimental feature I added to solve a very idiosyncratic problem. I don't expect its behavior to change at this point in time, but I don't feel comfortable giving the same level of stability guarantee the regular metans.net service has. If you're considering using this, ping me.

Why?

With IPv6 addresses being longer, you often care less about the exact numerical value of an address than you did with IPv4. Conversely, having DNS records becomes more important.

For example, consider the case of a VPN that uses IPv6 exclusively (maybe using an ULA prefix), where new members can appear dynamically. Typical cases are M2M or IoT applications. While the management overhead for the VPN infrastructure can be kept low using some kind of PKI infrastructure, providing DNS for each device requires continually updating a zone when a new device appears and possibly a mechanism for expiring old records.

The hash.metans.net resolves this problem by statically allocating a fixed IP address below a given prefix to every possible name. Applying the same calculation when assigning an IP address to a device with a given name effectively results in a matching DNS record.

How does it work?

The first two labels below hash.metans.net describe an IPv6 prefix. The remaining labels are hashed using BLAKE2b-128 using NUL bytes as separators. The trailing bits of the resulting hash form the rest of the address:

$ dig +short hello-world-1.20010db8.64.hash.metans.net AAAA | cut -d: -f4-
42b3:2cd1:9221:10ac
$ printf 'hello-world-1' | b2sum -l 128 | cut -d ' ' -f 1 | tail -c 17
42b32cd1922110ac
$
$ dig +short hello-world-1.foo.20010db8.64.hash.metans.net AAAA | cut -d: -f4-
1623:7f0a:5a31:a26
$ printf 'foo\0hello-world-1' | b2sum -l 128 | cut -d ' ' -f 1 | tail -c 17
16237f0a5a310a26

Multiple levels of labels are especially useful for resolving collisions. hash.metans.net deliberately does not special case this with the keyed mode of BLAKE2b or use other superior ways of domain separation to stay within the limits of what can be easily computed using the lowest common denominator of shell utilities etc.

How do I use it?

hash.metans.net is meant to be used in combination with DNAME records. If your prefix is 2001:db8::/64, and you want to use the domain my-vpn.example.com, you would add the following record to the example.com zone:

my-vpn 600 IN DNAME 20010db8.64.hash.metans.net.

Note that while the records synthesized by hash.metans.net inherently cannot change and thus have a long TTL (7 days), the TTL of your DNAME record should be short enough to allow for changing your configuration in a reasonable time frame if you need to.

Then, names can be resolved below that domain:

$ dig hello-world-1.my-vpn.example.com AAAA
[...]
;; ANSWER SECTION:
my-vpn.example.com.		600	IN	DNAME	20010db8.64.hash.metans.net.
hello-world-1.my-vpn.example.com. 600 IN	CNAME	hello-world-1.20010db8.64.hash.metans.net.
hello-world-1.20010db8.64.hash.metans.net. 86400 IN AAAA 2001:db8::42b3:2cd1:9221:10ac
[...]

Downsides

Unlike the mechanism behind the main metans.net service, a hash function is not a bijection. This has two important downsides:

However, this might be acceptable depending on your application. In particular, the probability of encountering a collision with a standard /64 prefix is negligible in many deployments.