PyLDNS based tool for DNS configuration check

Dnscheck is a tool written in Python which implements some basic DNS tests. This tests are designed to discover some errors or mistakes in the DNS configuration. Or they can just give useful info about a domain.

Features

  • Dnscheck is a modular tool. The functionality of the program can be enhanced by adding more plugins preforming additional tests.
  • Each module can have a list of dependencies on other modules. A module can process the results of other modules.
  • The tool can work with the IPv6 address-space. Feel free to enable the IPv6 functionality.
  • It is possible to fully disable the IPv4 functionality, however this is not recommended.
  • Includes DNSSEC functionality.
  • Supports IDN.
  • Can check HTTP servers for activity.
  • Can check SMTP servers for activity.

Installation and testing

In order to use the tool you need to have the ldns library present on you system and a wrapper module installed in your Python sitedir. If you do, you may skip the installation procedure to point 5.

  1. Download the source archive (pydnscheck) and extract it by typing:

    > cd
    > mkdir pydnscheck
    > cd pydnscheck
    > tar -xzf pydnscheck.tar.gz
    > ls -l
    dnscheck
    ldns-src
  1. Configure and compile ldns:

    > cd ldns-src
    > ./configure --with-pyldns
    > make
  2. If you do not want to install the wrapper and library onto your system then, instead of make install, type the command:

    > cd contrib/python
    > make testenv
    > cd ../../..

    This will start a new shell, during which execution the symbolic links will be working. When you exit the shell, then the symbolic links will be deleted. The application will not work in case when the symbolic links do not exist.

  3. If you want to install the ldns library and Python wrapper onto your system run:

    > make install

    Skip to point 6.

  4. If you have already installed the ldns library and Python wrapper, you may download only the dnscheck sources (dnschecksrc) and run:

    > cd
    > mkdir pydnscheck
    > cd pydnscheck
    > tar -xzf pydnscheck-src.tar.gz
    > ls -l
    dnscheck
  1. Two files named dnsc and dnscheck.py are to be found in the directory. If you have the ldns library with the wrapper already installed onto you system, then use directly the dnscheck.py file. In the other case you must call the dnsc script which sets the library path and then calls the dnscheck.py.:

    > cd dnscheck
    > ls
    dnsc
    dnscheck.py
    doc
    modules

    You may edit the shell script according to your desire.

  2. Run the application:

    > ./dnsc -d cz
  3. You may get a result similar to this:

    Warning: environment variable LANG=cs_CZ.ISO-8859-2 differs from the value obtained from default locale cs_CZ.ISO8859-2
            using ISO8859-2
    
    All DNS servers responding: yes
    
    All DNS servers have the same serial number: no
    
    All DNS servers are authoritative: yes
    
    All DNS servers have the same primary server name ( a.ns.nic.cz. ): yes
    
    All primary server name values seem syntactically ok: yes
    
    All DNS servers have the same email ( hostmaster.nic.cz. ): yes
    
    All email values seem syntactically ok: yes
    
    Each reverse-resolved name for each ipv4 is resolvable back to its original ip: no
    
    At least one reverse-resolved name for each ipv4 is resolvable back to its original ip: yes
    
    All DNS servers listed in NS records on each server: yes

Parameters

Usage

> ./dnsc -h
Usage: dnscheck.py [options]

Options:
  -h, --help            show this help message and exit
  -d DOMAIN, --dname=DOMAIN
                        set domain name
  -n, --noipv4          disable IPv4 checks
  -6, --ipv6            enable IPv6 checks - does not create IPv6 resolvers
  -r, --resolver6       enable IPv6 checks - creates IPv6 based resolvers
  -R VALIDATING-RESOLVER-IP, --vresolver=VALIDATING-RESOLVER-IP
                        use a validating resolver to resolve IPs
  -m, --mxrecs          show MX records
  -M, --mailcheck       checks mailservers
  -a NAME, --arecs=NAME
                        show A records for names in domain, this option may be
                        used multiple times
  -w, --web             check machines listed by A record parameters for HTTP
                        server presence
  -z, --zone            check zone download
  -v, --verbose         increase verbosity, may be used multiple times

Usage

The default output is not very verbose, try to increase its verbosity by specifying more -v options.

If you want to resolve IPv6 addresses, you must specify the -6 switch. This does not enable resolvers based on IPv6. Instead it only asks for AAAA records. If you want to query IPv6 nameservers, you need to specify the -r option. Adding only the -6r option does not increase the verbosity. If you want to see what happened use the -vv option:

> ./dnsc -d cz -6r -vv
...

