Skip to main content

No project description provided

Project description

Python DNS Client Library

A simple dns client library for send queries.

  • null-dependency
  • threadsafe
  • type hints

Install:

# from pypi.org
pip install dns-client

# latest commit
pip install git+https://github.com/s3rgeym/python-dns-client.git

Examples:

In [1]: from dns_client import DNSClient, RecordType

# use cloudflare to resolve dns queries
In [2]: client = DNSClient('1.1.1.1')

# get host ip address
In [3]: client.gethostaddr('yandex.ru')
Out[3]: '5.255.255.77'

# get name servers
In [4]: client.get_name_servers('yandex.ru')
Out[4]: ['ns2.yandex.ru', 'ns1.yandex.ru']

# each value is string
In [5]: client.query('www.linux.org')
Out[5]:
[Record(name='www.linux.org', qtype=<RecordType.A: 1>, qclass=<RecordClass.IN: 1>, ttl=300, value='172.67.73.26'),
 Record(name='www.linux.org', qtype=<RecordType.A: 1>, qclass=<RecordClass.IN: 1>, ttl=300, value='104.26.15.72'),
 Record(name='www.linux.org', qtype=<RecordType.A: 1>, qclass=<RecordClass.IN: 1>, ttl=300, value='104.26.14.72')]

In [6]: client.query('www.linux.org', RecordType.AAAA)
Out[6]:
[Record(name='www.linux.org', qtype=<RecordType.AAAA: 28>, qclass=<RecordClass.IN: 1>, ttl=300, value='2606:4700:20::681a:f48'),
 Record(name='www.linux.org', qtype=<RecordType.AAAA: 28>, qclass=<RecordClass.IN: 1>, ttl=300, value='2606:4700:20::681a:e48'),
 Record(name='www.linux.org', qtype=<RecordType.AAAA: 28>, qclass=<RecordClass.IN: 1>, ttl=300, value='2606:4700:20::ac43:491a')]

# but for MX each value is tuple where first element is priority
In [7]: client.query('yandex.ru', RecordType.MX)
Out[7]: [Record(name='yandex.ru', qtype=<RecordType.MX: 15>, qclass=<RecordClass.IN: 1>, ttl=1078, value=(10, 'mx.yandex.ru'))]

In [8]: client.query('ya.ru', RecordType.TXT)
Out[8]:
[Record(name='ya.ru', qtype=<RecordType.TXT: 16>, qclass=<RecordClass.IN: 1>, ttl=1200, value='_globalsign-domain-verification=dHoe580bPQ-lfi_vh-BEIwB4NAtUwURIzrzsivByVL'),
 Record(name='ya.ru', qtype=<RecordType.TXT: 16>, qclass=<RecordClass.IN: 1>, ttl=1200, value='e1c8e4dd3d13fad0dd9e8ed54a1813ececd3d5412fb16c4ed2c0612332950fe'),
 Record(name='ya.ru', qtype=<RecordType.TXT: 16>, qclass=<RecordClass.IN: 1>, ttl=1200, value='_globalsign-domain-verification=xUUDG4u7Zo56EmmFewz7Y4UK3MfAU7QSjAgBsy0w6q'),
 Record(name='ya.ru', qtype=<RecordType.TXT: 16>, qclass=<RecordClass.IN: 1>, ttl=1200, value='v=spf1 redirect=_spf.yandex.ru'),
 Record(name='ya.ru', qtype=<RecordType.TXT: 16>, qclass=<RecordClass.IN: 1>, ttl=1200, value='google-site-verification=SVTEeUiCU4KV-5qGw4o4JPok7mfsP8NtQTIdN6tt6Nw'),
 Record(name='ya.ru', qtype=<RecordType.TXT: 16>, qclass=<RecordClass.IN: 1>, ttl=1200, value='_globalsign-domain-verification=eLi0_-xATuNmRfuTIX8VQIvgfyi7Od7Hph4V0yNisF')]

In [9]: client.get_all_records('ya.ru')
Out[9]:
[('A', '5.255.255.242'),
 ('A', '77.88.55.242'),
 ('AAAA', '2a02:6b8::2:242'),
 ('NS', 'ns2.yandex.ru'),
 ('NS', 'ns1.yandex.ru'),
 ('MX', (10, 'mx.yandex.ru')),
 ('TXT', 'v=spf1 redirect=_spf.yandex.ru'),
 ('TXT',
  '_globalsign-domain-verification=xUUDG4u7Zo56EmmFewz7Y4UK3MfAU7QSjAgBsy0w6q'),
 ('TXT',
  '_globalsign-domain-verification=eLi0_-xATuNmRfuTIX8VQIvgfyi7Od7Hph4V0yNisF'),
 ('TXT',
  '_globalsign-domain-verification=dHoe580bPQ-lfi_vh-BEIwB4NAtUwURIzrzsivByVL'),
 ('TXT',
  'google-site-verification=SVTEeUiCU4KV-5qGw4o4JPok7mfsP8NtQTIdN6tt6Nw'),
 ('TXT', 'e1c8e4dd3d13fad0dd9e8ed54a1813ececd3d5412fb16c4ed2c0612332950fe')]

