How to get the CNAME for a domain?
Grant Taylor
gtaylor at tnetconsulting.net
Thu Jan 12 03:13:18 UTC 2017
On 01/10/2017 03:40 AM, Michelle Konzack wrote:
> Hello experts,
/me looks over his shoulders wondering who's being addressed.
> I do not want to querry the world, but only my own Name Server for CNAME
> configured (or not).
Okay. ONLY use local data. Check.
> Currently I am updating my web administration interface and I have lost
> over the time a script, which queried my Name Server for CNAMES.
Been there, done that. Here, have a drink (of your choice) to wash the
bitter taste of lost tools down.
> E.g. if I have a physical server <vserver04.tamay-dogan.net> I like to
> know, which CNAMEs (on MY Name Server) pointing to it as
>
> www.electronica.tamay-dogan.net IN CNAME vserver04.tamay-dogan.net
If I'm understanding you correctly, you are wanting to know the name of
the RR that has your server as the target of a CNAME. (Correct me if
I'm wrong.)
> OK, I can grep the whole /etc/bind/master/ directory, but since my Name
> Server is responsable for several 1000 (sub)domains, the execution of
> the script takes ages!
Something seems wrong here. Unix is EXTREMELY good at text processing,
which is what I think would be best here. (I see no reason to involve
DNS at all, besides the obvious data subject.)
A few things jump out at me as I read your script, some of which could
have significant impact on performance.
> ----[tdgetincname]------------------------------------------------------
> #!/bin/bash
>
> VSERVER="$1"
>
> LIST=`cd /etc/bind/master/ && find -type f |grep -v -E "(.conf|.signed|.private|.key)$" |sed 's|^\./||' |sort`
It looks like you're looking to exclude files that end in .conf or
.signed, or .private, or .key.
However, that's not what you're actually asking (e)grep to do. You're
really asking (e)grep for any occurrence of conf or signed or private or
key with any character before them.
I suspect you meant to escape the periods so that you are looking for
the literal strings ".conf" or ".signed" or ".private" or ",key".
grep -v -E "(\.conf|\.signed|\.private|\.key)$"
I'm guessing this will speed things up more than a little bit.
I question why you cd to the /etc/bind/master directory rather than just
passing the path to find. (Perhaps it's because find's output then
returns the full path, instead of just file names. I think there are
other ways to deal with this.)
Why are you excluding the files types that you don't want? I would
think that it would be better to include just the files types that you
do want. (I'm going to assume that you want .zone files for the rest of
this email.)
It looks like you're removing the leading "./" from find's output.
Curious, is sorting the output strictly necessary? Or just a would be
nice to have. (I ask because this may be a small performance hit.)
Putting all of that I'd be tempted to try to accomplish the goal of
building the list of files differently.
find /etc/bind/master/ -type f -name '*.zone' | sed 's|.*\/||'
Let find generate a raw list (/etc/bind/master/example.com.zone) and
then remove all of the head with sed so that you end up with
(example.com.zone).
Q: Do you have all your zone files in one directory, /etc/bind/master,
or are they separated in something like /etc/bind/master/$client/$zone?
- This would change the RE.
(Sorting the output if you want to.)
> for FILE in ${LIST}
> do
> RET=`cd /etc/bind/master/ && grep -E "IN CNAME.*${VSERVER}" ${FILE} |sed "s|\.[ \t]*IN CNAME.*||"`
I suspect that the first ".*" is desired to deal with various types of
white space.
I'm guessing that you are wanting to take grep's output, something like
"www.electronica.tamay-dogan.net IN CNAME
vserver04.tamay-dogan.net", and turn it into just the owning RR name,
"www.electronica.tamay-dogan.net". (Correct me if I'm wrong.)
> if [ -n "${RET}" ]
> then
> echo "${RET}"
> fi
It looks like you are printing the owning RR name /if/ there is a value.
I'm guessing your RET variable will either be zero bytes or a list of
one or more owning RR names. (Correct me if I'm wrong.)
> done
> ------------------------------------------------------------------------
>
> Note: If I do not the "cd /etc/bind/master/ &&",
> I exceed the maximum lenght of the commandline.
I'm guessing that you have enough files that your sub-command that
populates the LIST variable is too long.
> Any ideas how to do this better?
Maybe ...
I think I'd be tempted to do something like the following:
for ZONE in $(find /etc/bind -type f -name '*.zone'); do
awk '($2 == "CNAME" && $3 == "vserver04.tamay-dogan.net."){print $1}'
${ZONE}
done
To me this has a number of advantages:
- There are no Regular Expressions, which can be slow.
- awk will deal with the different fields for you.
- Match *JUST* CNAME records.
- Match the CNAME target
- Print the RR name
- You can pass a fully qualified file to awk.
- No need to for text manipulation.
This is all very simple text manipulation (filtering), which unix excels at.
I have tested the above code and it "Works for Me" (TM).
However ... there is a potential problem. If you are using abbreviated
zone files, you may end up missing the ORIGIN in the output since it's
not on the line. I.e. the following zone file:
$ORIGIN electronica.tamay-dogan.net.
www IN CNAME vserver04.tamay-dogan.net.
Similarly you may miss some CNAME's if the target is abbreviated. I.e.:
$ORIGIN tamay-dogan.net.
www,electronica IN CNAME vserver04
About the only (trivial) way that I can see to get around this (type of)
limitation is to actually parse the zone data, ...or use a tool that
does so for you.
I think it's easiest to cheat and parse the output of a "dig axfr".
for ZONE in $(find /etc/bind -type f -name '*.zone'); do
dig axfr ${ZONE} | awk '($4 == "CNAME" && $5 ==
"vserver04.tamay-dogan.net."){print $1}'
done
Note that the field numbers change because dig includes the TTL and the
protocol type, IN.
> Thanks in avance
You're welcome.
I hope I helped.
Good luck.
(Please share what you end up doing.)
--
Grant. . . .
unix || die
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 3717 bytes
Desc: S/MIME Cryptographic Signature
URL: <https://lists.isc.org/pipermail/bind-users/attachments/20170111/54106a90/attachment.bin>
More information about the bind-users
mailing list