Module: DNS machines
========================================================
Nameservers for domain: cz.
a.ns.nic.cz. ipv4: 217.31.205.180
a.ns.nic.cz. ipv6: 2001:1488:dada:176::180
b.ns.nic.cz. ipv4: 217.31.205.188
b.ns.nic.cz. ipv6: 2001:1488:dada:184::188
c.ns.nic.cz. ipv4: 195.66.241.202
c.ns.nic.cz. ipv6: 2a01:40:1000::2
d.ns.nic.cz. ipv4: 193.29.206.1
d.ns.nic.cz. ipv6: 2001:678:1::1
e.ns.nic.cz. ipv4: 194.146.105.38
f.ns.nic.cz. ipv4: 193.171.255.48
f.ns.nic.cz. ipv6: 2001:628:453:420::48

...

You may disable the IPv4 functionality by using the -n option. However this is not recommended. It may cause the application to crash, because of an inaccessible nameserver on IPv4 networks:

> ./dnsc -d cz -6rn -vv
...

Module: DNS machines
========================================================
Nameservers for domain: cz.
a.ns.nic.cz. ipv6: 2001:1488:dada:176::180
b.ns.nic.cz. ipv6: 2001:1488:dada:184::188
c.ns.nic.cz. ipv6: 2a01:40:1000::2
d.ns.nic.cz. ipv6: 2001:678:1::1
f.ns.nic.cz. ipv6: 2001:628:453:420::48

...

The application supports IDN:

> ./dnsc -d háčkyčárky.cz -a www -vv
Warning: environment variable LANG=cs_CZ.ISO-8859-2 differs from the value obtained from default locale cs_CZ.ISO8859-2
         using ISO8859-2

...

Module: Get NS records
========================================================
NS records for a.ns.xn--hkyrky-ptac70bc.cz. ipv4 217.31.205.180
server: a.ns.xn--hkyrky-ptac70bc.cz. discovered-ipv4: 217.31.205.180 glue-ipv4: 217.31.205.180
server: b.ns.xn--hkyrky-ptac70bc.cz. discovered-ipv4: 217.31.205.188 glue-ipv4: 217.31.205.188

NS records for b.ns.xn--hkyrky-ptac70bc.cz. ipv4 217.31.205.188
server: a.ns.xn--hkyrky-ptac70bc.cz. discovered-ipv4: 217.31.205.180 glue-ipv4: 217.31.205.180
server: b.ns.xn--hkyrky-ptac70bc.cz. discovered-ipv4: 217.31.205.188 glue-ipv4: 217.31.205.188

a.ns.xn--hkyrky-ptac70bc.cz. 217.31.205.180 ns entry for a.ns.xn--hkyrky-ptac70bc.cz. present: True
a.ns.xn--hkyrky-ptac70bc.cz. 217.31.205.180 ns entry for b.ns.xn--hkyrky-ptac70bc.cz. present: True
b.ns.xn--hkyrky-ptac70bc.cz. 217.31.205.188 ns entry for a.ns.xn--hkyrky-ptac70bc.cz. present: True
b.ns.xn--hkyrky-ptac70bc.cz. 217.31.205.188 ns entry for b.ns.xn--hkyrky-ptac70bc.cz. present: True

All DNS servers listed in NS records on each server: yes

...

When you specify the -m options, then MX records will be resolved:

> ./dnsc -d fit.vutbr.cz -m -v
...

Module: Get MX records
========================================================
kazi.fit.vutbr.cz. 147.229.8.12 : 10 kazi.fit.vutbr.cz.
kazi.fit.vutbr.cz. 147.229.8.12 : 20 eva.fit.vutbr.cz.
guta.fit.vutbr.cz. 147.229.9.11 : 10 kazi.fit.vutbr.cz.
guta.fit.vutbr.cz. 147.229.9.11 : 20 eva.fit.vutbr.cz.
rhino.cis.vutbr.cz. 147.229.3.10 : 10 kazi.fit.vutbr.cz.
rhino.cis.vutbr.cz. 147.229.3.10 : 20 eva.fit.vutbr.cz.
gate.feec.vutbr.cz. 147.229.71.10 : 10 kazi.fit.vutbr.cz.
gate.feec.vutbr.cz. 147.229.71.10 : 20 eva.fit.vutbr.cz.

MX records found: yes

Equal nameservers listed: yes

Equal MX records on nameservers: yes

...

If you specify the -M option, the resolved mailservers will be checked for activity:

> ./dnsc -d fit.vutbr.cz -M -vv
...

Module: Test mail servers
========================================================
adding mailserver kazi.fit.vutbr.cz. 147.229.8.12
adding mailserver eva.fit.vutbr.cz. 147.229.176.14

