витой днс не работает - PullRequest
       5

витой днс не работает

4 голосов
/ 01 ноября 2010

Я хотел бы знать, почему следующее не работает.

from twisted internet import defer, reactor
from twisted.python.failure import Failure
import twisted.names.client

def do_lookup(do_lookup):
    d = twisted.names.client.getHostByName(domain)
    d.addBoth(lookup_done)

def lookup_done(result):
    print 'result:', result
    reactor.stop()

domain = 'twistedmatrix.com'    
reactor.callLater(0, do_lookup, domain) 
reactor.run()

Результат:

result: [Failure instance: Traceback
(failure with no frames): <class
'twisted.names.error.ResolverError'>:
Stuck at response without answers or
delegation ]

Ответы [ 3 ]

5 голосов
/ 04 июля 2013

На момент написания этой статьи это не получилось в Windows, поскольку он использует неверный путь к файлу хоста Windows (в twisted.names.client.createResolver . Он использует «c: \ windows \ hosts»Это было бы хорошо для версий Windows 98 и Me (ссылка здесь ), но не получилось бы с такой «современной» версией, как XP.

Сегодня, вероятно, следует использовать что-то вроде:

hosts = os.path.join(
                     os.environ.get('systemroot','C:\\Windows'),
                     r'system32\drivers\etc\hosts'
                    )

Я думаю это только частично решает проблему (или, может быть, это красная сельдь).

Теперь это будет работать только для имен, фактически указанных в этомфайл hosts. Что ему, вероятно, нужно сделать, это какой-то запрос реестра для DNS-сервера, а затем запросить его для поиска действительного имени DNS.

Этот рецепт выглядит многообещающим для получения фактическогоDNS-сервер.

3 голосов
/ 01 ноября 2010

Исправьте ваш пример следующим образом, чтобы он был синтаксически действителен:

from twisted.internet import reactor
import twisted.names.client

def do_lookup(domain):
    d = twisted.names.client.getHostByName(domain)
    d.addBoth(lookup_done)

def lookup_done(result):
    print 'result:', result
    reactor.stop()

domain = 'twistedmatrix.com'
reactor.callLater(0, do_lookup, domain)
reactor.run()

Я получаю:

$ python so-example.py 
result: 66.35.39.65

Итак, чтобы ответить на ваш вопрос: ваша локальная среда DNS не работает, а не искажено. Или, может быть, есть ошибка. Вам нужно будет отследить его дальше.

1 голос
/ 25 сентября 2015

Я немного покопался, почему явный client.createResolver(servers) не работал на наших корпоративных машинах с Windows.В кишках Twisted's createResolver является зависимой от ОС веткой:

def createResolver(servers=None, resolvconf=None, hosts=None):
    ...
    from twisted.names import resolve, cache, root, hosts as hostsModule
    if platform.getType() == 'posix':
        if resolvconf is None:
            resolvconf = '/etc/resolv.conf'
        if hosts is None:
            hosts = '/etc/hosts'
        theResolver = Resolver(resolvconf, servers)
        hostResolver = hostsModule.Resolver(hosts)
    else:
        if hosts is None:
            hosts = r'c:\windows\hosts'
        from twisted.internet import reactor
        bootstrap = _ThreadedResolverImpl(reactor)
        hostResolver = hostsModule.Resolver(hosts)
        theResolver = root.bootstrap(bootstrap)

    L = [hostResolver, cache.CacheResolver(), theResolver]
    return resolve.ResolverChain(L)

Первый предупреждающий знак для Windows заключается в том, что аргумент servers не используется, поэтому custom-DNSсерверы игнорируются.Далее следует, что _ThreadedResolverImpl (), который использует код, специфичный для платформы, перед добавлением в цепочку преобразователя заключен в root.bootstrap().

Цель root.bootstrap - использовать средство поиска платформы для поиска.root-servers.net, b.root-servers.net и т. д. с использованием синхронного распознавателя платформы Windows (который работает - и возвращает IP-адреса), а затем выполняет прямые DNS-запросы к корневым серверам.UDP-пакеты, запущенные на корневых серверах, затем блокируются нашим корпоративным брандмауэром - я вижу их в Wireshark.

Стандартный вызов getResolver (), используемый names.client.getHostByName (), вызывает createResolver() напрямую, чтоможет снова привести к этой неправильной настройке, загруженной рабочей настройкой DNS.В большинстве сред я думаю, что добавление Resolver (с корневыми или явными серверами) в ResolverChain вместе с _ThreadedResolverImpl будет работать как запасной вариант - за исключением того, что преобразователь платформы представляет собой другой интерфейс.

Вот пример обнаружениялокальные DNS-серверы асинхронно (анализируя выходные данные ipconfig), а затем устанавливая пользовательский преобразователь для их использования.

import sys

from twisted.python import log
from twisted.names import root, hosts, resolve, cache, client
from twisted.python.runtime import platform

from twisted.internet import reactor
from twisted.internet import utils
import re

def parseIpconfigDNSServers(output):
    servers = []
    found = False
    for line in output.split('\n'):
        if 'DNS Servers . . . . . . . . . . . :' in line or (found and not '. . . .' in line):
            servers.append(line[38:].strip())
            found = True
        else:
            found = False
    log.msg( 'Windows: Detected DNS servers %s' % (str(servers)))
    return servers

if platform.getType() != 'posix':
    d = utils.getProcessOutput(os.path.join(os.environ['WINDIR'], 'system32', 'ipconfig.exe'), ["/all"])
    d.addCallback(parseIpconfigDNSServers)
    d.addCallback(lambda r: client.Resolver(servers=[(h, 53) for h in r]))
    d.addErrback(log.msg)
    theResolver = root.DeferredResolver(d)
    client.theResolver = resolve.ResolverChain([cache.CacheResolver(), theResolver])

if __name__ == '__main__':
    log.startLogging(sys.stdout)
    def do_lookup(domain):
        d = client.getHostByName(domain)
        d.addBoth(log.msg)

    from twisted.internet import reactor
    reactor.callLater(0, do_lookup, 'example.com')
    reactor.run()

Я убрал это и разместил здесь https://gist.github.com/shuckc/af7490e1c4a2652ca740

...