diff --git a/CHANGELOG.md b/CHANGELOG.md index 10dd08e..312b03a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ 所有对本项目的显著更改都将记录在此文件中。 +## [1.1.2] - 2025-12-19 + +### 添加 +- 添加不验证DNSSEC的域名功能,支持通过配置文件指定需要跳过DNSSEC验证的域名模式 +- 在DNSConfig结构体中增加NoDNSSECDomains字段,用于存储不验证DNSSEC的域名模式列表 + +### 修改 +- 在forwardDNSRequestWithCache函数中添加域名匹配逻辑,检查域名是否包含不验证DNSSEC的模式 +- 在所有查询模式(parallel、loadbalance、fastest-ip、default)中实现跳过DNSSEC验证的功能 + ## [1.1.1] - 2025-12-19 ### 修改 diff --git a/config.json b/config.json index efda661..60cfaba 100644 --- a/config.json +++ b/config.json @@ -40,6 +40,12 @@ }, "prefixDomain": [ "" + ], + "noDNSSECDomains": [ + "amazehome.cn", + "addr.arpa", + "amazehome.xyz", + ".cn" ] }, "http": { diff --git a/config/config.go b/config/config.go index fcdd59b..3e3a2aa 100644 --- a/config/config.go +++ b/config/config.go @@ -24,6 +24,7 @@ type DNSConfig struct { EnableDNSSEC bool `json:"enableDNSSEC"` // 是否启用DNSSEC支持 QueryMode string `json:"queryMode"` // 查询模式:"loadbalance"(负载均衡)、"parallel"(并行请求)、"fastest-ip"(最快的IP地址) DomainSpecificDNS DomainSpecificDNS `json:"domainSpecificDNS"` // 域名特定DNS服务器配置 + NoDNSSECDomains []string `json:"noDNSSECDomains"` // 不验证DNSSEC的域名模式列表 PrefixDomain []string `json:"prefixDomain"` // 搜索域名前缀列表,对应/etc/resolv.conf中的search domain } diff --git a/cookies.txt b/cookies.txt new file mode 100644 index 0000000..b31cfba --- /dev/null +++ b/cookies.txt @@ -0,0 +1,5 @@ +# Netscape HTTP Cookie File +# https://curl.se/docs/http-cookies.html +# This file was generated by libcurl! Edit at your own risk. + +#HttpOnly_localhost FALSE / FALSE 1765974335 session_id 1765887935065810022_0 diff --git a/dns-server b/dns-server index 507daa8..44763fb 100755 Binary files a/dns-server and b/dns-server differ diff --git a/dns/server.go b/dns/server.go index 57cdba0..44b3092 100644 --- a/dns/server.go +++ b/dns/server.go @@ -356,7 +356,7 @@ func (s *Server) handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) { if r.RecursionDesired == false { response := new(dns.Msg) response.SetReply(r) - response.RecursionAvailable = true + // 不再硬编码RecursionAvailable,使用默认值或上游返回的值 response.SetRcode(r, dns.RcodeRefused) w.WriteMsg(response) @@ -606,7 +606,7 @@ func (s *Server) handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) { func (s *Server) handleHostsResponse(w dns.ResponseWriter, r *dns.Msg, ip string) { response := new(dns.Msg) response.SetReply(r) - response.RecursionAvailable = true + // 不再硬编码RecursionAvailable,使用默认值或上游返回的值 if len(r.Question) > 0 { q := r.Question[0] @@ -646,7 +646,7 @@ func (s *Server) handleBlockedResponse(w dns.ResponseWriter, r *dns.Msg, domain response := new(dns.Msg) response.SetReply(r) - response.RecursionAvailable = true + // 不再硬编码RecursionAvailable,使用默认值或上游返回的值 // 获取屏蔽方法配置 blockMethod := "NXDOMAIN" // 默认值 @@ -717,6 +717,17 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg var udpSize uint16 = 4096 var doFlag bool = s.config.EnableDNSSEC + // 检查域名是否匹配不验证DNSSEC的模式 + noDNSSEC := false + for _, pattern := range s.config.NoDNSSECDomains { + if strings.Contains(domain, pattern) { + noDNSSEC = true + doFlag = false + logger.Debug("域名匹配到不验证DNSSEC的模式", "domain", domain, "pattern", pattern) + break + } + } + // 检查客户端请求是否包含EDNS记录 if opt := r.IsEdns0(); opt != nil { // 保留客户端的UDP缓冲区大小 @@ -816,14 +827,12 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg // 更新服务器统计信息 s.updateServerStats(resp.server, true, resp.rtt) - // 设置递归可用标志 - resp.response.RecursionAvailable = true - // 检查是否包含DNSSEC记录 containsDNSSEC := s.hasDNSSECRecords(resp.response) // 如果启用了DNSSEC且响应包含DNSSEC记录,验证DNSSEC签名 - if s.config.EnableDNSSEC && containsDNSSEC { + // 但如果域名匹配不验证DNSSEC的模式,则跳过验证 + if s.config.EnableDNSSEC && containsDNSSEC && !noDNSSEC { // 验证DNSSEC记录 signatureValid := s.verifyDNSSEC(resp.response) @@ -843,6 +852,9 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg stats.DNSSECFailed++ }) } + } else if noDNSSEC { + // 对于不验证DNSSEC的域名,始终设置AD标志为false + resp.response.AuthenticatedData = false } // 如果响应成功或为NXDOMAIN,根据DNSSEC状态选择最佳响应 @@ -910,14 +922,12 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg // 更新服务器统计信息 s.updateServerStats(selectedServer, true, rtt) - // 设置递归可用标志 - response.RecursionAvailable = true - // 检查是否包含DNSSEC记录 containsDNSSEC := s.hasDNSSECRecords(response) // 如果启用了DNSSEC且响应包含DNSSEC记录,验证DNSSEC签名 - if s.config.EnableDNSSEC && containsDNSSEC { + // 但如果域名匹配不验证DNSSEC的模式,则跳过验证 + if s.config.EnableDNSSEC && containsDNSSEC && !noDNSSEC { // 验证DNSSEC记录 signatureValid := s.verifyDNSSEC(response) @@ -937,6 +947,9 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg stats.DNSSECFailed++ }) } + } else if noDNSSEC { + // 对于不验证DNSSEC的域名,始终设置AD标志为false + response.AuthenticatedData = false } // 如果响应成功或为NXDOMAIN,根据DNSSEC状态选择最佳响应 @@ -1003,14 +1016,12 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg // 更新服务器统计信息 s.updateServerStats(fastestServer, true, rtt) - // 设置递归可用标志 - response.RecursionAvailable = true - // 检查是否包含DNSSEC记录 containsDNSSEC := s.hasDNSSECRecords(response) // 如果启用了DNSSEC且响应包含DNSSEC记录,验证DNSSEC签名 - if s.config.EnableDNSSEC && containsDNSSEC { + // 但如果域名匹配不验证DNSSEC的模式,则跳过验证 + if s.config.EnableDNSSEC && containsDNSSEC && !noDNSSEC { // 验证DNSSEC记录 signatureValid := s.verifyDNSSEC(response) @@ -1030,6 +1041,9 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg stats.DNSSECFailed++ }) } + } else if noDNSSEC { + // 对于不验证DNSSEC的域名,始终设置AD标志为false + response.AuthenticatedData = false } // 如果响应成功或为NXDOMAIN,根据DNSSEC状态选择最佳响应 @@ -1110,14 +1124,13 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg // 处理所有响应 for resp := range responses { if resp.error == nil && resp.response != nil { - // 设置递归可用标志 - resp.response.RecursionAvailable = true // 检查是否包含DNSSEC记录 containsDNSSEC := s.hasDNSSECRecords(resp.response) // 如果启用了DNSSEC且响应包含DNSSEC记录,验证DNSSEC签名 - if s.config.EnableDNSSEC && containsDNSSEC { + // 但如果域名匹配不验证DNSSEC的模式,则跳过验证 + if s.config.EnableDNSSEC && containsDNSSEC && !noDNSSEC { // 验证DNSSEC记录 signatureValid := s.verifyDNSSEC(resp.response) @@ -1137,6 +1150,9 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg stats.DNSSECFailed++ }) } + } else if noDNSSEC { + // 对于不验证DNSSEC的域名,始终设置AD标志为false + resp.response.AuthenticatedData = false } // 如果响应成功或为NXDOMAIN,根据DNSSEC状态选择最佳响应 @@ -1250,9 +1266,6 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg // 更新服务器统计信息 s.updateServerStats(resp.server, true, resp.rtt) - // 设置递归可用标志 - resp.response.RecursionAvailable = true - // 检查是否包含DNSSEC记录 containsDNSSEC := s.hasDNSSECRecords(resp.response) @@ -1313,9 +1326,6 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg // 更新服务器统计信息 s.updateServerStats(selectedServer, true, rtt) - // 设置递归可用标志 - response.RecursionAvailable = true - // 检查是否包含DNSSEC记录 containsDNSSEC := s.hasDNSSECRecords(response) @@ -1376,9 +1386,6 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg // 更新服务器统计信息 s.updateServerStats(fastestServer, true, rtt) - // 设置递归可用标志 - response.RecursionAvailable = true - // 检查是否包含DNSSEC记录 containsDNSSEC := s.hasDNSSECRecords(response) @@ -1437,9 +1444,6 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg // 更新服务器统计信息 s.updateServerStats(dnssecServer, true, rtt) - // 设置递归可用标志 - response.RecursionAvailable = true - // 检查是否包含DNSSEC记录 containsDNSSEC := s.hasDNSSECRecords(response) @@ -1505,7 +1509,7 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg // 本地解析成功,构建响应 localResponse := new(dns.Msg) localResponse.SetReply(r) - localResponse.RecursionAvailable = true + localResponse.AuthenticatedData = false localResponse.Rcode = dns.RcodeSuccess @@ -1568,7 +1572,7 @@ func (s *Server) forwardDNSRequestWithCache(r *dns.Msg, domain string) (*dns.Msg // 所有上游服务器都失败,返回服务器失败错误 response := new(dns.Msg) response.SetReply(r) - response.RecursionAvailable = true + response.SetRcode(r, dns.RcodeServerFailure) logger.Error("DNS查询失败", "domain", domain) diff --git a/temp_config.json b/temp_config.json deleted file mode 100644 index 237b7c2..0000000 --- a/temp_config.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "dns": { - "port": 5353, - "upstreamDNS": [ - "223.5.5.5:53", - "223.6.6.6:53", - "117.50.10.10:53", - "10.35.10.200:53" - ], - "dnssecUpstreamDNS": [ - "117.50.10.10:53", - "101.226.4.6:53", - "218.30.118.6:53", - "208.67.220.220:53", - "208.67.222.222:53" - ], - "timeout": 5000, - "statsFile": "data/stats.json", - "saveInterval": 300, - "cacheTTL": 30, - "enableDNSSEC": true, - "queryMode": "parallel", - "domainSpecificDNS": { - "amazehome.xyz": ["10.35.10.200:53"] - } - }, - "http": { - "port": 8081, - "host": "0.0.0.0", - "enableAPI": true, - "username": "admin", - "password": "admin" - }, - "shield": { - "localRulesFile": "data/rules.txt", - "blacklists": [], - "updateInterval": 3600, - "hostsFile": "data/hosts.txt", - "blockMethod": "NXDOMAIN", - "customBlockIP": "", - "statsFile": "./data/shield_stats.json", - "statsSaveInterval": 60, - "remoteRulesCacheDir": "data/remote_rules" - }, - "log": { - "file": "logs/dns-server-5353.log", - "level": "debug", - "maxSize": 100, - "maxBackups": 10, - "maxAge": 30 - } -} \ No newline at end of file