Mail server (kazi.fit.vutbr.cz. 147.229.8.12) has valid SMTP:  True
Mail server (kazi.fit.vutbr.cz. 147.229.8.12) response:  220 kazi.fit.vutbr.cz ESMTP Sendmail 8.14.3/8.14.3; Wed, 14 Jan 2009 19:21:42 +0100 (CET)
Mail server (eva.fit.vutbr.cz. 147.229.176.14) has valid SMTP:  True
Mail server (eva.fit.vutbr.cz. 147.229.176.14) response:  220 eva.fit.vutbr.cz ESMTP Sendmail 8.14.3/8.14.3; Wed, 14 Jan 2009 19:21:42 +0100 (CET)

All found mail servers have valid SMTP: yes

...

You may ask for A and/or AAAA records by specifying the -a NAME option. This will resolve the A/AAAA records according to the chosen IPv4/IPv6 parameters. Also it will produce useful info:

> ./dnsc -d fit.vutbr.cz -a www -a merlin -6 -v
...

Module: Get A records
========================================================
kazi.fit.vutbr.cz. 147.229.8.12 found A www.fit.vutbr.cz. : True
kazi.fit.vutbr.cz. 147.229.8.12 found authoritative A answer for www.fit.vutbr.cz. : True
kazi.fit.vutbr.cz. 147.229.8.12 found A merlin.fit.vutbr.cz. : True
kazi.fit.vutbr.cz. 147.229.8.12 found authoritative A answer for merlin.fit.vutbr.cz. : True
kazi.fit.vutbr.cz. 147.229.8.12 found AAAA www.fit.vutbr.cz. : True
kazi.fit.vutbr.cz. 147.229.8.12 found authoritative AAAA answer for www.fit.vutbr.cz. : True
kazi.fit.vutbr.cz. 147.229.8.12 found AAAA merlin.fit.vutbr.cz. : False
kazi.fit.vutbr.cz. 147.229.8.12 found authoritative AAAA answer for merlin.fit.vutbr.cz. : False
guta.fit.vutbr.cz. 147.229.9.11 found A www.fit.vutbr.cz. : True
guta.fit.vutbr.cz. 147.229.9.11 found authoritative A answer for www.fit.vutbr.cz. : True
guta.fit.vutbr.cz. 147.229.9.11 found A merlin.fit.vutbr.cz. : True
guta.fit.vutbr.cz. 147.229.9.11 found authoritative A answer for merlin.fit.vutbr.cz. : True
guta.fit.vutbr.cz. 147.229.9.11 found AAAA www.fit.vutbr.cz. : True
guta.fit.vutbr.cz. 147.229.9.11 found authoritative AAAA answer for www.fit.vutbr.cz. : True
guta.fit.vutbr.cz. 147.229.9.11 found AAAA merlin.fit.vutbr.cz. : False
guta.fit.vutbr.cz. 147.229.9.11 found authoritative AAAA answer for merlin.fit.vutbr.cz. : False
rhino.cis.vutbr.cz. 147.229.3.10 found A www.fit.vutbr.cz. : True
rhino.cis.vutbr.cz. 147.229.3.10 found authoritative A answer for www.fit.vutbr.cz. : True
rhino.cis.vutbr.cz. 147.229.3.10 found A merlin.fit.vutbr.cz. : True
rhino.cis.vutbr.cz. 147.229.3.10 found authoritative A answer for merlin.fit.vutbr.cz. : True
rhino.cis.vutbr.cz. 147.229.3.10 found AAAA www.fit.vutbr.cz. : True
rhino.cis.vutbr.cz. 147.229.3.10 found authoritative AAAA answer for www.fit.vutbr.cz. : True
rhino.cis.vutbr.cz. 147.229.3.10 found AAAA merlin.fit.vutbr.cz. : False
rhino.cis.vutbr.cz. 147.229.3.10 found authoritative AAAA answer for merlin.fit.vutbr.cz. : False
gate.feec.vutbr.cz. 147.229.71.10 found A www.fit.vutbr.cz. : True
gate.feec.vutbr.cz. 147.229.71.10 found authoritative A answer for www.fit.vutbr.cz. : True
gate.feec.vutbr.cz. 147.229.71.10 found A merlin.fit.vutbr.cz. : True
gate.feec.vutbr.cz. 147.229.71.10 found authoritative A answer for merlin.fit.vutbr.cz. : True
gate.feec.vutbr.cz. 147.229.71.10 found AAAA www.fit.vutbr.cz. : True
gate.feec.vutbr.cz. 147.229.71.10 found authoritative AAAA answer for www.fit.vutbr.cz. : True
gate.feec.vutbr.cz. 147.229.71.10 found AAAA merlin.fit.vutbr.cz. : False
gate.feec.vutbr.cz. 147.229.71.10 found authoritative AAAA answer for merlin.fit.vutbr.cz. : False
A records resolved for merlin.fit.vutbr.cz. on all nameservers: True
AAAA records resolved for merlin.fit.vutbr.cz. on all nameservers: False
A records for merlin.fit.vutbr.cz. all authoritative: True

