【发布时间】:2014-10-01 10:44:03
【问题描述】:
我是 python 的 Twisted 框架的新手。我正在玩客户 DNS 服务器,我想知道如何定位 DNS 请求的 SRC_IP。
我正在使用以下脚本:http://twisted.readthedocs.org/en/latest/names/howto/custom-server.html
特别是动态解析并想知道我如何定位请求的源 IP 的那个。 谢谢
【问题讨论】:
我是 python 的 Twisted 框架的新手。我正在玩客户 DNS 服务器,我想知道如何定位 DNS 请求的 SRC_IP。
我正在使用以下脚本:http://twisted.readthedocs.org/en/latest/names/howto/custom-server.html
特别是动态解析并想知道我如何定位请求的源 IP 的那个。 谢谢
【问题讨论】:
对twisted不太熟悉,我不知道这是否是最好的方式。我怀疑我在下面提出的不是因为直接在套接字上操作感觉不对,而是这样。
子类server.DNSServerFactory并覆盖handleQuery()方法,例如:
import socket
from twisted.internet.address import IPv4Address
class MyDNSServerFactory(server.DNSServerFactory):
def handleQuery(self, message, protocol, address):
if protocol.transport.socket.type == socket.SOCK_STREAM:
self.peer_address = protocol.transport.getPeer()
elif protocol.transport.socket.type == socket.SOCK_DGRAM:
self.peer_address = IPv4Address('UDP', *address)
else:
print "Unexpected socket type %r" % protocol.transport.socket.type
print "Got message from : %r" % self.peer_address
return server.DNSServerFactory.handleQuery(self, message, protocol, address)
.
.
.
factory = MyDNSServerFactory(
clients=[DynamicResolver(), client.Resolver(resolv='/etc/resolv.conf')]
)
需要担心的事情:
socket 似乎很卑鄙。还有其他方法可以做到这一点,例如子类dns.DNSDatagramProtocol 并覆盖datagramReceived(self, data, addr) 以获取客户端UDP 地址。 TCP 客户端地址将通过子类化和覆盖server.DNSServerFactory.connectionMade(self, protocol) 并使用protocol.transport.getPeer() 获取对等方的地址来获得。
更新答案以在 DynamicResolver 中提供对等地址
修改MyDNSServerFactory.handleQuery() 为具有peer_address 属性的解析器设置peer_address:
class MyDNSServerFactory(server.DNSServerFactory):
def handleQuery(self, message, protocol, address):
if protocol.transport.socket.type == socket.SOCK_STREAM:
self.peer_address = protocol.transport.getPeer()
elif protocol.transport.socket.type == socket.SOCK_DGRAM:
self.peer_address = IPv4Address('UDP', *address)
else:
print "Unexpected socket type %r" % protocol.transport.socket.type
print "Got message from : %r" % self.peer_address
# Make peer_address available to resolvers that support that attribute
for resolver in self.resolver.resolvers:
if hasattr(resolver, 'peer_address'):
resolver.peer_address = self.peer_address
return server.DNSServerFactory.handleQuery(self, message, protocol, address)
将以下peer_address 属性添加到类DynamicResolver:
def __init__(self):
self._peer_address = None
@property
def peer_address(self):
return self._peer_address
@peer_address.setter
def peer_address(self, value):
self._peer_address = value
现在您可以在DynamicResolver.query() 中访问peer_address,例如
def query(self, query, timeout=None):
print "In DynamicResolver.query(): self.peer_address = %r" % self.peer_address
if self._dynamicResponseRequired(query):
return defer.succeed(self._doDynamicResponse(query))
else:
return defer.fail(error.DomainError())
【讨论】:
socket让每个人都超级伤心。
DynamicResolver 可以从self.resolver.resolvers 列表中的MyDNSServerFactory 实例访问。这会很难看,但您可以为 peer_address 添加一个属性到 DynamicResolver,并通过迭代 self.resolver.resolvers 并为具有 peer_address 属性的解析器设置 peer_address 从 handleQuery 设置它。跨度>