Dnspython is a DNS toolkit for Python.

Overview

dnspython

Build Status Documentation Status PyPI version License: ISC

INTRODUCTION

dnspython is a DNS toolkit for Python. It supports almost all record types. It can be used for queries, zone transfers, and dynamic updates. It supports TSIG authenticated messages and EDNS0.

dnspython provides both high and low level access to DNS. The high level classes perform queries for data of a given name, type, and class, and return an answer set. The low level classes allow direct manipulation of DNS zones, messages, names, and records.

To see a few of the ways dnspython can be used, look in the examples/ directory.

dnspython is a utility to work with DNS, /etc/hosts is thus not used. For simple forward DNS lookups, it's better to use socket.getaddrinfo() or socket.gethostbyname().

dnspython originated at Nominum where it was developed to facilitate the testing of DNS software.

ABOUT THIS RELEASE

This is the development version of dnspython 2.2.0. Please read What's New for information about the changes in this release.

INSTALLATION

  • Many distributions have dnspython packaged for you, so you should check there first.
  • If you have pip installed, you can do pip install dnspython
  • If not just download the source file and unzip it, then run sudo python setup.py install
  • To install the latest from the master branch, run pip install git+https://github.com/rthalley/dnspython.git

If you want to use DNS-over-HTTPS, you must run pip install dnspython[doh].

If you want to use DNSSEC functionality, you must run pip install dnspython[dnssec].

If you want to use internationalized domain names (IDNA) functionality, you must run pip install dnspython[idna]

If you want to use the Trio asynchronous I/O package, you must run pip install dnspython[trio].

If you want to use the Curio asynchronous I/O package, you must run pip install dnspython[curio].

Note that you can install any combination of the above, e.g.: pip install dnspython[doh,dnssec,idna]

Notices

Python 2.x support ended with the release of 1.16.0. dnspython 2.0.0 and later only support Python 3.6 and later.

Documentation has moved to dnspython.readthedocs.io.

The ChangeLog has been discontinued. Please see the git history for detailed change information.

Comments
  • Add support for gss-tsig and TKEY records to support GSSAPI authentication

    Add support for gss-tsig and TKEY records to support GSSAPI authentication

    Following earlier feedback on https://github.com/rthalley/dnspython/pull/524, I've tried an alternative option for adding support for gss-tsig.

    Although it's a smaller and less structural change, I can't help but think it's making the code slightly less clear/tidy, and that at least a small class representing the HMAC style TSIGs would avoid a few of the 'if digestmod == gss_tsig' stanzas.

    I'll note that @bwelling's earlier comment about making gss-tsig look like a digest isn't quite possible as verifying a gss-tsig isn't the same as an hmac style TSIG - you can't just re-do the signature operation and compare the result - you have to call a verification method on the GSSAPI context, and pass in the expected value and the data that produced it. There are other (cryptographic) aspects to the signature that can't be reproduced in this way. This has led to a small chance in the way verification works (by passing an expected value into the signature operation). I'd previously proposed an alternative option which might be cleaner, by factoring out the bits of code that collect up the TSIG values required for the signature into a method on a TSIG (which could then be reused in the sign/verify operations separately).

    I'll also draw your attention to the minor metaclass related change for TKEY records; these can have a class of ANY, so the metaclass check on queries needs to be slightly relaxed.

    opened by nrhall 94
  • Cannot import package

    Cannot import package

    I'm trying to use the package, but without success, I tried installing using all commands below: pip install dnspython pip install git+https://github.com/rthalley/dnspython pacman -S python-dnspython pip install dnspython==1.15.0

    Second and third commands were recommended as solution here; fourth was recommended here.

    OS: ArchLinux
    Python: 3.6.0
    pip: 9.0.1
    dnspython: 1.16.0
    setuptools: 28.8.0
    
    Python 3.6.0 (default, Jan 16 2017, 09:27:59) 
    [GCC 6.3.1 20170109] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import dns.resolver
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ModuleNotFoundError: No module named 'dns.resolver'; 'dns' is not a package
    

    Am I missing something? I tried to find people with similar issues, but the all suggested solutions yielded the same result (as above).

    Thanks in advance!

    opened by flavioheleno 24
  • Add support for DNS over HTTPS

    Add support for DNS over HTTPS

    This adds support for DNS over HTTPS. It adds additional dns.query.doh() method which uses urllib to get DNS response from DoH resolver. It is used in dns.resolver.Resolver when a DNS nameserver starts with https:// (so it is DoH resolver).

    @rthalley Can you check this? Also, when do you plan to release stable 2.0?

    opened by filips123 22
  • Export results to JSON

    Export results to JSON

    Hi,

    I'd like to be able to export the results of a Message to JSON format, for integration with other tools, such as client-side Ajax requests for DNS lookups, etc.

    I wrote some code that does this, but I think a native solution as part of the framework would be ideal, by adding to_json() methods in rdata types, etc. Has anyone considered working on this?

    Enhancement Request Needs Author 
    opened by rgluga 22
  • pytest failures under systemd-resolved, in Fedora 33

    pytest failures under systemd-resolved, in Fedora 33

    In a fresh install of Fedora 33 with systemd-resolved enabled, I'm seeing the following pytest failures:

    ============================================ FAILURES ============================================
    ______________________________ AsyncTests.testCanonicalNameDangling ______________________________
    
    self = <tests.test_async.AsyncTests testMethod=testCanonicalNameDangling>
    
        def testCanonicalNameDangling(self):
            name = dns.name.from_text('dangling-cname.dnspython.org')
            cname = dns.name.from_text('dangling-target.dnspython.org')
            async def run():
                return await dns.asyncresolver.canonical_name(name)
    >       self.assertEqual(self.async_run(run), cname)
    E       AssertionError: <DNS name dangling-cname.dnspython.org.> != <DNS name dangling-target.dnspython.org.>
    
    tests/test_async.py:214: AssertionError
    __________________________ LiveResolverTests.testCanonicalNameDangling ___________________________
    
    self = <tests.test_resolver.LiveResolverTests testMethod=testCanonicalNameDangling>
    
        def testCanonicalNameDangling(self):
            name = dns.name.from_text('dangling-cname.dnspython.org')
            cname = dns.name.from_text('dangling-target.dnspython.org')
    >       self.assertEqual(dns.resolver.canonical_name(name), cname)
    E       AssertionError: <DNS name dangling-cname.dnspython.org.> != <DNS name dangling-target.dnspython.org.>
    
    tests/test_resolver.py:686: AssertionError
    ________________________ SelectResolverTestCase.testCanonicalNameDangling ________________________
    
    self = <tests.test_resolver.SelectResolverTestCase testMethod=testCanonicalNameDangling>
    
        def testCanonicalNameDangling(self):
            name = dns.name.from_text('dangling-cname.dnspython.org')
            cname = dns.name.from_text('dangling-target.dnspython.org')
    >       self.assertEqual(dns.resolver.canonical_name(name), cname)
    E       AssertionError: <DNS name dangling-cname.dnspython.org.> != <DNS name dangling-target.dnspython.org.>
    
    tests/test_resolver.py:686: AssertionError
    _________________________ PollResolverTestCase.testCanonicalNameDangling _________________________
    
    self = <tests.test_resolver.PollResolverTestCase testMethod=testCanonicalNameDangling>
    
        def testCanonicalNameDangling(self):
            name = dns.name.from_text('dangling-cname.dnspython.org')
            cname = dns.name.from_text('dangling-target.dnspython.org')
    >       self.assertEqual(dns.resolver.canonical_name(name), cname)
    E       AssertionError: <DNS name dangling-cname.dnspython.org.> != <DNS name dangling-target.dnspython.org.>
    
    tests/test_resolver.py:686: AssertionError
    _____________________ OverrideSystemResolverTestCase.test_basic_getaddrinfo ______________________
    
    self = <tests.test_resolver_override.OverrideSystemResolverTestCase testMethod=test_basic_getaddrinfo>
    
        @unittest.skipIf(sys.platform == 'win32',
                         'avoid windows original getaddrinfo issues')
        def test_basic_getaddrinfo(self):
            self.assertTrue(self.equivalent('dns.google', 53, socket.AF_INET,
                                            socket.SOCK_DGRAM))
    >       self.assertTrue(self.equivalent('dns.google', 53, socket.AF_INET6,
                                            socket.SOCK_DGRAM))
    E       AssertionError: False is not true
    
    tests/test_resolver_override.py:98: AssertionError
    ==================================== short test summary info =====================================
    FAILED tests/test_async.py::AsyncTests::testCanonicalNameDangling - AssertionError: <DNS name d...
    FAILED tests/test_resolver.py::LiveResolverTests::testCanonicalNameDangling - AssertionError: <...
    FAILED tests/test_resolver.py::SelectResolverTestCase::testCanonicalNameDangling - AssertionErr...
    FAILED tests/test_resolver.py::PollResolverTestCase::testCanonicalNameDangling - AssertionError...
    FAILED tests/test_resolver_override.py::OverrideSystemResolverTestCase::test_basic_getaddrinfo
    =========================== 5 failed, 1115 passed, 18 skipped in 9.11s ===========================
    

    /etc/resolv.conf has the folowing configuration:

    # This file is managed by man:systemd-resolved(8). Do not edit.
    #
    # This is a dynamic resolv.conf file for connecting local clients to the
    # internal DNS stub resolver of systemd-resolved. This file lists all
    # configured search domains.
    #
    # Run "resolvectl status" to see details about the uplink DNS servers
    # currently in use.
    #
    # Third party programs should typically not access this file directly, but only
    # through the symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a
    # different way, replace this symlink by a static file or a different symlink.
    #
    # See man:systemd-resolved.service(8) for details about the supported modes of
    # operation for /etc/resolv.conf.
    
    nameserver 127.0.0.53
    options edns0 trust-ad
    

    I haven´t changed systemd-resolved configuration.

    Any help on how to debug this issues, is welcome.

    opened by rjeffman 19
  • 2.0.0 Release Planning

    2.0.0 Release Planning

    As may be apparent from the burst of work recently, I'm trying to get 2.0.0 ready for release. This issue will be for discussing the process. I'm thinking "by the end of June" as a target release time, but am very open to suggestions. My thinking is "pretty soon, but not so soon I can't make progress on the documentation".

    We're in pretty good shape code-wise. There are no release-blocking bugs at this time. We need to resolve some of the remaining "should we make an API-breaking change?" issues, e.g. with resolver search functionality. I tagged some things as "Post 2.0.0" as I think that they don't require API-breaking changes and are too big to do in the amount of time that remains.

    I'm going to try to work on documentation the next few weekends, as it would be nice to get the work I started long ago done, and replace the documentation currently on the website.

    opened by rthalley 19
  • Parse additional options from resolv.conf

    Parse additional options from resolv.conf

    read_resolv_conf only understands the rotate option. /etc/resolv.conf has more options like timeout.

    https://github.com/rthalley/dnspython/blob/aab95c61d554dcf8bc2cf991811165a320991b8c/dns/resolver.py#L586-L604

    Please consider to support additional options like global timeout, https://linux.die.net/man/5/resolv.conf

    Enhancement Request 
    opened by tiran 19
  • IDNA2008 implementation breaks backward compatibility

    IDNA2008 implementation breaks backward compatibility

    Sorry I didn't noticed earlier, but in case that idna 2008 module is installed on system, idna2008 is used by default. Because idna 2008 and 2003 are incompatible, this may cause issues for current implementations using python-dns that relays on idna 2003. Even that idna 2003 is deprecated, this standard is still widely used in SW or registrars. This cause issues mainly in german speaking countries where handling of sharp S (ß) is different.

    IMO idna 2003 should stay default and from_unicode methods shold have kwarg to chose idna2003 or idna2008 or any of transitional mechanism

    Bug Fixed 
    opened by ghost 19
  • Windows-specific read_registry / _win32_is_nic_enabled error on AWS EC2

    Windows-specific read_registry / _win32_is_nic_enabled error on AWS EC2

    Specifically, the experimentally derived test for a 1 on internal Registry value ConfigFlags doesn't work. The code erroneously thinks that a disabled network adapter is enabled. Based on this error, it uses the wrong DNS server address.

    https://github.com/rthalley/dnspython/blob/585add9d96ed981ab6a23b373a9166d8986620ab/dns/resolver.py#L938

    Microsoft documents that ConfigFlags is for internal use only.

    Additionally, Microsoft has a supported API GetNetworkParams, that has been available since Windows 2000, to get the DNS nameservers.

    I'd like to suggest that we consider using GetNetworkParams instead of the Windows Registry code to produce the list of nameservers.

    I've attached a zipped standalone Python script that uses GetNetworkParams to produce the list of DNS nameservers on a Windows machine. I've tested it on a Windows 10 desktop and an AWS EC2 running Windows Server 2019 Datacenter Version 1809. It relies on the built-in ctypes package to access GetNetworkParams. The attached code isn't a pull request, as I wanted to gauge the project's level of interest in fixing this bug first.

    win_dns_nameservers.zip

    Bug Fixed 
    opened by Jeff17Robbins 18
  • What is the equivalent of this code in dnspython?

    What is the equivalent of this code in dnspython?

    NO MORE HELP WANTED

    My OS is Windows 10, Python: 3.7.4 64 Bit

    Now: I want to change MY current DNS Server address. I know two ways to do so.

    With os:

    os.system('netsh interface ip set dns "Wi-Fi" static 192.168.0.1')
    

    With wmi it works with this piece of code:

    nic_configs = wmi.WMI().Win32_NetworkAdapterConfiguration(IPEnabled=True);
    nic = nic_configs[0];
    setNewDns = nic.SetDNSServerSearchOrder(['192.168.0.1']);
    

    How do I change it with dnspython.

    I know how to read the current dns using dnspython:

    import dns
    import dns.resolver
    
    default = dns.resolver.get_default_resolver()
    nameserver = default.nameservers[0]
    

    But I haven't figured out what method I need to use in order to CHANGE the address of MY DNS server.

    For example: Change it from "192.168.0.1" to "192.168.0.2"

    I looked through the documentation at dnspython.org but I had no luck.

    Thanks a lot for any help!

    NO MORE HELP WANTED

    opened by Enigma3000 17
  • Python minimum version 3.7?

    Python minimum version 3.7?

    We keep running into situations where if we knew we had at least python 3.7, things could be cleaner. I propose we consider making 3.7 the minimum python version for dnspython 2.0.

    opened by rthalley 16
  • dns.query.https bootstrap_address should override DNS lookup but not replace hostname in url

    dns.query.https bootstrap_address should override DNS lookup but not replace hostname in url

    Hello,

    First of all thank you for this fantastic library. It seems to be very high quality, it is appreciated.

    The implementation of bootstrap_address in dns.query.https seems weird. It replaces the hostname in the URL with the IP, which will not work for a lot of servers (only Google and CF have their IPs in SAN).

    I think? bootstrap_address was intended to override the DNS lookup, but when doing that we should keep the DoH url hostname unchanged. If implemented right bootstrap_address would be a very useful tool to monitor DNS servers with hostnames with multiple IP addresses. Like if I wanted to monitor the servers at dns.google (which currently resolves to 4 IPs) I could use bootstrap_address to specify which one to use. That doesn't mean the IP should go in the URL though :)

    On a related note dns.query.tls could use the same bootstrap_address functionality, for the same reasons.

    Thoughts? Thanks! :)

    opened by tykling 3
  • Query nameservers using their FQDN

    Query nameservers using their FQDN

    Motivation Nowadays dns.resolver.Resolver().nameservers supports IPs and valid HTTPS addresses. If we override the DNS servers to use ns2.google.com we'll get the following message:

    ValueError: nameserver ns2.google.com is not an IP address or valid HTTPS URL

    The motivation is to query nameservers for a specific domain using fully qualified domain names, so we can achieve the same behavior as dig @ns2.google.com

    Describe the solution you'd like. dns.resolver.Resolver.nameservers accept fully qualified domain names:

    Example of valid code:

    import dns.resolver
    
    my_resolver = dns.resolver.Resolver()
    
    my_resolver.nameservers = ['ns2.google.com']
    
    my_resolver.resolve('google.com', "A")
    

    Thank you.

    Enhancement Request 
    opened by nunodio 6
  • Compact DNSSEC Denial of Existence support

    Compact DNSSEC Denial of Existence support

    Would you mind implementing NXDOMAIN synthesis in case of "Black Lies" presence ?

    Motivation Compact DNSSEC Denial of Existence or "Black Lies" is a Cloudflare proprietary DNSSEC protocol modification unilaterally deployed in their infrastructures and later adopted by other big actors ( Route53, NS1).

    Black Lies are "mostly" compatible with DNSSEC. They don't break validation but have two impacts:

    • Non existent entry no longer generate NXDOMAIN status code.
    • ENT (Empty Non Terminal) entry are no longer distinguishable from NXDOMAIN (Route53), difficult to identify reliably (Cloudflare) or need additional support to be identified (NS1)

    As we don't control how the resolver used will do iterative query for specific destinations (Cloudflare correctly generate NXDOMAIN for queries without EDNS or DO bit), and because good resolvers do requests with EDNS and DO bit (and do validation), we should implement black lies decoding to properly return NXDOMAIN to applications witch rely on this status code. Applications relying on ENT identification are rare and distinguish-ability between NXDOMAIN and real NODATA is the same (Cloudflare, NS1): NSEC bitmap exactly covering "RRSIG NSEC" types.

    The "Black Lies" hack could not be properly fixed/addressed on the resolvers(servers) side, but is a reality with which we should live until the implementers change their mind or is superseded by a new better standardized mechanism. Client code that rely on obtaining correct DNS response codes needs a reliable way of inferring the real response status in spite of these hacks. Having this possibility on the client side, on the stub resolver is sadly the only viable option today.

    Describe the solution you'd like. Having an option on the stub resolver (like "raise_on_blacklies") which when true:

    • imply EDNS0 and DO on the resolver configuration or error out.
    • blacklies detection/decoding on NODATA condition is performed and NXDOMAIN is raised in case of successful decoding.

    Reference: https://github.com/shuque/blrcode https://datatracker.ietf.org/doc/html/draft-valsorda-dnsop-black-lies-00 https://datatracker.ietf.org/doc/html/draft-huque-dnsop-blacklies-ent-01

    Enhancement Request 
    opened by Tazmaniac 1
  • Improve support for DNS-over-TLS

    Improve support for DNS-over-TLS

    At present, DNS-over-TLS is more inconvenient to use than DNS-over-HTTPS, although their treatment should be similar.

    • dns.query.https can use https://host:port/path but dns.query.tls cannot
    • dns.resolver.Resolver do not support DNS-over-TLS

    I think we can use something like tls://host_or_IP:port as the where parameter for dns.query.tls and use the host given here as server_hostname if server_hostname==None. Maybe we can add a bootstrap_address like dns.query.https.

    As for dns.resolver.Resolver, we can treat DNS-over-TLS like DNS-over-HTTPS, i.e. accept tls://host:port in the nameservers.

    Things as similar for DNS-over-QUIC, we can use quic://host_or_IP:port

    Enhancement Request 
    opened by URenko 2
  • New release?

    New release?

    Hello.

    Do you plan to release a new version? There is quite a lot of commits in the master branch since March and a lot of changes in compatible versions of dependencies.

    Have a nice day.

    Enhancement Request 
    opened by frenzymadness 6
