Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么DNSPython区域转移偶尔会失败_Python_Python 3.x_Dns_Dnspython - Fatal编程技术网

为什么DNSPython区域转移偶尔会失败

为什么DNSPython区域转移偶尔会失败,python,python-3.x,dns,dnspython,Python,Python 3.x,Dns,Dnspython,因此,在python方面,我仍然处于noob级别。我知道。。。我知道。。。也许有一种更有效的方法来做我正在尝试但仍在学习的事情,希望通过练习我会变得更好 对于一个培训项目,我正在编写一个脚本来对域执行各种DNS操作。我找到了DNSPython,它似乎正是我需要使用的,我认为我已经使用它了,但当我在另一个域上尝试它时,它在区域转移时总是失败 我现在有两个硬编码的域用于测试。megacorpone域iw按照我的预期工作,但是,现在它失败了(没有代码更改),为了让它工作,我必须过滤返回的第一条记录“@

因此,在python方面,我仍然处于noob级别。我知道。。。我知道。。。也许有一种更有效的方法来做我正在尝试但仍在学习的事情,希望通过练习我会变得更好

对于一个培训项目,我正在编写一个脚本来对域执行各种DNS操作。我找到了DNSPython,它似乎正是我需要使用的,我认为我已经使用它了,但当我在另一个域上尝试它时,它在区域转移时总是失败

我现在有两个硬编码的域用于测试。megacorpone域iw按照我的预期工作,但是,现在它失败了(没有代码更改),为了让它工作,我必须过滤返回的第一条记录“@”,否则它也失败了

然而,zonetransfer.me域有时完成脚本时会出错,但偶尔也会出错,但由于某种原因,它从不显示主机记录,而且我还不知道如何修复它,为此我绞尽脑汁已有一段时间了

megacoprone的运行在以前每次都是有效的,现在根本不起作用了。到目前为止,我唯一能想到的是,这可能是一个时机问题

与MegaCoprOne一起运行

Attempting zone transfers for megacorpone.com
Traceback (most recent call last):
  File "/home/kali/Exercises/Module_7/dns-axfer.py", line 56, in zoneXFR
    zone = dns.zone.from_xfr(dns.query.xfr(str(server).rstrip('.'), domain))
  File "/usr/lib/python3/dist-packages/dns/zone.py", line 1106, in from_xfr
    for r in xfr:
  File "/usr/lib/python3/dist-packages/dns/query.py", line 627, in xfr
    raise TransferError(rcode)
dns.query.TransferError: Zone transfer error: REFUSED

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/kali/Exercises/Module_7/dns-axfer.py", line 73, in <module>
    zoneXFR()
  File "/home/kali/Exercises/Module_7/dns-axfer.py", line 66, in zoneXFR
    print ("\nResults for",server, "\nZone origin:", str(zone.origin).rstrip('.'))
UnboundLocalError: local variable 'zone' referenced before assignment

我看到您正在尝试专门为测试而设置的知名服务器。然而,为了其他读者的利益,我将添加一些解释

您可能知道,现在大多数名称服务器都不允许区域传输。这就是说,一个给定域名的每个名称服务器可能会有不同的行为(它们可能有不同的配置,甚至运行不同的软件)

对于megacorpone.com,列出了3个名称服务器:

  • ns2.megacorpone.com
  • ns3.megacorpone.com
  • ns1.megacorpone.com
ns2.megacorpone.com是唯一允许区域传输的

此消息

dns.query.TransferError: Zone transfer error: REFUSED
意思是:您的查询被拒绝。可能你和服务器的名字说错了

然后出现另一个错误,表明存在变量范围问题:

UnboundLocalError: local variable 'zone' referenced before assignment
您正在按以下顺序调用函数:

name_servers = getNS()
getMX()
zoneXFR()
如果
name\u服务器
失败,那么对
zoneXFR
的后续调用也将失败。因为这个代码:

for server in name_servers:
将尝试遍历空列表

间歇性DNS解析故障很常见,因此此处需要进行一些检查。至少要确保NS列表不是空的

另一个问题:在
try
块外启动
for
循环,这样控制结构就在中间被破坏了:

for server in name_servers:
    try:
        zone = dns.zone.from_xfr(dns.query.xfr(str(server).rstrip('.'), domain))
        print ("\nResults for",server, "\nZone origin:", str(zone.origin).rstrip('.'))
        line()
改为这样做:

try:
    for server in name_servers:
        zone = dns.zone.from_xfr(dns.query.xfr(str(server).rstrip('.'), domain))
        print ("\nResults for",server, "\nZone origin:", str(zone.origin).rstrip('.'))
        ...

我怀疑您的脚本间歇性失败,因为名称服务器列表并非总是以相同的顺序返回。如果返回的第一个NS是ns1.megacorpone.com。或ns3.megacorpone.com。然后代码崩溃了。如果脚本以ns2.megacorpone.com(唯一允许区域传输的NS)开始,那么它似乎工作正常

此代码失败时(AXFR被拒绝):

然后,
区域
没有定义,这就是为什么不能在异常块中打印它。相反,显示域名或您知道已定义且有效的其他变量

因此,如果AXFR被拒绝,您的脚本应该处理此异常,并悄悄地转到下一个NS(如果有),直到列表用尽为止


另一点建议:您尝试解析与“@”不同的资源名称。相反,请查看记录类型。您应该只解析
CNAME
MX
NS
。其他常见类型有
TXT
A
AAAA
SOA
。其余的则更加奇特,如
NAPTR
LOC
SRV
。我认为没有什么应该解决的。

