12
votes

Comment puis-je trouver le serveur DNS faisant autorité pour un domaine utilisant DnSpython?

Dans le cadre d'un outil que j'écris, je veux avoir un diagnostic qui indiquera à l'utilisateur s'ils ont configuré correctement le DNS de leur domaine pour un service particulier. Je veux interroger le serveur DNS faisant autorité pour leur domaine afin que je puisse contourner les résultats mis en cache.


0 commentaires

4 Réponses :


18
votes

Voici ma tentative de cette tentative. Il utilise le serveur DNS standard du système pour rechercher le serveur racine pour le domaine de niveau supérieur et pour résoudre les noms des différents serveurs DNS le long de la chaîne, que je pense appropriée car ces noms changent probablement très rarement.

Looking up com. on 192.168.255.10
l.gtld-servers.net. is authoritative for com.
Looking up stackoverflow.com. on 192.41.162.30
ns1.p19.dynect.net. is authoritative for stackoverflow.com.
Looking up meta.stackoverflow.com. on 208.78.70.19
Same server is authoritative for meta.stackoverflow.com.
208.78.70.19


0 commentaires

8
votes

J'ai rencontré la réponse de Jon Colverson, et cela m'a aidé à comprendre le module Dnspython et à traiter les résultats (je suppose que tous les modules DNS ont le même labyrinthe twisty de la structure de classe ...) J'avais besoin de la TTL et des enregistrements de colle , alors j'ai créé ma propre adaptation. Je le pose ici au cas où quelqu'un le trouverait utile; Je n'ai pas l'intention de rivaliser avec l'excellente réponse de Jon Colverson, il suffit de remplir des blancs supplémentaires. L'amélioration de base est l'utilisation des informations de noms de noms de la section supplémentaire de la réponse, le cas échéant. Je suppose qu'un serveur puisse mettre autre chose que des enregistrements de colle dans la section supplémentaire, il faut peut-être encore être amélioré pour corréler correctement les informations de la section supplémentaire avec les informations de la section de réponse. Je récupère et imprimez tous les serveurs de noms, pas seulement le premier.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import dns.query
import dns.resolver
from dns.exception import DNSException

def query_authoritative_ns (domain, log=lambda msg: None):

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

    n = domain.split('.')

    for i in xrange(len(n), 0, -1):
        sub = '.'.join(n[i-1:])

        log('Looking up %s on %s' % (sub, ns))
        query = dns.message.make_query(sub, dns.rdatatype.NS)
        response = dns.query.udp(query, ns)

        rcode = response.rcode()
        if rcode != dns.rcode.NOERROR:
            if rcode == dns.rcode.NXDOMAIN:
                raise Exception('%s does not exist.' % (sub))
            else:
                raise Exception('Error %s' % (dns.rcode.to_text(rcode)))

        if len(response.authority) > 0:
            rrsets = response.authority
        elif len(response.additional) > 0:
            rrsets = [response.additional]
        else:
            rrsets = response.answer

        # Handle all RRsets, not just the first one
        for rrset in rrsets:
            for rr in rrset:
                if rr.rdtype == dns.rdatatype.SOA:
                    log('Same server is authoritative for %s' % (sub))
                elif rr.rdtype == dns.rdatatype.A:
                    ns = rr.items[0].address
                    log('Glue record for %s: %s' % (rr.name, ns))
                elif rr.rdtype == dns.rdatatype.NS:
                    authority = rr.target
                    ns = default.query(authority).rrset[0].to_text()
                    log('%s [%s] is authoritative for %s; ttl %i' % 
                        (authority, ns, sub, rrset.ttl))
                    result = rrset
                else:
                    # IPv6 glue records etc
                    #log('Ignoring %s' % (rr))
                    pass

    return result

import sys

def log (msg):
    sys.stderr.write(msg + u'\n')

for s in sys.argv[1:]:
    print query_authoritative_ns (s, log)


0 commentaires

2
votes

Les autres exemples sont corrects mais trop complexes si vous avez besoin juste des serveurs de noms. Exemples de http://c0deman.wordpress.com/ 2014/06/17 / Trouver-noms-noms-de-domaine-nom-python / :

import dns.resolver

domain = 'google.com'
answers = dns.resolver.query(domain,'NS')
for server in answers:
    print server


2 commentaires

Aurais-je raison de penser que cela pourrait renvoyer des résultats en cache, cependant? Dans mon cas, je voulais spécifiquement trouver le serveur actuel en évitant toute mise en cache, mais il pourrait y avoir une façon de faire de manière significative que la façon dont je l'ai fait. :)


Cela ne vous donnera que le serveur de noms pour le domaine de niveau supérieur (ou sous-domaines s'ils ont des enregistrements NS). Il ne vous dira pas ce que le serveur DNS autorité est pour www.example.org et augmentera un dns.resolver.noanswer exception.



1
votes

Je suis sûr que cela le ferait.

Main Name In Zone: co.uk,
Cache TTL: 600,
Class: IN,
Authoritive NS: dns1.nic.uk,
Email Address: hostmaster.nominet.org.uk,
Last Change: 1305857394,
Retry In Secs: 300,
Expiry: 2419200,
Slave Cache In Sec: 10800


1 commentaires

Corrigez-moi si je me trompe, mais je crois que ces résultats de SOA pourraient toujours être mis en cache sur le résolveur, cependant? Il faisait contourner la mise en cache qui rendait les choses plus élaborées.