CoreDNS筆記


因為項目的原因需要在客戶端啟動DNS服務,攔截本機DNS請求,考察了一下開源的DNS Server項目,適合在Windows下使用的只有CoreDNS。

說明

CoreDNS的項目地址
https://coredns.io
https://github.com/coredns/coredns

這是go語言寫的,所以默認支持大部分平台,在windows下有一些瑕疵(下面會說),但是總體已經是功能比較完整的一個DNS服務端實現。

使用

CoreDNS的使用很簡單,coredns.exe配合一個Corefile配置文件直接就可以運行。配置文件的格式類似於

# 監聽默認端口(53), .表示所有域名
. {
  # 綁定lo網口,這樣啟動是靜默的,否則默認綁定0.0.0.0會彈出windows防火牆
  bind 127.0.0.1

  # hosts插件,自定義域名的解析,解析的域名少就直接用hosts插件完成需求,如果有大量自定義域名解析建議用file插件使用 符合RFC 1035規范的DNS解析配置文件
  hosts {
    10.6.6.2 somewhere.com
    10.6.6.3 ip.com
    10.10.0.2 m.baidu.com
    # ttl
    ttl 60
    # 繼續執行
    fallthrough
  }
  # 將走到這一步的所有解析請求轉發給192.168.10.1,這里可以配置多個地址,轉發時會同時對多個地址發起轉發
  forward . 192.168.10.1:53

  # 重載hosts配置 windows下不支持
  # reload 10s

  # 輸出錯誤
  errors

  # 輸出日志
  #log . "{remote}:{port} - {>id} \"{proto} Request: {name} {type} {rsize} {rcode}\""
}

在命令行執行下面的命令啟動服務

coredns.exe -conf path\to\Corefile

然后新開一個窗口,驗證dns服務是否正常。注意這里第二個參數就是DNS服務器地址,要用127.0.0.1不能用localhost

nslookup www.baidu.com 127.0.0.1

編譯和定制

在Goland里可以直接通過go mod tidy && go build編譯,在clone的代碼上直接編譯,產生的coredns.exe文件有60M。如果要減小文件尺寸,可以去掉一些不必要的插件。
插件的配置文件在plugin.cfg,可以將其中和k8s, aws相關的插件屏蔽,以下是我屏蔽插件后的列表

metadata:metadata
cancel:cancel
tls:tls
reload:reload
nsid:nsid
bufsize:bufsize
root:root
bind:bind
debug:debug
trace:trace
ready:ready
health:health
pprof:pprof
#prometheus:metrics
errors:errors
log:log
dnstap:dnstap
local:local
dns64:dns64
acl:acl
any:any
chaos:chaos
loadbalance:loadbalance
cache:cache
rewrite:rewrite
dnssec:dnssec
autopath:autopath
template:template
transfer:transfer
hosts:hosts
#route53:route53
#azure:azure
#clouddns:clouddns
#k8s_external:k8s_external
#kubernetes:kubernetes
file:file
auto:auto
secondary:secondary
etcd:etcd
loop:loop
forward:forward
grpc:grpc
#erratic:erratic
whoami:whoami
on:github.com/coredns/caddy/onevent
sign:sign

然后執行下面的命令就可以重新編譯

# 根據plugin.cfg更新插件配置
go generate
# 編譯
go build

這樣產生的coredns.exe只有25M大小
通過coredns.exe -plugins命令可以看到包含插件的情況

coredns.exe -plugins
Server types:
  dns

Caddyfile loaders:
  flag
  default

Other plugins:
  dns.acl
  dns.any
  dns.auto
  dns.autopath
  dns.bind
  dns.bufsize
  dns.cache
  dns.cancel
  dns.chaos
  dns.debug
  dns.dns64
  dns.dnssec
  dns.dnstap
  dns.errors
  dns.etcd
  dns.file
  dns.forward
  dns.grpc
  dns.health
  dns.hosts
  dns.loadbalance
  dns.local
  dns.log
  dns.loop
  dns.metadata
  dns.nsid
  dns.pprof
  dns.prometheus
  dns.ready
  dns.reload
  dns.rewrite
  dns.root
  dns.secondary
  dns.sign
  dns.template
  dns.tls
  dns.trace
  dns.transfer
  dns.whoami
  on

修改

因為要記錄解析結果,但是CoreDNS的日志輸出不包含解析結果,需要自己動手修改。這個修改在forward.go
在 ServeDNS() 方法下,在下面兩行之前

		w.WriteMsg(ret)
		return 0, nil

增加

		for _, a := range ret.Answer {
			if a.Header().Rrtype == dns.TypeA {
				for _, b := range ret.Question {
					log.Printf("%v ", b.Name)
				}
				log.Printf("IP: %v\n", a.(*dns.A).A.String())
			} else if a.Header().Rrtype == dns.TypeAAAA {
				for _, b := range ret.Question {
					log.Printf("%v ", b.Name)
				}
				log.Printf("IP: %v\n", a.(*dns.AAAA).AAAA.String())
			} else if a.Header().Rrtype == dns.TypeCNAME {
				for _, b := range ret.Question {
					log.Printf("%v ", b.Name)
				}
				log.Printf("CNAME: %v\n", a.(*dns.CNAME).Target)
			} else if a.Header().Rrtype == dns.TypePTR {
				log.Printf("PTR: %v\n", a.(*dns.PTR).Ptr)
			} else {
				log.Printf("Type: %v\n", a.Header().Rrtype)
			}
		}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM