2010-11-01 12 views
9

एक उपकरण के हिस्से के रूप में मैं लिख रहा हूं, मैं निदान करना चाहता हूं जो उपयोगकर्ता को बताएगा कि उन्होंने किसी विशेष सेवा के लिए अपने डोमेन के DNS को सही तरीके से कॉन्फ़िगर किया है या नहीं। मैं अपने डोमेन के लिए आधिकारिक DNS सर्वर से पूछना चाहता हूं ताकि मैं किसी भी कैश किए गए परिणामों को बाईपास कर सकूं।मैं dnspython का उपयोग कर डोमेन के लिए आधिकारिक DNS सर्वर कैसे ढूंढ सकता हूं?

उत्तर

14

यहां मेरा प्रयास है। यह शीर्ष-स्तरीय डोमेन के लिए रूट सर्वर को देखने के लिए सिस्टम के मानक DNS सर्वर का उपयोग करता है और श्रृंखला के साथ विभिन्न DNS सर्वरों के नामों को हल करने के लिए, जो मुझे लगता है कि उचित है क्योंकि उन नामों को संभवतः बहुत बार बदलना होगा।

import dns 
import dns.name 
import dns.query 
import dns.resolver 

def get_authoritative_nameserver(domain, log=lambda msg: None): 
    n = dns.name.from_text(domain) 

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

    last = False 
    while not last: 
     s = n.split(depth) 

     last = s[0].to_unicode() == u'@' 
     sub = s[1] 

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

     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)) 

     rrset = None 
     if len(response.authority) > 0: 
      rrset = response.authority[0] 
     else: 
      rrset = response.answer[0] 

     rr = rrset[0] 
     if rr.rdtype == dns.rdatatype.SOA: 
      log('Same server is authoritative for %s' % sub) 
     else: 
      authority = rr.target 
      log('%s is authoritative for %s' % (authority, sub)) 
      nameserver = default.query(authority).rrset[0].to_text() 

     depth += 1 

    return nameserver 


import sys 

def log(msg): 
    print msg 

print get_authoritative_nameserver(sys.argv[1], log) 

कुछ नमूने यहां उत्पादन है:

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 
5

मैं जॉन Colverson के जवाब में आए, और यह मेरे dnspython मॉड्यूल समझने में मदद की और कैसे परिणाम कार्रवाई करने के लिए (मुझे लगता है कि सभी DNS मॉड्यूल एक ही twisty है वर्ग संरचना की भूलभुलैया ...) मुझे टीटीएल और गोंद के रिकॉर्ड की आवश्यकता थी, इसलिए मैंने अपना खुद का अनुकूलन बनाया। यदि कोई इसे उपयोगी लगेगा तो मैं इसे यहां पोस्ट कर रहा हूं; मैं जॉन कोलवर्सन के उत्कृष्ट उत्तर के साथ प्रतिस्पर्धा करने का इरादा नहीं रखता हूं, बस कुछ अतिरिक्त रिक्त स्थान भरें। मूल सुधार उत्तर के अतिरिक्त खंड से नाम सर्वर जानकारी का उपयोग है, जहां उपलब्ध है। मुझे लगता है कि एक सर्वर अतिरिक्त खंड में गोंद रिकॉर्ड से कुछ और डाल सकता है, इसलिए शायद इसे उत्तर अनुभाग में जानकारी के साथ अतिरिक्त अनुभाग से जानकारी को सही ढंग से सहसंबंधित करने के लिए बढ़ाया जाना चाहिए। मैं सभी नाम सर्वर भी लाता हूं और मुद्रित करता हूं, न केवल पहले।

#!/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) 
2

अन्य उदाहरण ठीक हैं लेकिन अत्यधिक जटिल हैं यदि आपको केवल नेमसर्वर की आवश्यकता है। http://c0deman.wordpress.com/2014/06/17/find-nameservers-of-domain-name-python/ से उदाहरण:

import dns.resolver 

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

मैं सोच है कि कैश की गई परिणाम वापस हो सकता है, हालांकि सही नहीं होगा सकता है? मेरे मामले में मैं विशेष रूप से मौजूदा सर्वर को किसी भी कैशिंग से परहेज करना चाहता था, लेकिन ऐसा करने के तरीके से ऐसा करने का एक आसान तरीका हो सकता है। :) –

+2

यह आपको केवल शीर्ष-स्तरीय डोमेन (या उप-डोमेन के लिए नेमसर्वर देगा यदि उनके पास एनएस रिकॉर्ड हैं)। यह आपको नहीं बताएगा कि आधिकारिक DNS सर्वर 'www.example.org' के लिए क्या है और' dns.resolver.NoAnswer' अपवाद उठाएगा। – pwaring

0

इम यकीन है कि यह यह करना होगा।

import dns.resolver 

domain = 'co.uk' 

response = dns.resolver.query(domain, 'SOA') 
if response.rrset is not None: 
    print response.rrset 

आप निश्चित सफाई की प्रतिक्रिया

import dns.resolver 
import re 

domain = 'co.uk' 

response = dns.resolver.query(domain, 'SOA') 

if response.rrset is not None: 
    pattern= r'(%s)\.\s(\d{1,})\s(\w+)\sSOA\s(.*?)\.\s(.*?)\.\s(\d{1,})\s(\d{1,})\s(\d{1,})\s(\d{1,})\s(\d{1,})' % domain 
    match = re.match(pattern, str(response.rrset)) 
    m_name, ttl, class_, ns, email, serial, refresh, retry, expiry, minim = match.groups() 

output =''' 
Main Name In Zone: {a}, 
Cache TTL: {b}, 
Class: {c}, 
Authoritive NS: {d}, 
Email Address: {e}, 
Last Change: {f}, 
Retry In Secs: {g}, 
Expiry: {h}, 
Slave Cache In Sec: {i} 
'''.format(a = m_name, b = ttl, c = class_, d = ns, e = str(email).replace('\\', ''), f = serial, g = retry, h = expiry, i = minim) 

print output 

यह पैदा करता है

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

अगर मैं गलत हूं तो मुझे सही करें, लेकिन मेरा मानना ​​है कि उन एसओए परिणामों को अभी भी रिज़ॉल्वर पर कैश किया जा सकता है, हालांकि? यह कैशिंग को छोड़ रहा था जिसने चीजों को और अधिक विस्तृत बनाया। –

संबंधित मुद्दे

 संबंधित मुद्दे