【问题标题】:Python DNS ServerPython DNS 服务器
【发布时间】:2011-04-16 01:14:55
【问题描述】:

我正在向我当前的项目添加一项功能,该功能将允许网络管理员将软件安装到网络。我需要用 Python 编写一个 DNS 服务器,如果请求地址在我的列表中,我可以重定向到某个页面。我能够编写服务器,只是不确定如何重定向。

谢谢。我在 Windows XP 上使用 Python 2.6。

【问题讨论】:

    标签: python windows redirect dns


    【解决方案1】:

    我使用Python Twisted 库为NameOcean.net 编写了一个DNS 服务器。您可以在https://twistedmatrix.com/documents/16.5.0/names/howto/custom-server.html 上查看示例。

    【讨论】:

      【解决方案2】:

      使用circuitsdnslib,这是一个用 Python 编写的完整递归 dns 服务器,代码仅 143 行:

      #!/usr/bin/env python
      
      
      from __future__ import print_function
      
      
      from uuid import uuid4 as uuid
      
      
      from dnslib import CLASS, QR, QTYPE
      from dnslib import DNSHeader, DNSQuestion, DNSRecord
      
      
      from circuits.net.events import write
      from circuits import Component, Debugger, Event
      from circuits.net.sockets import UDPClient, UDPServer
      
      
      class lookup(Event):
          """lookup Event"""
      
      
      class query(Event):
          """query Event"""
      
      
      class response(Event):
          """response Event"""
      
      
      class DNS(Component):
      
          def read(self, peer, data):
              record = DNSRecord.parse(data)
              if record.header.qr == QR["QUERY"]:
                  return self.fire(query(peer, record))
              return self.fire(response(peer, record))
      
      
      class ReturnResponse(Component):
      
          def response(self, peer, response):
              return response
      
      
      class Client(Component):
      
          channel = "client"
      
          def init(self, server, port, channel=channel):
              self.server = server
              self.port = int(port)
      
              self.transport = UDPClient(0, channel=self.channel).register(self)
              self.protocol = DNS(channel=self.channel).register(self)
              self.handler = ReturnResponse(channel=self.channel).register(self)
      
      
      class Resolver(Component):
      
          def init(self, server, port):
              self.server = server
              self.port = port
      
          def lookup(self, qname, qclass="IN", qtype="A"):
              channel = uuid()
      
              client = Client(
                  self.server,
                  self.port,
                  channel=channel
              ).register(self)
      
              yield self.wait("ready", channel)
      
              self.fire(
                  write(
                      (self.server, self.port),
                      DNSRecord(
                          q=DNSQuestion(
                              qname,
                              qclass=CLASS[qclass],
                              qtype=QTYPE[qtype]
                          )
                      ).pack()
                  )
              )
      
              yield (yield self.wait("response", channel))
      
              client.unregister()
              yield self.wait("unregistered", channel)
              del client
      
      
      class ProcessQuery(Component):
      
          def query(self, peer, query):
              qname = query.q.qname
              qtype = QTYPE[query.q.qtype]
              qclass = CLASS[query.q.qclass]
      
              response = yield self.call(lookup(qname, qclass=qclass, qtype=qtype))
      
              record = DNSRecord(
                  DNSHeader(id=query.header.id, qr=1, aa=1, ra=1),
                  q=query.q,
              )
      
              for rr in response.value.rr:
                  record.add_answer(rr)
      
              yield record.pack()
      
      
      class Server(Component):
      
          def init(self, bind=("0.0.0.0", 53)):
              self.bind = bind
      
              self.transport = UDPServer(self.bind).register(self)
              self.protocol = DNS().register(self)
              self.handler = ProcessQuery().register(self)
      
      
      class App(Component):
      
          def init(self, bind=("0.0.0.0", 53), server="8.8.8.8", port=53,
                   verbose=False):
      
              if verbose:
                  Debugger().register(self)
      
              self.resolver = Resolver(server, port).register(self)
              self.server = Server(bind).register(self)
      
      
      def main():
          App().run()
      
      
      if __name__ == "__main__":
          main()
      

      用法:

      默认情况下,此示例绑定 go 0.0.0.0:53,因此您需要执行以下操作:

      sudo ./dnsserver.py
      

      否则更改bind 参数。

      【讨论】:

        【解决方案3】:

        这是一个用 python 编写的适用于我的 dns serer/proxy:

        http://thesprawl.org/projects/dnschef/

        【讨论】:

          【解决方案4】:

          有一个小而简单的例子here可以很容易地适应制作各种“迷你假DNS服务器”。请注意,绝对不涉及“重定向”(这不是 DNS 的工作方式):相反,请求是针对 域名,该请求的结果是 IP 地址。如果您想要做的与将名称转换为地址完全不同,那么您可能需要的是不是实际上是 DNS 服务器...?

          【讨论】:

          • 我猜不是。那我需要什么?我认为我需要一个代理,因为我希望网络和ims 可以轻松地使用我的程序进行网址过滤。如果我使用代理,它不能是“网络范围”实用程序,因为大多数路由器设置中没有任何地方可以设置代理。
          • @Zachary,我不知道你需要什么,因为我仍然不明白你想要完成什么样的“网址过滤”——我刚刚回答了你的实际问题 问。例如,如果您正在编写一个需要根据发出请求的 IP 做出不同响应的 Web 服务器,那么这显然是一个完全不同的问题(取决于您选择的 Web 框架 &c,对于初学者来说;-)。
          • ...如果您想要让您的服务器代理到不同的服务器,而不是技术上的 HTTP 代理,那也是可行的,但是 又一个 完全不同的问题.请提出一个不同的问题,具体说明您要更准确地完成什么,然后关闭这个问题!-)
          • 不太确定。我已经编写了一个代理,它可以阻止对具有某些关键字或地址的站点的访问。现在我需要一个针对整个网络的相同类型的解决方案。也许我需要 DNS 服务器通过代理转发所有请求?如果这是我需要的,请告诉我,我将发布该问题。谢谢。
          • @Zachary,当然,您可以拥有一个仅不翻译某些指定地址的 DNS 服务器(这是 DNS 服务器“阻止访问”的唯一方法) !-) -- “转发到代理”没有什么意义,除非你所谓的“代理”处理宇宙中的每个协议(包括基于 TCP 和基于 UDP 的协议,但这只是一个start),这确实是一个非常奇怪的“代理”(代理通常处理少量协议,通常只处理 HTTP 和 HTTPS ——而且 DNS 服务器当然不知道在什么协议中播放)。
          猜你喜欢
          • 2023-04-05
          • 1970-01-01
          • 1970-01-01
          • 2021-04-16
          • 1970-01-01
          • 2019-10-11
          • 2016-11-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多