DNS lookup tools
Python
Switch branches/tags
Nothing to show
Clone or download
kalou enhance TYPE-based query helper
Provide an easy way to query for text representations:

In [4]: dnsknife.Checker('example.net').NS(text=True)
Out[4]: ['ns-6-c.example.net.', 'ns-1-a.example.net.', 'ns-5-b.example.net.']

might resolve #4
Latest commit 295e7f7 Feb 1, 2018

README.rst

dnsknife: a DNS tool

Quick overview:

>>> from dnsknife import resolver
>>> ans = resolver.query('example.com', 'A', dnssec=True)

Specific queries shortcuts:

>>> import dnsknife
>>> print dnsknife.Checker('example.com').mx()
[]

>>> print dnsknife.Checker('example.com').spf()
None

>>> print dnsknife.Checker('example.com').txt()
$Id: example.com 4415 2015-08-24 20:12:23Z davids $
v=spf1 -all

Checking a domain TXT record is installed, looking at each domain NS (no local caches) for a match:

>>> from dnsknife import Checker
>>> Checker('example.com', direct=True).has_txt('dbef8938bef', ignore_case=True)
False

Or, if you are into domain challenges:

>>> from dnsknife import Checker

>>> Checker('example.com').has_challenge('secretkey')
False

>>> Checker('example.com').challenge('secretkey')
'f1ef9be83f844d64f8f2bea8bcfb9f7f4cf0792487ae24707937344dbec8f4fb'

Querying a few dozen things at the same time:

>>> from dnsknife.resolver import Resolver
>>> with Resolver(timeout=2) as r:
        a = r.query_at('www.example.com', 'A', '1.2.3.4')
        ...
        x = r.query_at('www.example.com', 'A', '1.2.3.4')

>>> print a.get()
<dns.resolver.Answer at 0x7f6e3d398ad0>

>>> print x.get()
<dns.resolver.Answer at 0x7f6e3d398bd0>

Scanning a zone:

In [16]: from dnsknife.scanner import Scanner
In [9]: time list(Scanner('google.com').scan())
CPU times: user 476 ms, sys: 28 ms, total: 504 ms
Wall time: 2.4 s
Out[9]:
[<DNS mail.google.com. IN CNAME RRset>,
 <DNS support.google.com. IN CNAME RRset>,
 <DNS google.com. IN A RRset>,
 <DNS google.com. IN AAAA RRset>,
 <DNS google.com. IN NS RRset>,
 <DNS google.com. IN MX RRset>,
 <DNS google.com. IN TXT RRset>,
 <DNS www.google.com. IN A RRset>,
 <DNS www.google.com. IN AAAA RRset>,
 <DNS googlemail.l.google.com. IN A RRset>,
 <DNS googlemail.l.google.com. IN AAAA RRset>,
 <DNS mail.google.com. IN TXT RRset>,
 <DNS corp.google.com. IN A RRset>,
 <DNS corp.google.com. IN AAAA RRset>,
 <DNS corp.google.com. IN NS RRset>,
 <DNS admin.google.com. IN A RRset>,
 <DNS admin.google.com. IN AAAA RRset>,
 <DNS www3.l.google.com. IN A RRset>,
 <DNS www3.l.google.com. IN AAAA RRset>,
 <DNS googlemail.l.google.com. IN A RRset>,
 <DNS googlemail.l.google.com. IN AAAA RRset>,
 <DNS www3.l.google.com. IN A RRset>,
 <DNS www3.l.google.com. IN AAAA RRset>,
 <DNS ns4.google.com. IN A RRset>,
 <DNS ns2.google.com. IN A RRset>,
 <DNS ns1.google.com. IN A RRset>,
 <DNS ns3.google.com. IN A RRset>,
 <DNS alt4.aspmx.l.google.com. IN A RRset>,
 <DNS alt4.aspmx.l.google.com. IN AAAA RRset>,
 <DNS aspmx.l.google.com. IN A RRset>,
 <DNS aspmx.l.google.com. IN AAAA RRset>,
 <DNS alt2.aspmx.l.google.com. IN A RRset>,
 <DNS alt2.aspmx.l.google.com. IN AAAA RRset>,
 <DNS alt1.aspmx.l.google.com. IN A RRset>,
 <DNS alt1.aspmx.l.google.com. IN AAAA RRset>,
 <DNS alt3.aspmx.l.google.com. IN A RRset>,
 <DNS alt3.aspmx.l.google.com. IN AAAA RRset>,
 <DNS ns2.google.com. IN A RRset>,
 <DNS ns1.google.com. IN A RRset>,
 <DNS ns3.google.com. IN A RRset>,
 <DNS ns4.google.com. IN A RRset>]

It can be used for DNSSEC lookups, implements a few CDS/CDNSKEY drafts:

>>> c = Checker('example.com', dnssec=True)
>>> print c.spf()
None

>>> Checker('ten.pm').cdnskey()

---------------------------------------------------------------------------
BadCDNSKEY                                Traceback (most recent call last)
...

BadCDNSKEY: 1324 did not sign DNSKEY RR
>>> from dnsknife import dnssec, resolver
>>> keys = resolver.query('example.com', 'DNSKEY')
>>> dnssec.signed_by(ans, keys[0])
True
>>> dnssec.signers(dnsknife.Checker('pm.', dnssec=True)
                   .query_relative('', 'DNSKEY'))
{<DNS name pm.>: [35968, 60859]}
>>> dnssec.trusted(ans)
True

Finally it implements TPDA - the draft can be found in docs.

A third party provider wanting to change customer NS:

>>> from dnsknife import tpda

>>> # initialize with private key from repo:
>>> client = tpda.Client('ten.pm', 'dnsknife/tests/test.key')

>>> # generate url for domain
>>> URI = client.nameservers_uri('whe.re', ['ns1.ten.pm','ns2.ten.pm'])

A DNS operator/registrar validating inbound params:

>>> tpda.validate_URI(URI)
'http://partners.gandi.net/nameservers/v1?source=ten.pm&domain=whe.re&expires=20160415000918&ns=ns1.ten.pm&ns=ns2.ten.pm'