🥑 A Python ARP and DNS Spoofer CLI and INTERFACE 🥓

NEXTGEN SPOOFER ?? A Python ARP and DNS Spoofer CLI and INTERFACE ?? CLI -> advanced pentesters INTERFACE -> beginners SetUp Make sure you installed P

null 9 Dec 25, 2022
Build custom OSINT tools and APIs (Ping, Traceroute, Scans, Archives, DNS, Scrape, Whois, Metadata & built-in database for more info) with this python package

Build custom OSINT tools and APIs with this python package - It includes different OSINT modules (Ping, Traceroute, Scans, Archives, DNS, Scrape, Whoi

QeeqBox 52 Jan 6, 2023
A pure python implementation of multicast DNS service discovery

python-zeroconf Documentation. This is fork of pyzeroconf, Multicast DNS Service Discovery for Python, originally by Paul Scott-Murphy (https://github

Jakub Stasiak 483 Dec 29, 2022
A great python/java dynamic DNS service for NameSilo, with log, email reminder...

English NameSilo DDNS is a DDNS service for NameSilo domain names for home broadband , it can automatically detect IP changes in home broadband

云牧青 77 Dec 28, 2022
Way find out if DNS is down or your instance

DNS-PING Way to find out if DNS is down or your instance Problem: At times it happens that DNS provider services of a website URL is down and so to re

Giten Mitra 4 Nov 18, 2022
ExtDNS synchronizes labeled records in docker-compose with DNS providers.

ExtDNS for docker-compose ExtDNS synchronizes labeled records in docker-compose with DNS providers. Inspired by External DNS, ExtDNS makes resources d

DNTSK 6 Dec 24, 2022
mitm6 is a pentesting tool that exploits the default configuration of Windows to take over the default DNS server.

mitm6 is a pentesting tool that exploits the default configuration of Windows to take over the default DNS server.

Fox-IT 1.3k Jan 5, 2023
Script and library to wait for a DNS authority server to get its configuration.

DNSWait dnswait is a small script to wait for the "propagation" of a namserver configuration. Installing It's as easy as: python -m pip install dnswai

Julien Palard 14 Jan 17, 2022
Makes dynamically updating your Cloudflare DNS records a bit easier ⏩👍😎

Easy Dynamic Cloudflare DNS Updater Makes dynamically updating your Cloudflare DNS records a bit easier ⏩ ?? ?? If using it as a 'Dynamic DNS' client,

Zac Koch 3 Dec 19, 2021
Octodns-cloudflare - Cloudflare DNS provider for octoDNS

CloudflareProvider provider for octoDNS An octoDNS provider that targets Cloudfl

octoDNS 6 May 28, 2022
Bark Toolkit is a toolkit wich provides Denial-of-service attacks, SMS attacks and more.

Bark Toolkit About Bark Toolkit Bark Toolkit is a set of tools that provides denial of service attacks. Bark Toolkit includes SMS attack tool, HTTP

null 13 Jan 4, 2023
Modern Denial-of-service ToolKit for python

?? Impulse Modern Denial-of-service ToolKit ?? Main window ?? Methods: Method Target Description SMS PHONE Sends a massive amount of SMS messages and

null 1 Nov 29, 2021
A Scapy implementation of SMS-SUBMIT and (U)SIM Application Toolkit command packets.

A Scapy implementation of SMS-SUBMIT and (U)SIM Application Toolkit command packets.

mnemonic 83 Dec 11, 2022
A simple implementation of an RPC toolkit

Simple RPC With Raw Sockets Repository for the Data network course project: Introduction In this project, you will attempt to code a simple implementa

Milad Samimifar 1 Mar 25, 2022
Medusa is a cross-platform agent compatible with both Python 3.8 and Python 2.7.

Medusa Medusa is a cross-platform agent compatible with both Python 3.8 and Python 2.7. Installation To install Medusa, you'll need Mythic installed o

Mythic Agents 123 Nov 9, 2022
ProtOSINT is a Python script that helps you investigate Protonmail accounts and ProtonVPN IP addresses

ProtOSINT ProtOSINT is a Python script that helps you investigate ProtonMail accounts and ProtonVPN IP addresses. Description This tool can help you i

pixelbubble 249 Dec 23, 2022
A Python tool used to automate the execution of the following tools : Nmap , Nikto and Dirsearch but also to automate the report generation during a Web Penetration Testing

?? WebMap A Python tool used to automate the execution of the following tools : Nmap , Nikto and Dirsearch but also to automate the report generation

Iliass Alami Qammouri 274 Jan 1, 2023
msgspec is a fast and friendly implementation of the MessagePack protocol for Python 3.8+

msgspec msgspec is a fast and friendly implementation of the MessagePack protocol for Python 3.8+. In addition to serialization/deserializat

Jim Crist-Harif 414 Jan 6, 2023
Light, simple RPC framework for Python

Agileutil是一个Python3 RPC框架。基于微服务架构,封装了rpc/http/orm/log等常用组件,提供了简洁的API,开发者可以很快上手,快速进行业务开发。

null 16 Nov 22, 2022