update
This commit is contained in:
245
dns/main.go
Normal file
245
dns/main.go
Normal file
@@ -0,0 +1,245 @@
|
||||
// DNS Server API
|
||||
// @title DNS Server API
|
||||
// @version 1.0
|
||||
// @description DNS服务器API文档
|
||||
// @termsOfService http://swagger.io/terms/
|
||||
// @contact.name API Support
|
||||
// @contact.email support@example.com
|
||||
// @license.name Apache 2.0
|
||||
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
// @host localhost:8080
|
||||
// @BasePath /api
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
|
||||
"dns-server/config"
|
||||
"dns-server/dns"
|
||||
"dns-server/gfw"
|
||||
"dns-server/http"
|
||||
"dns-server/logger"
|
||||
"dns-server/shield"
|
||||
)
|
||||
|
||||
// createDefaultConfig 创建默认配置文件
|
||||
func createDefaultConfig(configFile string) error {
|
||||
// 默认配置内容
|
||||
defaultConfig := `{
|
||||
"dns": {
|
||||
"port": 53,
|
||||
"upstreamDNS": [
|
||||
"223.5.5.5:53",
|
||||
"223.6.6.6:53"
|
||||
],
|
||||
"dnssecUpstreamDNS": [
|
||||
"8.8.8.8:53",
|
||||
"1.1.1.1:53"
|
||||
],
|
||||
"timeout": 5000,
|
||||
"saveInterval": 300,
|
||||
"cacheTTL": 30,
|
||||
"enableDNSSEC": true,
|
||||
"queryMode": "parallel"
|
||||
},
|
||||
"http": {
|
||||
"port": 8080,
|
||||
"host": "0.0.0.0",
|
||||
"enableAPI": true,
|
||||
"username": "admin",
|
||||
"password": "admin"
|
||||
},
|
||||
"shield": {
|
||||
"blacklists": [
|
||||
{
|
||||
"name": "AdGuard DNS filter",
|
||||
"url": "https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/filter.txt",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "Adaway Default Blocklist",
|
||||
"url": "https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/hosts/adaway.txt",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "CHN-anti-AD",
|
||||
"url": "https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "My GitHub Rules",
|
||||
"url": "https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/costomize.txt",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"updateInterval": 3600,
|
||||
"blockMethod": "NXDOMAIN",
|
||||
"customBlockIP": "",
|
||||
"statsSaveInterval": 60
|
||||
},
|
||||
"gfwList": {
|
||||
"ip": "127.0.0.1",
|
||||
"content": "./data/gfwlist.txt",
|
||||
"enabled": true
|
||||
},
|
||||
"log": {
|
||||
"level": "debug",
|
||||
"maxSize": 100,
|
||||
"maxBackups": 10,
|
||||
"maxAge": 30
|
||||
}
|
||||
}`
|
||||
|
||||
// 写入默认配置到文件
|
||||
return os.WriteFile(configFile, []byte(defaultConfig), 0644)
|
||||
}
|
||||
|
||||
// createRequiredFiles 创建所需的文件和文件夹
|
||||
func createRequiredFiles(cfg *config.Config) error {
|
||||
// 创建数据文件夹
|
||||
dataDir := "./data"
|
||||
if err := os.MkdirAll(dataDir, 0755); err != nil {
|
||||
return fmt.Errorf("创建数据文件夹失败: %w", err)
|
||||
}
|
||||
|
||||
// 创建远程规则缓存文件夹
|
||||
if err := os.MkdirAll("data/remote_rules", 0755); err != nil {
|
||||
return fmt.Errorf("创建远程规则缓存文件夹失败: %w", err)
|
||||
}
|
||||
|
||||
// 创建日志文件夹
|
||||
logDir := filepath.Dir("logs/dns-server.log")
|
||||
if logDir != "." {
|
||||
if err := os.MkdirAll(logDir, 0755); err != nil {
|
||||
return fmt.Errorf("创建日志文件夹失败: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// 创建自定义规则文件
|
||||
if _, err := os.Stat("data/rules.txt"); os.IsNotExist(err) {
|
||||
if err := os.WriteFile("data/rules.txt", []byte("# 自定义规则文件\n# 格式:域名\n# 例如:example.com\n"), 0644); err != nil {
|
||||
return fmt.Errorf("创建自定义规则文件失败: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// 创建Hosts文件
|
||||
if _, err := os.Stat("data/hosts.txt"); os.IsNotExist(err) {
|
||||
if err := os.WriteFile("data/hosts.txt", []byte("# Hosts文件\n# 格式:IP 域名\n# 例如:127.0.0.1 localhost\n"), 0644); err != nil {
|
||||
return fmt.Errorf("创建Hosts文件失败: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// 创建GFWList文件
|
||||
if _, err := os.Stat("data/gfwlist.txt"); os.IsNotExist(err) {
|
||||
if err := os.WriteFile("data/gfwlist.txt", []byte("# GFWList规则文件\n# 格式:每行一条规则\n# 例如:www.google.com\n"), 0644); err != nil {
|
||||
return fmt.Errorf("创建GFWList文件失败: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// 创建统计数据文件
|
||||
if _, err := os.Stat("data/stats.json"); os.IsNotExist(err) {
|
||||
if err := os.WriteFile("data/stats.json", []byte("{}"), 0644); err != nil {
|
||||
return fmt.Errorf("创建统计数据文件失败: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// 创建Shield统计数据文件
|
||||
if _, err := os.Stat("data/shield_stats.json"); os.IsNotExist(err) {
|
||||
if err := os.WriteFile("data/shield_stats.json", []byte("{}"), 0644); err != nil {
|
||||
return fmt.Errorf("创建Shield统计数据文件失败: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
// 命令行参数解析
|
||||
var configFile string
|
||||
flag.StringVar(&configFile, "config", "config.json", "配置文件路径")
|
||||
flag.Parse()
|
||||
|
||||
// 检查配置文件是否存在,如果不存在则创建默认配置文件
|
||||
if _, err := os.Stat(configFile); os.IsNotExist(err) {
|
||||
log.Printf("配置文件 %s 不存在,正在创建默认配置文件...", configFile)
|
||||
if err := createDefaultConfig(configFile); err != nil {
|
||||
log.Fatalf("创建默认配置文件失败: %v", err)
|
||||
}
|
||||
log.Printf("默认配置文件 %s 创建成功", configFile)
|
||||
}
|
||||
|
||||
// 初始化配置
|
||||
var cfg *config.Config
|
||||
var err error
|
||||
cfg, err = config.LoadConfig(configFile)
|
||||
if err != nil {
|
||||
log.Fatalf("加载配置失败: %v", err)
|
||||
}
|
||||
|
||||
// 创建所需的文件和文件夹
|
||||
log.Println("正在创建所需的文件和文件夹...")
|
||||
if err := createRequiredFiles(cfg); err != nil {
|
||||
log.Fatalf("创建所需文件和文件夹失败: %v", err)
|
||||
}
|
||||
log.Println("所需文件和文件夹创建成功")
|
||||
|
||||
// 初始化日志系统
|
||||
if err := logger.InitLogger("logs/dns-server.log", cfg.Log.Level, 0, 0, 0, false); err != nil {
|
||||
log.Fatalf("初始化日志系统失败: %v", err)
|
||||
}
|
||||
defer logger.Close()
|
||||
|
||||
// 初始化屏蔽管理系统
|
||||
shieldManager := shield.NewShieldManager(&cfg.Shield)
|
||||
if err := shieldManager.LoadRules(); err != nil {
|
||||
logger.Error("加载屏蔽规则失败", "error", err)
|
||||
}
|
||||
|
||||
// 初始化GFWList管理系统
|
||||
gfwManager := gfw.NewGFWListManager(&cfg.GFWList)
|
||||
if err := gfwManager.LoadRules(); err != nil {
|
||||
logger.Error("加载GFWList规则失败", "error", err)
|
||||
}
|
||||
|
||||
// 启动DNS服务器
|
||||
dnsServer := dns.NewServer(&cfg.DNS, &cfg.Shield, shieldManager, &cfg.GFWList, gfwManager)
|
||||
go func() {
|
||||
if err := dnsServer.Start(); err != nil {
|
||||
logger.Error("DNS服务器启动失败", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}()
|
||||
|
||||
// 启动HTTP控制台服务器
|
||||
httpServer := http.NewServer(cfg, dnsServer, shieldManager, gfwManager)
|
||||
go func() {
|
||||
if err := httpServer.Start(); err != nil {
|
||||
logger.Error("HTTP控制台服务器启动失败", "error", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// 启动定时更新任务
|
||||
go shieldManager.StartAutoUpdate()
|
||||
|
||||
logger.Info(fmt.Sprintf("DNS服务器已启动,监听端口: %d", cfg.DNS.Port))
|
||||
logger.Info(fmt.Sprintf("HTTP控制台已启动,监听端口: %d", cfg.HTTP.Port))
|
||||
|
||||
// 监听信号
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-sigCh
|
||||
|
||||
// 清理资源
|
||||
logger.Info("正在关闭服务...")
|
||||
dnsServer.Stop()
|
||||
httpServer.Stop()
|
||||
shieldManager.StopAutoUpdate()
|
||||
|
||||
logger.Info("服务已关闭")
|
||||
}
|
||||
Reference in New Issue
Block a user