支持DNSSEC
This commit is contained in:
@@ -104,6 +104,7 @@ func NewServer(config *config.DNSConfig, shieldConfig *config.ShieldConfig, shie
|
||||
resolver: &dns.Client{
|
||||
Net: "udp",
|
||||
Timeout: time.Duration(config.Timeout) * time.Millisecond,
|
||||
UDPSize: 4096, // 增大UDP包大小以支持DNSSEC记录
|
||||
},
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
@@ -431,13 +432,43 @@ func (s *Server) handleBlockedResponse(w dns.ResponseWriter, r *dns.Msg, domain
|
||||
|
||||
// forwardDNSRequest 转发DNS请求到上游服务器
|
||||
func (s *Server) forwardDNSRequest(w dns.ResponseWriter, r *dns.Msg, domain string) {
|
||||
// 复制请求,保留原始请求的DO标志
|
||||
reqCopy := r.Copy()
|
||||
|
||||
// 尝试所有上游DNS服务器
|
||||
for _, upstream := range s.config.UpstreamDNS {
|
||||
response, rtt, err := s.resolver.Exchange(r, upstream)
|
||||
if err == nil && response != nil && response.Rcode == dns.RcodeSuccess {
|
||||
// 设置UDP客户端的Size以支持EDNS0和DNSSEC
|
||||
s.resolver.UDPSize = 4096
|
||||
|
||||
response, rtt, err := s.resolver.Exchange(reqCopy, upstream)
|
||||
if err == nil && response != nil {
|
||||
// 设置递归可用标志
|
||||
response.RecursionAvailable = true
|
||||
|
||||
// 如果启用了DNSSEC,确保响应包含DNSSEC记录
|
||||
if s.config.EnableDNSSEC {
|
||||
logger.Debug("DNSSEC启用,转发DNSSEC记录", "domain", domain, "server", upstream)
|
||||
}
|
||||
|
||||
// 保留客户端请求中的DO标志
|
||||
if edns0 := r.IsEdns0(); edns0 != nil {
|
||||
// 检查客户端是否请求了DNSSEC (设置了DO标志)
|
||||
if edns0.Do() {
|
||||
// 客户端请求了DNSSEC,确保响应包含EDNS0和DO标志
|
||||
if responseOpt := response.IsEdns0(); responseOpt != nil {
|
||||
responseOpt.SetDo()
|
||||
} else {
|
||||
// 添加EDNS0选项并设置DO标志
|
||||
responseOpt := new(dns.OPT)
|
||||
responseOpt.Hdr.Name = "."
|
||||
responseOpt.Hdr.Rrtype = dns.TypeOPT
|
||||
responseOpt.SetDo()
|
||||
response.Extra = append(response.Extra, responseOpt)
|
||||
}
|
||||
logger.Debug("保留DO标志", "domain", domain, "server", upstream)
|
||||
}
|
||||
}
|
||||
|
||||
w.WriteMsg(response)
|
||||
logger.Debug("DNS查询成功", "domain", domain, "rtt", rtt, "server", upstream)
|
||||
|
||||
@@ -456,6 +487,20 @@ func (s *Server) forwardDNSRequest(w dns.ResponseWriter, r *dns.Msg, domain stri
|
||||
response.SetReply(r)
|
||||
response.RecursionAvailable = true
|
||||
response.SetRcode(r, dns.RcodeServerFailure)
|
||||
|
||||
// 保留客户端请求中的DO标志
|
||||
if edns0 := r.IsEdns0(); edns0 != nil {
|
||||
// 检查客户端是否请求了DNSSEC (设置了DO标志)
|
||||
if edns0.Do() {
|
||||
// 添加EDNS0选项并设置DO标志
|
||||
responseOpt := new(dns.OPT)
|
||||
responseOpt.Hdr.Name = "."
|
||||
responseOpt.Hdr.Rrtype = dns.TypeOPT
|
||||
responseOpt.SetDo()
|
||||
response.Extra = append(response.Extra, responseOpt)
|
||||
}
|
||||
}
|
||||
|
||||
w.WriteMsg(response)
|
||||
|
||||
logger.Error("DNS查询失败", "domain", domain)
|
||||
|
||||
Reference in New Issue
Block a user