[BALUG-Talk] DNS ... CNAME records ... to CNAMES? How long a chain? Loops? ...
Michael Paoli
Michael.Paoli@cal.berkeley.edu
Sun Oct 9 20:58:56 UTC 2022
DNS ... CNAME records ... to CNAMES? How long a chain? Loops? ...
So, sometimes the question comes up, can you do a CNAME to a CNAME?
Yes, ... but not recommended. What about CNAME to CNAME to CNAME ...?
Again, not recommended, but within reason, it will still work.
Up to? Probably 8, ... maybe 16 ... more than that? Hypothetically,
but mostly not.
What about a CNAME loop? That should cleanly fail ... but that
doesn't mean it always does.
I set up some CNAME "test" records again ... if folks wanted to poke at
such a bit and see how it behaves.
First teensy primer on number bases >10 and >16 ... just continue the
character sequence so ... I use some base36 - characters go from 0
through 9 then a through z. I did that to make the
coding/interpretation of such fairly easy to be able to go up to 36 with
a single character.
Anyway, set up temporarily (goes away
# at -l | fgrep root
71 Sat Nov 12 09:52:00 2022 a root
)
fair number of CNAME records one can poke at, notably a chain, and
several loops.
So, the chain ... eventually resolves to working IPs ..., we have:
cc-0-tmp.balug.org. IN CNAME www.balug.org.
cc-1-tmp.balug.org. IN CNAME cc-0-tmp.balug.org.
cc-2-tmp.balug.org. IN CNAME cc-1-tmp.balug.org.
cc-3-tmp.balug.org. IN CNAME cc-2-tmp.balug.org.
...
cc-h-tmp.balug.org. IN CNAME cc-g-tmp.balug.org.
cc-i-tmp.balug.org. IN CNAME cc-h-tmp.balug.org.
cc-j-tmp.balug.org. IN CNAME cc-i-tmp.balug.org.
(cc - think Cname Chain) so, a chain of 20 (0 through j, base36) CNAME
records.
Feel free to, e.g. try resolving, doing some use of dig(1) to lookup the
DNS data, etc.
Oh, and yes, works as a web site ... cert even matches those names ...
but since those CNAMES aren't canonical names for that site, the website
is configured to redirect to a canonical name for the web site.
Loops! Yes, also set up CNAME loops of various sizes one can poke at:
cl-0-tmp.balug.org. IN CNAME cl-0-tmp.balug.org.
cl-01-tmp.balug.org. IN CNAME cl-10-tmp.balug.org.
cl-10-tmp.balug.org. IN CNAME cl-01-tmp.balug.org.
cl-012-tmp.balug.org. IN CNAME cl-201-tmp.balug.org.
cl-120-tmp.balug.org. IN CNAME cl-012-tmp.balug.org.
cl-201-tmp.balug.org. IN CNAME cl-120-tmp.balug.org.
...
cl-0123456789abcdef-tmp.balug.org. IN CNAME
cl-f0123456789abcde-tmp.balug.org.
...
cl-0123456789abcdefg-tmp.balug.org. IN CNAME
cl-g0123456789abcdef-tmp.balug.org.
...
cl-0123456789abcdefgh-tmp.balug.org. IN CNAME
cl-h0123456789abcdefg-tmp.balug.org.
So cl (think Cname Loop), loops from 1 to 18 CNAME records in each loop.
If we use > to represent our link, we have these loops - showing the
portion that varies in each name:
0>0
01>10>01
012>201>120>012
...
0123456789abcdefgh>h0123456789abcdefg>...>0123456789abcdefgh
Also, RFC 1034 (look for "loop" within) we have:
The recommended
priorities for the resolver designer are:
1. Bound the amount of work (packets sent, parallel processes
started) so that a request can't get into an infinite loop or
start off a chain reaction of requests or queries with other
implementations EVEN IF SOMEONE HAS INCORRECTLY CONFIGURED
SOME DATA.
domain software should not fail when presented with CNAME
chains or loops; CNAME chains should be followed and CNAME loops
signaled as an error.
Multiple levels of
aliases should be avoided due to their lack of efficiency, but should
not be signaled as an error. Alias loops and aliases which point to
non-existent names should be caught and an error condition passed back
to the client.
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.
And ... was pretty easy to write little program
to create the records ... and get rid of same records.
Yes, Dynamic DNS (DDNS) also makes it quite nice 'n easy,
and also at(1) to later do the removals:
#!/bin/sh
# add/del CNAME chain / loop(s)
set -e
suffix=-tmp.balug.org.
ttl=300
b="$(basename "$0")"
case "$b" in
add|CNAMEadd)
adddel=add
;;
del|CNAMEdel)
adddel=del
;;
*)
echo "$0: expecting to be invoked as add, CNAMEadd, del, or" \
"CNAMEdel, aborting" 1>&2
exit 1
;;
esac
# our base36 digits:
seq=0123456789abcdefghijklmnopqrstuvwxyz # max 36
{
# CNAME chain
prefix=cc- # Cname Chain
c0=www.balug.org. # Chain 0 to (anchor)
max=20 # integer between 2 and 36, this is count, not value
set -- \
$(
echo "$seq" |
sed -ne '
s/^\(.\{'"$max"'\}\).*$/\1/
s/./& /gp
'
)
o="$1"; shift
echo "update $adddel $prefix$o$suffix $ttl IN CNAME $c0"
while :
do
case "$1" in ?):;;*)break;;esac # break if < 1 arg
echo "update $adddel $prefix$1$suffix $ttl IN CNAME" \
"$prefix$o$suffix"
o="$1"; shift
done
# CNAME loops
prefix=cl- # Cname Loop
max=18 # integer between 1 and 36
n="$max"
while [ "$n" -ge 1 ]
do
a=$(
echo "$seq" |
sed -ne 's/^\(.\{'"$n"'\}\).*$/\1/p'
)
while :
do
b=$(
echo "$a" |
sed -ne 's/^\(.*\)\(.\)$/\2\1/p'
)
echo "update $adddel $prefix$a$suffix $ttl IN CNAME" \
"$prefix$b$suffix"
case "$b" in 0*) break;; esac # last one
a="$b"
done
n="$(expr "$n" - 1)"
done
echo send
} |
nsupdate -l
More information about the BALUG-Talk
mailing list