In [10]: adguard_client = DNSClient('94.140.14.14')

# unknown dns record types and some other returns raw bytes
In [11]: adguard_client.query('www.linux.org', RecordType.ANY)
Out[11]: [Record(name='www.linux.org', qtype=<RecordType.UNKNOWN: -1>, qclass=<RecordClass.IN: 1>, ttl=3280, value=b'\x07RFC8482\x00')]

# exceptions
# axfr queries are useful for domain scanning
In [12]: adguard_client.query('www.linux.org', RecordType.AXFR)
---------------------------------------------------------------------------
DNSBadResponse                               Traceback (most recent call last)
Cell In[12], line 1
...
DNSBadResponse: dns server returns bad response code: 0x05

# you can get entire response instead list of records
In [13]: adguard_client.get_response_query('www.linux.org', RecordType.AXFR)
Out[13]: Packet(header=Header(id=36118, response=True, opcode=<OpCode.QUERY: 0>, authoritative_record=False, truncated=False, recursion_desired=True, recursion_available=False, reserved=2, rcode=<ResponseCode.REFUSED: 5>, num_questions=1, num_records=0, num_authorities=0, num_additionals=0), questions=[Question(name='www.linux.org', qtype=<RecordType.AXFR: 252>, qclass=<RecordClass.IN: 1>)], records=[])

CLI Usage:

$ python -m dns_client google.co -t ns -d
DEBUG:__main__:set header flags: 0000000100100000
DEBUG:__main__:Packet(header=Header(id=11148, response=False, opcode=<OpCode.QUERY: 0>, authoritative_record=False, truncated=False, recursion_desired=True, recursion_available=False, reserved=2, rcode=<ResponseCode.NOERROR: 0>, num_questions=1, num_records=0, num_authorities=0, num_additionals=0), questions=[Question(name='google.co', qtype=<RecordType.NS: 2>, qclass=<RecordClass.IN: 1>)], records=[])
DEBUG:__main__:get header flags: 0000000100100000
DEBUG:__main__:raw query data: 2b 8c 01 20 00 01 00 00 00 00 00 00 06 67 6f 6f 67 6c 65 02 63 6f 00 00 02 00 01
DEBUG:__main__:set header flags: 1000000110000000
DEBUG:__main__:Packet(header=Header(id=11148, response=True, opcode=<OpCode.QUERY: 0>, authoritative_record=False, truncated=False, recursion_desired=True, recursion_available=True, reserved=0, rcode=<ResponseCode.NOERROR: 0>, num_questions=1, num_records=4, num_authorities=0, num_additionals=0), questions=[Question(name='google.co', qtype=<RecordType.NS: 2>, qclass=<RecordClass.IN: 1>)], records=[Record(name='google.co', qtype=<RecordType.NS: 2>, qclass=<RecordClass.IN: 1>, ttl=345600, value='ns1.google.com'), Record(name='google.co', qtype=<RecordType.NS: 2>, qclass=<RecordClass.IN: 1>, ttl=345600, value='ns2.google.com'), Record(name='google.co', qtype=<RecordType.NS: 2>, qclass=<RecordClass.IN: 1>, ttl=345600, value='ns4.google.com'), Record(name='google.co', qtype=<RecordType.NS: 2>, qclass=<RecordClass.IN: 1>, ttl=345600, value='ns3.google.com')])
DEBUG:__main__:get header flags: 1000000110000000
DEBUG:__main__:function query tooks 0.081s
ns1.google.com
ns2.google.com
ns4.google.com
ns3.google.com

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dns-client-0.1.1.tar.gz (10.5 kB view details)

Uploaded Source

Built Distribution

dns_client-0.1.1-py3-none-any.whl (10.5 kB view details)

Uploaded Python 3

File details

Details for the file dns-client-0.1.1.tar.gz.

File metadata

  • Download URL: dns-client-0.1.1.tar.gz
  • Upload date:
  • Size: 10.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.7

File hashes

Hashes for dns-client-0.1.1.tar.gz
Algorithm Hash digest
SHA256 98d3781c1d4c4167a1e68ba738d5916b342155c5f29e41122c2bb199dbb02fa3
MD5 a817220b8ef24d28b98aaccf20f9dfb6
BLAKE2b-256 5582e1d4c69a64222ff128b24afd2e1c7cf47d60219c5316856fb969751a10ba

See more details on using hashes here.

File details

Details for the file dns_client-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: dns_client-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 10.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.7

File hashes

Hashes for dns_client-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 55c7928c415a77d9dea0e78188e9d8bf6599742962dd2aadb25a39c136234601
MD5 65d6d8eaa1dacb1750e5c4555f75e15f
BLAKE2b-256 20a43103e53c0d759e05726edfddaaaabd2efefc4e5de2ac547097a38d350144

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page