(研) Dns寻找中...

文章记录学习过程,但并不一定有结果,会不断更新,也可能会挖坑。

之前也有写,一直在寻找一款DNS服务器。它需要有:

  1. 上游查询结果缓存功能。或以实现查询的加速。
  2. 请求过滤功能。主要还是http/https过滤广告,似乎有点超出DNS的范围。
  3. 手动指定ip与域名。多用于内网使用。
  4. 统计访问。

今天看的第一个是https://github.com/kenshinx/godns,测试能正常使用,缺少一些东西可能需要自己补。
它只是一个简单的DNS缓存服务。当本地配置文件修改时,能自动载入。可以在配置文件中指定ip与域名。
配有一个Web管理https://github.com/kenshinx/joke,虽然配置了一下Redis,但还是没运行正确。


继续研究github.com\kenshinx\godns。
因为原/etc/resolv.conf是空的,导致代码自己无法解析DNS请求,修改如下:

# 阿里
nameserver 223.5.5.5  
# 移动本身 
nameserver 218.203.244.62
# Public DNS
nameserver 119.29.29.29 
# BaiduDNS
nameserver 180.76.76.76

似乎当第一个没有返回时,并没有自动去查询第二个。稍后再确认、修改。

为了调试,在cache.go中添加Length函数,判断已用缓存的大小。 代码中已实现过Memcache和Redis缓存。
不知道server-list-file与resolv的区别是什么。


在 resolver.go 的 Lookup 函数中,发现对多个域名服务器的查询。

	ticker := time.NewTicker(time.Duration(settings.ResolvConfig.Interval) * time.Millisecond)
	defer ticker.Stop()
	//从顶到下开始查找每个名称服务器
	nameservers := r.Nameservers(qname)

	for _, nameserver := range nameservers {
		wg.Add(1)
		go L(nameserver)
		// 如果有答案,请提前退出
		select {
		case re := <-res:
			logger.Debug("%s resolv on %s rtt: %v", UnFqdn(qname), re.nameserver, re.rtt)
			return re.msg, nil
		case <-ticker.C:
			continue
		}
	}
	// 等待所有服务器完成
	wg.Wait()

这里的 L(nameserver) 即查询上游DNS服务器。


根据对 github.com\kenshinx\godns 的分析,可以把它扩展做为一个动态域名服务器:通过Web扩展API,客户端发送请求,服务器获取动态IP,写入hosts文件。
当然这只是利用原有方案。另外完全可以在hosts之后,上级DNS之前,添加一个中间过程,用于存取数据库IP记录或读取记录到缓存。
那接下来是否把域名的DNS解析设置给自己就可以了?

至于广告过滤,需要完成http/https代理服务。有时间再继续。


在pi的ubuntu中,库miekg/dns存在问题不能执行

# github.com/miekg/dns
../../miekg/dns/udp.go:18:10: undefined: ipv4.NewControlMessage
../../miekg/dns/udp.go:19:10: undefined: ipv6.NewControlMessage
../../miekg/dns/udp.go:73:8: cm6.Parse undefined (type *ipv6.ControlMessage has no field or method Parse)
../../miekg/dns/udp.go:77:8: cm4.Parse undefined (type *ipv4.ControlMessage has no field or method Parse)
../../miekg/dns/udp.go:95:11: cm.Marshal undefined (type *ipv6.ControlMessage has no field or method Marshal)
../../miekg/dns/udp.go:99:11: cm.Marshal undefined (type *ipv4.ControlMessage has no field or method Marshal)

准备给这个DNS服务套个壳,用Godot或fyne作为前端。然后再看看Linux下的问题。


Win中的Ubuntu系统能够正常的编译。