更新Web文件
This commit is contained in:
BIN
dns-server
BIN
dns-server
Binary file not shown.
@@ -131,3 +131,102 @@ time="2025-11-23T18:08:48+08:00" level=debug msg="接收到DNS查询" client="10
|
||||
time="2025-11-23T18:08:48+08:00" level=debug msg="DNS查询成功" domain=h5hosting.dbankcdn.com rtt=7.025853ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:08:48+08:00" level=debug msg="接收到DNS查询" client="10.35.10.11:12618" domain=metrics1.data.hicloud.com type=1
|
||||
time="2025-11-23T18:08:48+08:00" level=debug msg="DNS查询成功" domain=metrics1.data.hicloud.com rtt=5.85395ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:14:50+08:00" level=debug msg="接收到DNS查询" client="10.35.10.11:18455" domain=dns.weixin.qq.com.cn type=1
|
||||
time="2025-11-23T18:14:50+08:00" level=debug msg="DNS查询成功" domain=dns.weixin.qq.com.cn rtt=5.279561ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:15:31+08:00" level=debug msg="接收到DNS查询" client="10.35.10.11:51626" domain=tvax4.sinaimg.cn type=1
|
||||
time="2025-11-23T18:15:31+08:00" level=debug msg="DNS查询成功" domain=tvax4.sinaimg.cn rtt=5.918625ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:15:57+08:00" level=debug msg="接收到DNS查询" client="10.35.10.11:5242" domain=tsms-drcn.security.dbankcloud.cn type=1
|
||||
time="2025-11-23T18:15:57+08:00" level=debug msg="DNS查询成功" domain=tsms-drcn.security.dbankcloud.cn rtt=6.292185ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:17:24+08:00" level=debug msg="接收到DNS查询" client="10.35.10.11:3812" domain=login.microsoftonline.com type=1
|
||||
time="2025-11-23T18:17:24+08:00" level=debug msg="DNS查询成功" domain=login.microsoftonline.com rtt=8.062737ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:20:29+08:00" level=debug msg="接收到DNS查询" client="10.35.10.11:24579" domain=apd-pcdnwxlogin.teg.tencent-cloud.net type=1
|
||||
time="2025-11-23T18:20:29+08:00" level=debug msg="DNS查询成功" domain=apd-pcdnwxlogin.teg.tencent-cloud.net rtt=6.721482ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:22:01+08:00" level=debug msg="接收到DNS查询" client="10.35.10.11:46378" domain=nearby-find-api-drcn.hms.dbankcloud.com type=1
|
||||
time="2025-11-23T18:22:01+08:00" level=debug msg="DNS查询成功" domain=nearby-find-api-drcn.hms.dbankcloud.com rtt=5.399528ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:22:37+08:00" level=info msg="正在关闭服务..."
|
||||
time="2025-11-23T18:22:37+08:00" level=info msg="DNS服务器已停止"
|
||||
time="2025-11-23T18:22:37+08:00" level=error msg="HTTP控制台服务器启动失败" error="http: Server closed"
|
||||
time="2025-11-23T18:22:37+08:00" level=info msg="HTTP控制台服务器已停止"
|
||||
time="2025-11-23T18:22:37+08:00" level=info msg="所有服务已关闭"
|
||||
time="2025-11-23T18:22:37+08:00" level=warning msg="日志系统已关闭"
|
||||
time="2025-11-23T18:28:33+08:00" level=error msg="获取远程规则失败" error="远程服务器返回错误状态码: 404" url="https://example.com/rules.txt"
|
||||
time="2025-11-23T18:28:33+08:00" level=info msg="规则加载完成,域名规则: 2, 排除规则: 0, 正则规则: 2, hosts规则: 3"
|
||||
time="2025-11-23T18:28:33+08:00" level=info msg="DNS服务器已启动,监听端口: 53"
|
||||
time="2025-11-23T18:28:33+08:00" level=info msg="HTTP控制台已启动,监听端口: 8080"
|
||||
time="2025-11-23T18:28:33+08:00" level=info msg="DNS TCP服务器启动,监听端口: 53"
|
||||
time="2025-11-23T18:28:33+08:00" level=info msg="DNS UDP服务器启动,监听端口: 53"
|
||||
time="2025-11-23T18:28:33+08:00" level=info msg="HTTP控制台服务器启动,监听地址: 0.0.0.0:8080"
|
||||
time="2025-11-23T18:28:41+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55569" domain=adjust.net.amazehome.xyz type=1
|
||||
time="2025-11-23T18:28:41+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:55569" domain=adjust.net.amazehome.xyz
|
||||
time="2025-11-23T18:28:41+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55570" domain=adjust.net.amazehome.xyz type=28
|
||||
time="2025-11-23T18:28:41+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:55570" domain=adjust.net.amazehome.xyz
|
||||
time="2025-11-23T18:28:41+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55571" domain=adjust.net type=1
|
||||
time="2025-11-23T18:28:41+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:55571" domain=adjust.net
|
||||
time="2025-11-23T18:28:41+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55572" domain=adjust.net type=28
|
||||
time="2025-11-23T18:28:41+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:55572" domain=adjust.net
|
||||
time="2025-11-23T18:30:14+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:62375" domain=adjust.net.amazehome.xyz type=1
|
||||
time="2025-11-23T18:30:14+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:62375" domain=adjust.net.amazehome.xyz
|
||||
time="2025-11-23T18:30:14+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:62376" domain=adjust.net.amazehome.xyz type=28
|
||||
time="2025-11-23T18:30:14+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:62376" domain=adjust.net.amazehome.xyz
|
||||
time="2025-11-23T18:30:14+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:62377" domain=adjust.net type=1
|
||||
time="2025-11-23T18:30:14+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:62377" domain=adjust.net
|
||||
time="2025-11-23T18:30:14+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:62378" domain=adjust.net type=28
|
||||
time="2025-11-23T18:30:14+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:62378" domain=adjust.net
|
||||
time="2025-11-23T18:30:16+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55979" domain=adjust.net.amazehome.xyz type=1
|
||||
time="2025-11-23T18:30:16+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:55979" domain=adjust.net.amazehome.xyz
|
||||
time="2025-11-23T18:30:16+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55980" domain=adjust.net.amazehome.xyz type=28
|
||||
time="2025-11-23T18:30:16+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:55980" domain=adjust.net.amazehome.xyz
|
||||
time="2025-11-23T18:30:16+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55981" domain=adjust.net type=1
|
||||
time="2025-11-23T18:30:16+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:55981" domain=adjust.net
|
||||
time="2025-11-23T18:30:16+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55982" domain=adjust.net type=28
|
||||
time="2025-11-23T18:30:16+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:55982" domain=adjust.net
|
||||
time="2025-11-23T18:30:17+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:56717" domain=adjust.net.amazehome.xyz type=1
|
||||
time="2025-11-23T18:30:17+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:56717" domain=adjust.net.amazehome.xyz
|
||||
time="2025-11-23T18:30:17+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:56718" domain=adjust.net.amazehome.xyz type=28
|
||||
time="2025-11-23T18:30:17+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:56718" domain=adjust.net.amazehome.xyz
|
||||
time="2025-11-23T18:30:17+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:56719" domain=adjust.net type=1
|
||||
time="2025-11-23T18:30:17+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:56719" domain=adjust.net
|
||||
time="2025-11-23T18:30:17+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:56720" domain=adjust.net type=28
|
||||
time="2025-11-23T18:30:17+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:56720" domain=adjust.net
|
||||
time="2025-11-23T18:30:43+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:64531" domain=so.com.amazehome.xyz type=1
|
||||
time="2025-11-23T18:30:43+08:00" level=debug msg="DNS查询成功" domain=so.com.amazehome.xyz rtt=28.942261ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:30:43+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:64532" domain=so.com.amazehome.xyz type=28
|
||||
time="2025-11-23T18:30:43+08:00" level=debug msg="DNS查询成功" domain=so.com.amazehome.xyz rtt=66.744527ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:30:43+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:64533" domain=so.com type=1
|
||||
time="2025-11-23T18:30:43+08:00" level=debug msg="DNS查询成功" domain=so.com rtt=6.238678ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:30:43+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:64534" domain=so.com type=28
|
||||
time="2025-11-23T18:30:43+08:00" level=debug msg="DNS查询成功" domain=so.com rtt=76.33228ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:30:43+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:64535" domain=so.com.amazehome.xyz type=1
|
||||
time="2025-11-23T18:30:43+08:00" level=debug msg="DNS查询成功" domain=so.com.amazehome.xyz rtt=65.586366ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:30:43+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55838" domain=so.com.amazehome.xyz type=28
|
||||
time="2025-11-23T18:30:43+08:00" level=debug msg="DNS查询成功" domain=so.com.amazehome.xyz rtt=66.617532ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:30:43+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55839" domain=so.com type=1
|
||||
time="2025-11-23T18:30:43+08:00" level=debug msg="DNS查询成功" domain=so.com rtt=3.690694ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:30:43+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:55840" domain=so.com type=28
|
||||
time="2025-11-23T18:30:44+08:00" level=debug msg="DNS查询成功" domain=so.com rtt=24.691944ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:30:44+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:52832" domain=so.com.amazehome.xyz type=1
|
||||
time="2025-11-23T18:30:44+08:00" level=debug msg="DNS查询成功" domain=so.com.amazehome.xyz rtt=67.631415ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:30:44+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:52833" domain=so.com.amazehome.xyz type=28
|
||||
time="2025-11-23T18:30:44+08:00" level=debug msg="DNS查询成功" domain=so.com.amazehome.xyz rtt=67.775451ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:30:44+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:52834" domain=so.com type=1
|
||||
time="2025-11-23T18:30:44+08:00" level=debug msg="DNS查询成功" domain=so.com rtt=6.394435ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:30:44+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:52835" domain=so.com type=28
|
||||
time="2025-11-23T18:30:44+08:00" level=debug msg="DNS查询成功" domain=so.com rtt=41.126372ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:30:46+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:49722" domain=tracking.ad.qq.com.amazehome.xyz type=1
|
||||
time="2025-11-23T18:30:46+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:49722" domain=tracking.ad.qq.com.amazehome.xyz
|
||||
time="2025-11-23T18:30:46+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:49723" domain=tracking.ad.qq.com.amazehome.xyz type=28
|
||||
time="2025-11-23T18:30:46+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:49723" domain=tracking.ad.qq.com.amazehome.xyz
|
||||
time="2025-11-23T18:30:46+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:49724" domain=tracking.ad.qq.com type=1
|
||||
time="2025-11-23T18:30:46+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:49724" domain=tracking.ad.qq.com
|
||||
time="2025-11-23T18:30:46+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:49725" domain=tracking.ad.qq.com type=28
|
||||
time="2025-11-23T18:30:46+08:00" level=info msg="域名被屏蔽" client="10.35.10.78:49725" domain=tracking.ad.qq.com
|
||||
time="2025-11-23T18:30:48+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:64389" domain=ads.qq.com.amazehome.xyz type=1
|
||||
time="2025-11-23T18:30:48+08:00" level=debug msg="DNS查询成功" domain=ads.qq.com.amazehome.xyz rtt=23.436825ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:30:48+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:64390" domain=ads.qq.com.amazehome.xyz type=28
|
||||
time="2025-11-23T18:30:48+08:00" level=debug msg="DNS查询成功" domain=ads.qq.com.amazehome.xyz rtt=26.677483ms server="223.5.5.5:53"
|
||||
time="2025-11-23T18:30:48+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:64391" domain=ads.qq.com type=1
|
||||
time="2025-11-23T18:30:48+08:00" level=error msg="DNS查询失败" domain=ads.qq.com
|
||||
time="2025-11-23T18:30:48+08:00" level=debug msg="接收到DNS查询" client="10.35.10.78:64392" domain=ads.qq.com type=28
|
||||
time="2025-11-23T18:30:48+08:00" level=error msg="DNS查询失败" domain=ads.qq.com
|
||||
time="2025-11-23T18:31:49+08:00" level=debug msg="接收到DNS查询" client="10.35.10.11:8360" domain=self.events.data.microsoft.com type=65
|
||||
time="2025-11-23T18:31:49+08:00" level=debug msg="DNS查询成功" domain=self.events.data.microsoft.com rtt=14.34768ms server="223.5.5.5:53"
|
||||
|
||||
@@ -25,19 +25,21 @@ type BlockedDomain struct {
|
||||
|
||||
// Server DNS服务器
|
||||
type Server struct {
|
||||
config *config.DNSConfig
|
||||
shieldConfig *config.ShieldConfig
|
||||
shieldManager *shield.ShieldManager
|
||||
server *dns.Server
|
||||
resolver *dns.Client
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
statsMutex sync.Mutex
|
||||
stats *Stats
|
||||
blockedDomainsMutex sync.RWMutex
|
||||
blockedDomains map[string]*BlockedDomain
|
||||
hourlyStatsMutex sync.RWMutex
|
||||
hourlyStats map[string]int64 // 按小时统计屏蔽数量
|
||||
config *config.DNSConfig
|
||||
shieldConfig *config.ShieldConfig
|
||||
shieldManager *shield.ShieldManager
|
||||
server *dns.Server
|
||||
resolver *dns.Client
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
statsMutex sync.Mutex
|
||||
stats *Stats
|
||||
blockedDomainsMutex sync.RWMutex
|
||||
blockedDomains map[string]*BlockedDomain
|
||||
resolvedDomainsMutex sync.RWMutex
|
||||
resolvedDomains map[string]*BlockedDomain // 用于记录解析的域名
|
||||
hourlyStatsMutex sync.RWMutex
|
||||
hourlyStats map[string]int64 // 按小时统计屏蔽数量
|
||||
}
|
||||
|
||||
// Stats DNS服务器统计信息
|
||||
@@ -68,8 +70,9 @@ func NewServer(config *config.DNSConfig, shieldConfig *config.ShieldConfig, shie
|
||||
Allowed: 0,
|
||||
Errors: 0,
|
||||
},
|
||||
blockedDomains: make(map[string]*BlockedDomain),
|
||||
hourlyStats: make(map[string]int64),
|
||||
blockedDomains: make(map[string]*BlockedDomain),
|
||||
resolvedDomains: make(map[string]*BlockedDomain),
|
||||
hourlyStats: make(map[string]int64),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,6 +187,16 @@ func (s *Server) handleHostsResponse(w dns.ResponseWriter, r *dns.Msg, ip string
|
||||
response.Answer = append(response.Answer, answer)
|
||||
}
|
||||
|
||||
// 记录解析域名统计
|
||||
domain := ""
|
||||
if len(r.Question) > 0 {
|
||||
domain = r.Question[0].Name
|
||||
if len(domain) > 0 && domain[len(domain)-1] == '.' {
|
||||
domain = domain[:len(domain)-1]
|
||||
}
|
||||
s.updateResolvedDomainStats(domain)
|
||||
}
|
||||
|
||||
w.WriteMsg(response)
|
||||
s.updateStats(func(stats *Stats) {
|
||||
stats.Allowed++
|
||||
@@ -272,6 +285,9 @@ func (s *Server) forwardDNSRequest(w dns.ResponseWriter, r *dns.Msg, domain stri
|
||||
w.WriteMsg(response)
|
||||
logger.Debug("DNS查询成功", "domain", domain, "rtt", rtt, "server", upstream)
|
||||
|
||||
// 记录解析域名统计
|
||||
s.updateResolvedDomainStats(domain)
|
||||
|
||||
s.updateStats(func(stats *Stats) {
|
||||
stats.Allowed++
|
||||
})
|
||||
@@ -311,7 +327,26 @@ func (s *Server) updateBlockedDomainStats(domain string) {
|
||||
|
||||
// 更新小时统计
|
||||
hourKey := time.Now().Format("2006-01-02-15")
|
||||
s.hourlyStatsMutex.Lock()
|
||||
s.hourlyStats[hourKey]++
|
||||
s.hourlyStatsMutex.Unlock()
|
||||
}
|
||||
|
||||
// updateResolvedDomainStats 更新解析域名统计
|
||||
func (s *Server) updateResolvedDomainStats(domain string) {
|
||||
s.resolvedDomainsMutex.Lock()
|
||||
defer s.resolvedDomainsMutex.Unlock()
|
||||
|
||||
if entry, exists := s.resolvedDomains[domain]; exists {
|
||||
entry.Count++
|
||||
entry.LastSeen = time.Now()
|
||||
} else {
|
||||
s.resolvedDomains[domain] = &BlockedDomain{
|
||||
Domain: domain,
|
||||
Count: 1,
|
||||
LastSeen: time.Now(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// updateStats 更新统计信息
|
||||
@@ -359,6 +394,29 @@ func (s *Server) GetTopBlockedDomains(limit int) []BlockedDomain {
|
||||
return domains
|
||||
}
|
||||
|
||||
// GetTopResolvedDomains 获取TOP解析域名
|
||||
func (s *Server) GetTopResolvedDomains(limit int) []BlockedDomain {
|
||||
s.resolvedDomainsMutex.RLock()
|
||||
defer s.resolvedDomainsMutex.RUnlock()
|
||||
|
||||
// 转换为切片
|
||||
domains := make([]BlockedDomain, 0, len(s.resolvedDomains))
|
||||
for _, entry := range s.resolvedDomains {
|
||||
domains = append(domains, *entry)
|
||||
}
|
||||
|
||||
// 按数量排序
|
||||
sort.Slice(domains, func(i, j int) bool {
|
||||
return domains[i].Count > domains[j].Count
|
||||
})
|
||||
|
||||
// 返回限制数量
|
||||
if len(domains) > limit {
|
||||
return domains[:limit]
|
||||
}
|
||||
return domains
|
||||
}
|
||||
|
||||
// GetRecentBlockedDomains 获取最近屏蔽的域名列表
|
||||
func (s *Server) GetRecentBlockedDomains(limit int) []BlockedDomain {
|
||||
s.blockedDomainsMutex.RLock()
|
||||
|
||||
@@ -46,6 +46,7 @@ func (s *Server) Start() error {
|
||||
mux.HandleFunc("/api/config", s.handleConfig)
|
||||
// 添加统计相关接口
|
||||
mux.HandleFunc("/api/top-blocked", s.handleTopBlockedDomains)
|
||||
mux.HandleFunc("/api/top-resolved", s.handleTopResolvedDomains)
|
||||
mux.HandleFunc("/api/recent-blocked", s.handleRecentBlockedDomains)
|
||||
mux.HandleFunc("/api/hourly-stats", s.handleHourlyStats)
|
||||
}
|
||||
@@ -114,6 +115,28 @@ func (s *Server) handleTopBlockedDomains(w http.ResponseWriter, r *http.Request)
|
||||
json.NewEncoder(w).Encode(result)
|
||||
}
|
||||
|
||||
// handleTopResolvedDomains 处理获取最常解析的域名请求
|
||||
func (s *Server) handleTopResolvedDomains(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
domains := s.dnsServer.GetTopResolvedDomains(10)
|
||||
|
||||
// 转换为前端需要的格式
|
||||
result := make([]map[string]interface{}, len(domains))
|
||||
for i, domain := range domains {
|
||||
result[i] = map[string]interface{}{
|
||||
"domain": domain.Domain,
|
||||
"count": domain.Count,
|
||||
}
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(result)
|
||||
}
|
||||
|
||||
// handleRecentBlockedDomains 处理最近屏蔽域名请求
|
||||
func (s *Server) handleRecentBlockedDomains(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -30,6 +31,8 @@ type ShieldManager struct {
|
||||
regexRules []regexRule
|
||||
regexExceptions []regexRule
|
||||
hostsMap map[string]string
|
||||
blockedDomainsCount map[string]int
|
||||
resolvedDomainsCount map[string]int
|
||||
rulesMutex sync.RWMutex
|
||||
updateCtx context.Context
|
||||
updateCancel context.CancelFunc
|
||||
@@ -46,6 +49,8 @@ func NewShieldManager(config *config.ShieldConfig) *ShieldManager {
|
||||
regexRules: []regexRule{},
|
||||
regexExceptions: []regexRule{},
|
||||
hostsMap: make(map[string]string),
|
||||
blockedDomainsCount: make(map[string]int),
|
||||
resolvedDomainsCount: make(map[string]int),
|
||||
updateCtx: ctx,
|
||||
updateCancel: cancel,
|
||||
}
|
||||
@@ -62,6 +67,7 @@ func (m *ShieldManager) LoadRules() error {
|
||||
m.regexRules = []regexRule{}
|
||||
m.regexExceptions = []regexRule{}
|
||||
m.hostsMap = make(map[string]string)
|
||||
// 保留计数数据,不随规则重新加载而清空
|
||||
|
||||
// 加载本地规则文件
|
||||
if err := m.loadLocalRules(); err != nil {
|
||||
@@ -380,6 +386,106 @@ func (m *ShieldManager) IsBlocked(domain string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// RecordBlockedDomain 记录被屏蔽的域名
|
||||
func (m *ShieldManager) RecordBlockedDomain(domain string) {
|
||||
m.rulesMutex.Lock()
|
||||
defer m.rulesMutex.Unlock()
|
||||
m.blockedDomainsCount[domain]++
|
||||
}
|
||||
|
||||
// RecordResolvedDomain 记录被解析的域名
|
||||
func (m *ShieldManager) RecordResolvedDomain(domain string) {
|
||||
m.rulesMutex.Lock()
|
||||
defer m.rulesMutex.Unlock()
|
||||
m.resolvedDomainsCount[domain]++
|
||||
}
|
||||
|
||||
// GetTopBlockedDomains 获取最常被屏蔽的域名
|
||||
func (m *ShieldManager) GetTopBlockedDomains(limit int) []map[string]interface{} {
|
||||
m.rulesMutex.RLock()
|
||||
defer m.rulesMutex.RUnlock()
|
||||
|
||||
// 如果没有数据,返回空数组
|
||||
if len(m.blockedDomainsCount) == 0 {
|
||||
return []map[string]interface{}{}
|
||||
}
|
||||
|
||||
// 转换为切片以便排序
|
||||
type domainCount struct {
|
||||
Domain string
|
||||
Count int
|
||||
}
|
||||
|
||||
var domains []domainCount
|
||||
for domain, count := range m.blockedDomainsCount {
|
||||
domains = append(domains, domainCount{Domain: domain, Count: count})
|
||||
}
|
||||
|
||||
// 按计数降序排序
|
||||
sort.Slice(domains, func(i, j int) bool {
|
||||
return domains[i].Count > domains[j].Count
|
||||
})
|
||||
|
||||
// 限制返回数量
|
||||
if len(domains) > limit {
|
||||
domains = domains[:limit]
|
||||
}
|
||||
|
||||
// 转换为API响应格式
|
||||
result := make([]map[string]interface{}, len(domains))
|
||||
for i, item := range domains {
|
||||
result[i] = map[string]interface{}{
|
||||
"domain": item.Domain,
|
||||
"count": item.Count,
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// GetTopResolvedDomains 获取最常被解析的域名
|
||||
func (m *ShieldManager) GetTopResolvedDomains(limit int) []map[string]interface{} {
|
||||
m.rulesMutex.RLock()
|
||||
defer m.rulesMutex.RUnlock()
|
||||
|
||||
// 如果没有数据,返回空数组
|
||||
if len(m.resolvedDomainsCount) == 0 {
|
||||
return []map[string]interface{}{}
|
||||
}
|
||||
|
||||
// 转换为切片以便排序
|
||||
type domainCount struct {
|
||||
Domain string
|
||||
Count int
|
||||
}
|
||||
|
||||
var domains []domainCount
|
||||
for domain, count := range m.resolvedDomainsCount {
|
||||
domains = append(domains, domainCount{Domain: domain, Count: count})
|
||||
}
|
||||
|
||||
// 按计数降序排序
|
||||
sort.Slice(domains, func(i, j int) bool {
|
||||
return domains[i].Count > domains[j].Count
|
||||
})
|
||||
|
||||
// 限制返回数量
|
||||
if len(domains) > limit {
|
||||
domains = domains[:limit]
|
||||
}
|
||||
|
||||
// 转换为API响应格式
|
||||
result := make([]map[string]interface{}, len(domains))
|
||||
for i, item := range domains {
|
||||
result[i] = map[string]interface{}{
|
||||
"domain": item.Domain,
|
||||
"count": item.Count,
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// GetHostsIP 获取hosts文件中的IP映射
|
||||
func (m *ShieldManager) GetHostsIP(domain string) (string, bool) {
|
||||
m.rulesMutex.RLock()
|
||||
|
||||
@@ -1567,40 +1567,37 @@ function loadRules() {
|
||||
document.getElementById('top-blocked-domains').innerHTML = '<div class="empty-state"><i class="fas fa-exclamation-circle"></i><p>加载失败</p></div>';
|
||||
});
|
||||
|
||||
// 加载TOP解析域名(由于没有直接的API,这里使用模拟数据)
|
||||
// 实际使用时,应该调用后端提供的相关API
|
||||
setTimeout(() => {
|
||||
const mockResolvedDomains = [
|
||||
{ domain: 'baidu.com', count: 1532 },
|
||||
{ domain: 'sina.com.cn', count: 987 },
|
||||
{ domain: 'qq.com', count: 845 },
|
||||
{ domain: 'aliyun.com', count: 732 },
|
||||
{ domain: 'github.com', count: 654 },
|
||||
{ domain: 'gitee.com', count: 521 },
|
||||
{ domain: 'bing.com', count: 489 },
|
||||
{ domain: 'sohu.com', count: 398 },
|
||||
{ domain: 'jd.com', count: 345 },
|
||||
{ domain: 'taobao.com', count: 298 }
|
||||
];
|
||||
|
||||
const container = document.getElementById('top-resolved-domains');
|
||||
container.innerHTML = '';
|
||||
|
||||
mockResolvedDomains.forEach((item, index) => {
|
||||
const listItem = document.createElement('div');
|
||||
listItem.className = 'list-item';
|
||||
listItem.innerHTML = `
|
||||
<div class="list-content">
|
||||
<div class="list-title">${index + 1}. ${item.domain}</div>
|
||||
<div class="list-description">解析次数: ${item.count}</div>
|
||||
</div>
|
||||
<div class="list-actions">
|
||||
<span class="badge badge-success">解析</span>
|
||||
</div>
|
||||
`;
|
||||
container.appendChild(listItem);
|
||||
// 加载TOP解析域名
|
||||
fetch('/api/top-resolved')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
const container = document.getElementById('top-resolved-domains');
|
||||
container.innerHTML = '';
|
||||
|
||||
if (!data || data.length === 0) {
|
||||
container.innerHTML = '<div class="empty-state"><i class="fas fa-info-circle"></i><p>暂无解析域名统计</p></div>';
|
||||
return;
|
||||
}
|
||||
|
||||
data.forEach((item, index) => {
|
||||
const listItem = document.createElement('div');
|
||||
listItem.className = 'list-item';
|
||||
listItem.innerHTML = `
|
||||
<div class="list-content">
|
||||
<div class="list-title">${index + 1}. ${item.domain}</div>
|
||||
<div class="list-description">解析次数: ${item.count}</div>
|
||||
</div>
|
||||
<div class="list-actions">
|
||||
<span class="badge badge-success">解析</span>
|
||||
</div>
|
||||
`;
|
||||
container.appendChild(listItem);
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('加载TOP解析域名失败:', error);
|
||||
document.getElementById('top-resolved-domains').innerHTML = '<div class="empty-state"><i class="fas fa-exclamation-circle"></i><p>加载失败</p></div>';
|
||||
});
|
||||
}, 500);
|
||||
}
|
||||
|
||||
// 初始化页面
|
||||
|
||||
Reference in New Issue
Block a user