diff --git a/conf/conf.go b/conf/conf.go index 990cd7d..07d1975 100644 --- a/conf/conf.go +++ b/conf/conf.go @@ -1,12 +1,5 @@ package conf -import ( - "encoding/json" - "fmt" - "os" - "strings" -) - // DNSRecord 用于构造 DNS 记录的 JSON 结构体 type DNSRecord struct { ZoneID string `json:"ZoneID"` @@ -32,12 +25,13 @@ type OneRes struct { type Mata struct { Target string + PS string `json:"ps"` Main DNSRecord Then DNSRecord } type cf struct { - ApiKey string + ApiKey string `json:"cf_api_key"` ZoneID string BotToken string ChatID string @@ -47,22 +41,3 @@ type cf struct { } var Config cf - -func init() { - // 读取配置文件 - file, err := os.Open("mata.json") - if err != nil { - fmt.Println("mata.json配置文件不存在") - os.Exit(0) - } - defer file.Close() - - // 解码 JSON - decoder := json.NewDecoder(file) - err = decoder.Decode(&Config) - if err != nil { - fmt.Println("mata.json配置文件错误") - os.Exit(0) - } - Config.TgApiUrl = strings.TrimRight(Config.TgApiUrl, "/") -} diff --git a/main.go b/main.go index faffe14..a58a76f 100644 --- a/main.go +++ b/main.go @@ -1,8 +1,12 @@ package main import ( + "encoding/json" "flag" + "fmt" "log" + "os" + "strings" "time" "csz.net/mata/conf" @@ -14,7 +18,10 @@ var Once bool func main() { for { for _, mata := range conf.Config.Mata { - log.Println("开始检测" + mata.Target) + if mata.PS == "" { + mata.PS = mata.Target + } + log.Println("开始检测" + mata.PS) send := false msg := "服务器在线" onlineCount := 0 @@ -39,6 +46,10 @@ func main() { } else { msg = "服务器离线" log.Println(msg) + if mata.Then.ZoneID == "" { + // 不填写then的zoneid则默认为main的zoneid + mata.Then.ZoneID = mata.Main.ZoneID + } ok, dns := utils.GetDnsRecoid(mata.Then.Name, mata.Then.ZoneID) if ok && dns.Content != mata.Then.Content { send = true @@ -47,7 +58,7 @@ func main() { } } if send && conf.Config.BotToken != "" && conf.Config.ChatID != "" { - msg = "【" + mata.Target + "】" + msg + msg = "【" + mata.PS + "】" + msg go utils.SendMessage("#MATA " + msg) } } @@ -59,8 +70,28 @@ func main() { } func init() { once := flag.Bool("once", false, "Run once") + configPath := flag.String("config", "mata.json", "Config file path") flag.Parse() if *once { Once = true } + configInit(*configPath) +} +func configInit(path string) { + // 读取配置文件 + file, err := os.Open(path) + if err != nil { + fmt.Println(path + "配置文件不存在") + os.Exit(0) + } + defer file.Close() + + // 解码 JSON + decoder := json.NewDecoder(file) + err = decoder.Decode(&conf.Config) + if err != nil { + fmt.Println(path + "配置文件错误") + os.Exit(0) + } + conf.Config.TgApiUrl = strings.TrimRight(conf.Config.TgApiUrl, "/") } diff --git a/mata.sample.json b/mata.sample.json index 66890ac..92af074 100644 --- a/mata.sample.json +++ b/mata.sample.json @@ -1,5 +1,5 @@ { - "ApiKey": "", + "cf_api_key": "", "BotToken": "", "ChatID": "", "TgApiUrl": "https://api.telegram.org", @@ -7,6 +7,7 @@ "Mata": [ { "Target": "1.1.1.1:80", + "ps": "csz.net", "Main": { "ZoneID": "", "Type": "A", diff --git a/utils/utils.go b/utils/utils.go index bac2e43..7fd84fe 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -7,12 +7,23 @@ import ( "io/ioutil" "net" "net/http" + "strings" "time" "csz.net/mata/conf" ) -func Check(address string, timeout time.Duration) bool { +// imcp check +func Ping(address string, timeout time.Duration) bool { + conn, err := net.DialTimeout("ip4:icmp", address, timeout) + if err != nil { + return false + } + defer conn.Close() + return true +} + +func Tcp(address string, timeout time.Duration) bool { conn, err := net.DialTimeout("tcp", address, timeout) if err != nil { return false // 连接失败 @@ -20,64 +31,56 @@ func Check(address string, timeout time.Duration) bool { defer conn.Close() // 确保关闭连接 return true // 连接成功 } +func Check(address string, timeout time.Duration) bool { + if strings.ContainsAny(address, ":") { + return Tcp(address, timeout) + } + return Ping(address, timeout) +} func Dns(record conf.DNSRecord, recordID string, ZoneID string) bool { - url := "https://api.cloudflare.com/client/v4/zones/" + ZoneID + "/dns_records/" + recordID - recordBytes, err := json.Marshal(record) if err != nil { fmt.Println("Error marshalling DNS record:", err) return false } - req, err := http.NewRequest("PATCH", url, bytes.NewBuffer(recordBytes)) - if err != nil { return false } - req.Header.Add("Content-Type", "application/json") req.Header.Add("Authorization", "Bearer "+conf.Config.ApiKey) - http.DefaultClient.Do(req) - return true } func GetDnsRecoid(recoid string, ZoneID string) (bool, conf.OneRes) { var no conf.OneRes url := "https://api.cloudflare.com/client/v4/zones/" + ZoneID + "/dns_records" - req, err := http.NewRequest("GET", url, nil) if err != nil { return false, no } - req.Header.Add("Content-Type", "application/json") req.Header.Add("Authorization", "Bearer "+conf.Config.ApiKey) - res, err := http.DefaultClient.Do(req) if err != nil { return false, no } - defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { return false, no } var result conf.RecoidRes - err = json.Unmarshal(body, &result) if err != nil { return false, no } - if !result.Success { return false, no } - for _, record := range result.Result { if record.Name == recoid { return true, record @@ -94,9 +97,7 @@ func SendMessage(text string) { fmt.Println("Error creating request: ", err) return } - req.Header.Set("Content-Type", "application/json") - client := &http.Client{} resp, err := client.Do(req) if err != nil { @@ -104,7 +105,6 @@ func SendMessage(text string) { return } defer resp.Body.Close() - if resp.StatusCode != http.StatusOK { fmt.Println("Error: ", resp.Status) } else {