添加dns功能

This commit is contained in:
lirui
2026-01-04 22:18:43 +08:00
parent 49022b7ad5
commit 2eb133dc7a
2 changed files with 385 additions and 0 deletions

View File

@@ -8,6 +8,7 @@ import (
"syscall"
"time"
"github.com/meowrain/nodeprobe/internal/dns"
"github.com/meowrain/nodeprobe/internal/netstat"
)
@@ -27,6 +28,21 @@ func main() {
// 2. 设置刷新间隔(默认 1 秒)
interval := 1 * time.Second
// 启动DNS服务器
// 使用 Cloudflare DoH (也可以用 Google: https://dns.google/dns-query)
dnsServer := dns.NewDNSServerWithDoH(5353, "https://1.1.1.1/dns-query")
// 或者使用传统UDP: dnsServer := dns.NewDNSServer(5353, "8.8.8.8:53")
err = dnsServer.Start()
if err != nil {
fmt.Fprintf(os.Stderr, "Warning: Failed to start DNS server: %v\n", err)
fmt.Println("Continuing without DNS monitoring...")
dnsServer = nil
} else {
defer dnsServer.Stop()
fmt.Println("Configure sing-box to use DNS: 127.0.0.1:5353")
time.Sleep(2 * time.Second) // 给用户时间看到DNS服务器启动信息
}
// 3. 隐藏光标
fmt.Print("\033[?25l")
defer fmt.Print("\033[?25h") // 退出时恢复光标
@@ -45,6 +61,9 @@ func main() {
rates := netstat.CalculateRate(prevStats, currStats, interval)
printHeader()
printStats(rates, currStats)
if dnsServer != nil {
printDNSQueries(dnsServer)
}
prevStats = currStats
// 7. 主循环
@@ -64,12 +83,18 @@ func main() {
moveCursorToTop()
printHeader()
printStats(rates, currStats)
if dnsServer != nil {
printDNSQueries(dnsServer)
}
// 更新上一次的数据
prevStats = currStats
case <-sigChan:
fmt.Print("\033[?25h") // 恢复光标
if dnsServer != nil {
dnsServer.Stop()
}
fmt.Println("\nExiting...")
return
}
@@ -135,6 +160,46 @@ func printStats(rates []netstat.TrafficRate, stats []netstat.InterfaceStats) {
fmt.Print("\033[J")
}
// printDNSQueries 显示DNS查询记录
func printDNSQueries(dnsServer *dns.DNSServer) {
queries := dnsServer.GetRecentQueries(15)
fmt.Println()
fmt.Println("DNS Queries from sing-box")
fmt.Println("=", strings.Repeat("=", 100))
fmt.Printf("%-50s %-10s %-10s %-15s\n", "Domain", "Type", "Count", "Last Seen")
fmt.Println("-", strings.Repeat("-", 100))
if len(queries) == 0 {
fmt.Println(" No DNS queries yet. Waiting for sing-box traffic...")
} else {
for _, q := range queries {
domain := q.Domain
if len(domain) > 48 {
domain = domain[:45] + "..."
}
elapsed := time.Since(q.Timestamp)
timeStr := ""
if elapsed < time.Minute {
timeStr = fmt.Sprintf("%ds ago", int(elapsed.Seconds()))
} else if elapsed < time.Hour {
timeStr = fmt.Sprintf("%dm ago", int(elapsed.Minutes()))
} else {
timeStr = fmt.Sprintf("%dh ago", int(elapsed.Hours()))
}
fmt.Printf("%-50s %-10s %-10d %-15s\n",
domain,
q.QueryType,
q.Count,
timeStr,
)
}
}
fmt.Println()
}
// 生成流量条形图
func makeTrafficBar(bps, maxBps float64, isDownload bool) string {
// ANSI 颜色代码