Я пытаюсь написать фиктивный DNS-сервер на основе Twisted для выполнения некоторых тестов.
Вдохновленный этим руководством Я написал очень простой сервер, который просто разрешает все в 127.0.0.1
:
from twisted.internet import defer, reactor
from twisted.names import dns, error, server
class MockDNSResolver:
def _doDynamicResponse(self, query):
name = query.name.name
record = dns.Record_A(address=b"127.0.0.1")
answer = dns.RRHeader(name=name, payload=record)
authority = []
additional = []
return [answer], authority, additional
def query(self, query, timeout=None):
print("Incoming query for:", query.name)
if query.type == dns.A:
return defer.succeed(self._doDynamicResponse(query))
else:
return defer.fail(error.DomainError())
if __name__ == "__main__":
clients = [MockDNSResolver()]
factory = server.DNSServerFactory(clients=clients)
protocol = dns.DNSDatagramProtocol(controller=factory)
reactor.listenUDP(10053, protocol)
reactor.listenTCP(10053, factory)
reactor.run()
Вышеописанное прекрасно работает с dig
и nslookup
(с другого терминала):
$ dig -p 10053 @localhost something.example.org A +short
127.0.0.1
$ nslookup something.else.example.org 127.0.0.1 -port=10053
Server: 127.0.0.1
Address: 127.0.0.1#10053
Non-authoritative answer:
Name: something.else.example.org
Address: 127.0.0.1
Я также получаю соответствующие хиты на терминале, на котором запущен сервер:
Incoming query for: something.example.org
Incoming query for: something.else.example.org
Затем я написал следующий фрагмент кода, основанный на этом разделе о выполнении запросов и этом разделе об установке пользовательского resolver :
from twisted.internet import reactor
from twisted.names.client import createResolver
from twisted.web.client import Agent
d = Agent(reactor).request(b'GET', b'http://does.not.exist')
reactor.installResolver(createResolver(servers=[('127.0.0.1', 10053)]))
def callback(result):
print('Result:', result)
d.addBoth(callback)
d.addBoth(lambda _: reactor.stop())
reactor.run()
Но это не удается (и я не получаю строк в серверном терминале). Похоже, что запросы отправляются не на фиктивный сервер, а на системный сервер:
Result: [Failure instance: Traceback: <class 'twisted.internet.error.DNSLookupError'>: DNS lookup failed: no results for hostname lookup: does.not.exist.
/.../venv/lib/python3.6/site-packages/twisted/internet/_resolver.py:137:deliverResults
/.../venv/lib/python3.6/site-packages/twisted/internet/endpoints.py:921:resolutionComplete
/.../venv/lib/python3.6/site-packages/twisted/internet/defer.py:460:callback
/.../venv/lib/python3.6/site-packages/twisted/internet/defer.py:568:_startRunCallbacks
--- <exception caught here> ---
/.../venv/lib/python3.6/site-packages/twisted/internet/defer.py:654:_runCallbacks
/.../venv/lib/python3.6/site-packages/twisted/internet/endpoints.py:975:startConnectionAttempts
]
Я использую:
- macOS 10.14.6 Python 3.6.6, витая 18.9.0
- Linux мята 19.1, Python 3.6.9, витая 19.7.0
Я ценю любую помощь, пожалуйста, дайте мне знать, требуется ли дополнительная информация.
Спасибо!