• PUDN用户
    了解作者
  • Python
    开发工具
  • 3KB
    文件大小
  • rar
    文件格式
  • 0
    收藏次数
  • 1 积分
    下载积分
  • 16
    下载次数
  • 2013-05-28 01:17
    上传日期
使用python语言实现 dns代理,支持使用TCP和UDP协议
DNSProxy.rar
  • DNSProxy
  • config.py
    998B
  • dnsproxy.py
    4KB
内容介绍
# -*- encoding: utf-8 -*- import sys, os sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from twisted.names import dns, server, client, cache from twisted.application import service, internet import config class DomainMapper: """ 域名匹配类。 输入一组域名的配置。凡是 example.tld 均为精确 匹配,而 .example.tld 匹配 example.tld 以及 其所有的子域名。 当查询匹配规则的时候,返回这个规则的原始域。如果 不匹配,则返回 None。 """ def __init__(self, domains): # 记录参数 self._tree = {} self._hash = {} self._domains = domains # 计算域名匹配树。 for d in domains: d = d.lower() if d == '': continue if d.startswith("."): # 匹配 .example.tld dd = d[1:] if dd == '': continue # 将 example.tld 加入 hash 表。 self._hash[dd] = d # 填写 tree[tld][example] 的查找树。 tree = self._tree dparts = dd.split('.') dparts.reverse() for k in dparts: if k == '': continue if k in tree: tree = tree[k] else: tree[k] = {} tree = tree[k] # 写入匹配信息 tree['@'] = d else: # 只写入 example.tld self._hash[d] = d def lookup(self, domain): domain = domain.lower() # 查找 hash 表。 if domain in self._hash: return self._hash[domain] # 查找树。 dparts = domain.split('.') dparts.reverse() tree = self._tree for k in dparts: if k == '': continue if k in tree: tree = tree[k] else: if "@" in tree: return tree["@"] else: return None if "@" in tree: return tree["@"] else: return None class CustomResolver(client.Resolver): """ 根据 config 对象的配置解析 Host。 """ def __init__(self, config): # 记录参数 self.config = config # 初始化基类 server = self.config.servers[self.config.default_server] client.Resolver.__init__(self, servers=[server["host"], server["port"]]) # 计算 Domain Mappers self.host_mappers = DomainMapper(self.config.hosts) self.lookup_mappers = {} for g in self.config.lookups: self.lookup_mappers[g[0]] = DomainMapper(g[1]) def lookupAddress(self, name, timeout=None): # 查找 HOST 表 kname = self.host_mappers.lookup(name) if kname is not None: result = self.config.hosts[kname] def packResult(value): return [ (dns.RRHeader(name, dns.A, dns.IN, self.config.hosts_ttl, dns.Record_A(value, self.config.hosts_ttl)),), (), (), ] # result.addCallback(packResult) return packResult(result) # 选定上游 DNS 服务器 server = self.config.servers[self.config.default_server] for g in self.config.lookups: dm = self.lookup_mappers[g[0]] kname = dm.lookup(name) if kname is not None: server = self.config.servers[g[0]] # 根据服务器建立 dns.Query,并执行查询 q = dns.Query(name, dns.A, dns.IN) r = client.Resolver(servers=[(server["host"], server["port"])]) d = None if server["tcp"]: if timeout is None: timeout = 10 d = r.queryTCP([q], timeout) else: d = r.queryUDP([q], timeout) d.addCallback(r.filterAnswers) return d # 创建 Twisted 程序框架。 application = service.Application('dnsserver', 1, 1) # 建立 Resolver resolver = CustomResolver(config) # 初始化协议 f = server.DNSServerFactory(caches=[cache.CacheResolver()], clients=[resolver]) p = dns.DNSDatagramProtocol(f) f.noisy = p.noisy = False # 同时注册 TCP 和 UDP 端口。 ret = service.MultiService() PORT=53 for (klass, arg) in [(internet.TCPServer, f), (internet.UDPServer, p)]: s = klass(PORT, arg) s.setServiceParent(ret) # 使用 Twisted 运行程序。 ret.setServiceParent(service.IServiceCollection(application)) # 空参数提示。 if __name__ == '__main__': import sys print "Usage: twistd -y %s" % sys.argv[0]
评论
    相关推荐