diff --git a/config.json b/config.json index fb9608f..08f8ad7 100644 --- a/config.json +++ b/config.json @@ -44,7 +44,7 @@ "customBlockIP": "", "statsFile": "./data/shield_stats.json", "statsSaveInterval": 60, - "remoteRulesCacheDir": "./data/remote_rules" + "remoteRulesCacheDir": "data/remote_rules" }, "log": { "file": "logs/dns-server.log", diff --git a/main.go b/main.go index 9f1e7d9..c0e86b4 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( "log" "os" "os/signal" + "path/filepath" "syscall" "dns-server/config" @@ -15,6 +16,122 @@ import ( "dns-server/shield" ) +// createDefaultConfig 创建默认配置文件 +func createDefaultConfig(configFile string) error { + // 默认配置内容 + defaultConfig := `{ + "dns": { + "port": 53, + "upstreamDNS": [ + "223.5.5.5:53", + "223.6.6.6:53" + ], + "timeout": 5000, + "statsFile": "./data/stats.json", + "saveInterval": 300 + }, + "http": { + "port": 8080, + "host": "0.0.0.0", + "enableAPI": true + }, + "shield": { + "localRulesFile": "data/rules.txt", + "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, + "hostsFile": "data/hosts.txt", + "blockMethod": "NXDOMAIN", + "customBlockIP": "", + "statsFile": "./data/shield_stats.json", + "statsSaveInterval": 60, + "remoteRulesCacheDir": "./data/remote_rules" + }, + "log": { + "file": "logs/dns-server.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(cfg.Shield.RemoteRulesCacheDir, 0755); err != nil { + return fmt.Errorf("创建远程规则缓存文件夹失败: %w", err) + } + + // 创建日志文件夹 + logDir := filepath.Dir(cfg.Log.File) + if logDir != "." { + if err := os.MkdirAll(logDir, 0755); err != nil { + return fmt.Errorf("创建日志文件夹失败: %w", err) + } + } + + // 创建本地规则文件 + if _, err := os.Stat(cfg.Shield.LocalRulesFile); os.IsNotExist(err) { + if err := os.WriteFile(cfg.Shield.LocalRulesFile, []byte("# 本地规则文件\n# 格式:域名\n# 例如:example.com\n"), 0644); err != nil { + return fmt.Errorf("创建本地规则文件失败: %w", err) + } + } + + // 创建Hosts文件 + if _, err := os.Stat(cfg.Shield.HostsFile); os.IsNotExist(err) { + if err := os.WriteFile(cfg.Shield.HostsFile, []byte("# Hosts文件\n# 格式:IP 域名\n# 例如:127.0.0.1 localhost\n"), 0644); err != nil { + return fmt.Errorf("创建Hosts文件失败: %w", err) + } + } + + // 创建统计数据文件 + if _, err := os.Stat(cfg.DNS.StatsFile); os.IsNotExist(err) { + if err := os.WriteFile(cfg.DNS.StatsFile, []byte("{}"), 0644); err != nil { + return fmt.Errorf("创建统计数据文件失败: %w", err) + } + } + + // 创建Shield统计数据文件 + if _, err := os.Stat(cfg.Shield.StatsFile); os.IsNotExist(err) { + if err := os.WriteFile(cfg.Shield.StatsFile, []byte("{}"), 0644); err != nil { + return fmt.Errorf("创建Shield统计数据文件失败: %w", err) + } + } + + return nil +} + func main() { // 命令行参数解析 var configFile string @@ -32,6 +149,15 @@ func main() { os.Exit(0) } + // 检查配置文件是否存在,如果不存在则创建默认配置文件 + 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 @@ -40,6 +166,13 @@ func main() { log.Fatalf("加载配置失败: %v", err) } + // 创建所需的文件和文件夹 + log.Println("正在创建所需的文件和文件夹...") + if err := createRequiredFiles(cfg); err != nil { + log.Fatalf("创建所需文件和文件夹失败: %v", err) + } + log.Println("所需文件和文件夹创建成功") + // 初始化日志系统 if err := logger.InitLogger(cfg.Log.File, cfg.Log.Level, 0, 0, 0); err != nil { log.Fatalf("初始化日志系统失败: %v", err) @@ -99,7 +232,7 @@ func daemonize() error { return fmt.Errorf("打开/dev/null失败: %w", err) } defer nullFile.Close() - + // 重定向文件描述符 err = syscall.Dup2(int(nullFile.Fd()), int(os.Stdin.Fd())) if err != nil { @@ -113,13 +246,13 @@ func daemonize() error { if err != nil { return fmt.Errorf("重定向stderr失败: %w", err) } - + // 2. 创建新的会话和进程组 _, err = syscall.Setsid() if err != nil { return fmt.Errorf("创建新会话失败: %w", err) } - + fmt.Println("守护进程已启动") return nil } diff --git a/output/dns-server b/output/dns-server deleted file mode 100755 index 0595c67..0000000 Binary files a/output/dns-server and /dev/null differ