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.2.tar.gz (10.5 kB view details)

Uploaded Source

Built Distribution

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

Uploaded Python 3

File details

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

File metadata

  • Download URL: dns-client-0.1.2.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.2.tar.gz
Algorithm Hash digest
SHA256 62b3a9a733df41017f91c0827a4bdeab3095aa7b3d65a6a4fa6b32a9c02fd55c
MD5 3f7b2eee24b70c96693d197dcccb1511
BLAKE2b-256 143c8158038b1b5447290b86457685d3de02a30d7254ac9189e4ee2a26949921

See more details on using hashes here.

File details

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

File metadata

  • Download URL: dns_client-0.1.2-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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 a91a75ec57c69686034f5c7c83f206e9a2a61e07e8ff2f3f39f002e2b8725d4c
MD5 a15282e6cb9f1b952b5ad99c8145e5f8
BLAKE2b-256 6adad747aa2493185c1dc98b63d519d38624761087e004c57677320cb53bba08

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