A records resolved for www.fit.vutbr.cz. on all nameservers: True
AAAA records resolved for www.fit.vutbr.cz. on all nameservers: True
A records for www.fit.vutbr.cz. all authoritative: True
AAAA records for www.fit.vutbr.cz. all authoritative: True

All A records successfully resolved: yes

All A records answered by an authoritative answer: yes

All AAAA records successfully resolved: no

...

When specifying the -z option, the checker will try to download the zonefile from the nameservers:

> ./dnsc -d fit.vutbr.cz -z -v
...

Module: Get zone, AXFR
========================================================
kazi.fit.vutbr.cz. 147.229.8.12 zone transfers: False
guta.fit.vutbr.cz. 147.229.9.11 zone transfers: False
rhino.cis.vutbr.cz. 147.229.3.10 zone transfers: False
gate.feec.vutbr.cz. 147.229.71.10 zone transfers: False

All DNS servers have inactive AXFR transfers ( domain fit.vutbr.cz. ): yes

...

By default the checker checks reverse records to the IP addresses of the found nameservers. The reverse-resolved names are translated back to IPs and compared with the original IPs. If an IP inconsistency occurs or the IP could not be resolved back a notification is displayed:

> ./dnsc -d cz -v
...

Module: Get PTR records
========================================================
e.ns.nic.cz. ipv4 194.146.105.38 found ip: 194.146.105.38
c.ns.nic.cz. ipv4 195.66.241.202 found ip: 195.66.241.202
c.ns.nic.cz. ipv4 195.66.241.202 leads to failed resolving via (in order): nsl.tld.cz. www.sury.cz.
d.ns.nic.cz. ipv4 193.29.206.1 found ip: 193.29.206.1
b.ns.nic.cz. ipv4 217.31.205.188 found ip: 217.31.205.188
f.ns.nic.cz. ipv4 193.171.255.48 found ip: 193.171.255.48
a.ns.nic.cz. ipv4 217.31.205.180 found ip: 217.31.205.180

Each reverse-resolved name for each ipv4 is resolvable back to its original ip: no

At least one reverse-resolved name for each ipv4 is resolvable back to its original ip: yes

...

The messages

c.ns.nic.cz. ipv4 195.66.241.202 leads to failed resolving via (in order): nsl.tld.cz. www.sury.cz.

Each reverse-resolved name for each ipv4 is resolvable back to its original ip: no

mean that the reverse resolution of 195.66.241.202 leads to domain name nsl.tld.cz, which has the canonical name www.sury.cz, which is not resolvable to IP.

When you use the -w option then the machines listed using the -a NAME option will be checked for HTTP server presence. If the domain name is resolvable to an IP, then the machine is also checked:

> ./dnsc -d google.com -a www -a ns1 -w -v
...

Module: Test http servers
========================================================
Machine (ns1.google.com. 216.239.32.10) has active HTTP:  False
Machine (www.google.com. 74.125.77.147) has active HTTP:  True
Machine (www.google.com. 74.125.77.99) has active HTTP:  True
Machine (www.google.com. 74.125.77.103) has active HTTP:  True
Machine (www.google.com. 74.125.77.104) has active HTTP:  True
Machine (google.com. 72.14.205.100) has active HTTP:  True
Machine (google.com. 74.125.45.100) has active HTTP:  True
Machine (google.com. 209.85.171.100) has active HTTP:  True

Some machines have active HTTP: yes

...

When you specify -vv then the HTTP header, when received, will be displayed:

> ./dnsc -d fit.vutbr.cz -a www -w -vv
...

Module: Test http servers
========================================================
adding machine www.fit.vutbr.cz. 147.229.9.23

Machine (www.fit.vutbr.cz. 147.229.9.23) has active HTTP:  True
Machine (www.fit.vutbr.cz. 147.229.9.23) HTTP server:  Apache/1.3.41 Ben-SSL/1.59 (Unix)

Some machines have active HTTP: yes

...

The DNSSEC functionality has to be switched on explicitly by specifying a validating resolver IP:

> ./dnsc -d dnssec.cz -a www -vv -R 127.0.0.1
...

Module: Check DNSSEC
========================================================
using validating resolver
adding to resolver 127.0.0.1
A and AAAA records:
www.dnssec.cz. 217.31.205.50 DNSSEC secure: True

for www.dnssec.cz. received DNSSEC secured ipv4: 217.31.205.50

All answers DNSSEC secured by given resolver: yes

...

You may use also an IPv6 address to specify the validating resolver. If you dont have such an IP then you may try to setup an Unbound based validating resolver on your localhost. Some hints may be found in the Querying DNS-SEC validators example in the PyLDNS documentation.