修复了您的代码,看起来还不太好,但它可以工作

#!/usr/bin/python3
# you might want to run python3 -m pip install dnspython before running this script

import sys
import dns.query
import dns.zone
import dns.resolver

# formatting setup
from colorama import Fore, Style
bracket = f"{Fore.BLUE}[{Fore.GREEN}*{Fore.BLUE}]{Style.RESET_ALL} "
bracket_err = f"{Fore.BLUE}[{Fore.RED}*{Fore.BLUE}]{Style.RESET_ALL} "
def drawLine():
    print ('-' * 75)
    
# read arguments    
try:
    domain = (sys.argv[1])
except:
    print("[!] USAGE: python3 zt.py DOMAIN_NAME")
    sys.exit(0)

# DNS functions
def resolveDNS(name):
    resolver = dns.resolver.Resolver()
    results = resolver.query(name , "A")
    return results

def getNS (domain):
    mapping = {}
    name_servers = dns.resolver.query(domain, 'NS')
    print ("\nThe name servers for " + domain + " are:")
    drawLine()
    for name_server in name_servers:
        A_records = resolveDNS(str(name_server))
        for item in A_records:
            answer = ','.join([str(item)])
        mapping[str(name_server)] = answer
        print (bracket, "{:30}".format(str(name_server).rstrip('.')), "{:15}".format(answer))       
    return mapping
    
def zoneXFR(server):
    try:
        zone = dns.zone.from_xfr(dns.query.xfr(str(server).rstrip('.'), domain))
    except Exception as e:
        print (bracket_err, f"{Fore.RED}Error:{Style.RESET_ALL}", e.__class__, e)
    else:
        print ("\nResults for",server, "\nZone origin:", str(zone.origin).rstrip('.'))
        drawLine()
        for host in zone:
            if str(host) != '@':
                A_records = resolveDNS(str(host) + "." + domain)
                for item in A_records:
                    answer = ','.join([str(item)])   
                print(bracket, "{:30}".format(str(host) + "." + domain), answer)
        drawLine()
        
name_servers = getNS(domain)
for server in name_servers:
    print ("\nAttempting zone transfers for", server,name_servers[server])
    zoneXFR(name_servers[server])

这一切都有道理。我没有时间更改和测试它,但我相信它应该可以工作。“名称服务器列表并不总是以相同的顺序返回。”这是DNS的设计。它不处理列表(有序),而是处理记录集(无序)。递归名称服务器通常在每次查询记录时都会以不同的顺序返回记录,以确保客户端不会坚持使用同一个记录。代码中存在多个问题,但对于DNS世界,您必须记住的一点是,对于任何查询,您可能会返回一些与预期记录不同的内容,比如查询
A
,但您会得到
CNAME
。你必须正确地处理这个问题,否则你会有很多假设,这些假设在某些情况下有效,但在其他情况下无效。
for server in name_servers:
    try:
        zone = dns.zone.from_xfr(dns.query.xfr(str(server).rstrip('.'), domain))
        print ("\nResults for",server, "\nZone origin:", str(zone.origin).rstrip('.'))
        line()
try:
    for server in name_servers:
        zone = dns.zone.from_xfr(dns.query.xfr(str(server).rstrip('.'), domain))
        print ("\nResults for",server, "\nZone origin:", str(zone.origin).rstrip('.'))
        ...
zone = dns.zone.from_xfr(dns.query.xfr(str(server).rstrip('.'), domain))
#!/usr/bin/python3
# you might want to run python3 -m pip install dnspython before running this script

import sys
import dns.query
import dns.zone
import dns.resolver

# formatting setup
from colorama import Fore, Style
bracket = f"{Fore.BLUE}[{Fore.GREEN}*{Fore.BLUE}]{Style.RESET_ALL} "
bracket_err = f"{Fore.BLUE}[{Fore.RED}*{Fore.BLUE}]{Style.RESET_ALL} "
def drawLine():
    print ('-' * 75)
    
# read arguments    
try:
    domain = (sys.argv[1])
except:
    print("[!] USAGE: python3 zt.py DOMAIN_NAME")
    sys.exit(0)

# DNS functions
def resolveDNS(name):
    resolver = dns.resolver.Resolver()
    results = resolver.query(name , "A")
    return results

def getNS (domain):
    mapping = {}
    name_servers = dns.resolver.query(domain, 'NS')
    print ("\nThe name servers for " + domain + " are:")
    drawLine()
    for name_server in name_servers:
        A_records = resolveDNS(str(name_server))
        for item in A_records:
            answer = ','.join([str(item)])
        mapping[str(name_server)] = answer
        print (bracket, "{:30}".format(str(name_server).rstrip('.')), "{:15}".format(answer))       
    return mapping
    
def zoneXFR(server):
    try:
        zone = dns.zone.from_xfr(dns.query.xfr(str(server).rstrip('.'), domain))
    except Exception as e:
        print (bracket_err, f"{Fore.RED}Error:{Style.RESET_ALL}", e.__class__, e)
    else:
        print ("\nResults for",server, "\nZone origin:", str(zone.origin).rstrip('.'))
        drawLine()
        for host in zone:
            if str(host) != '@':
                A_records = resolveDNS(str(host) + "." + domain)
                for item in A_records:
                    answer = ','.join([str(item)])   
                print(bracket, "{:30}".format(str(host) + "." + domain), answer)
        drawLine()
        
name_servers = getNS(domain)
for server in name_servers:
    print ("\nAttempting zone transfers for", server,name_servers[server])
    zoneXFR(name_servers[server])