diff --git a/denyip b/denyip index 97457ec..dd4271b 100644 Binary files a/denyip and b/denyip differ diff --git a/main.go b/main.go index 51a38bd..13f119b 100644 --- a/main.go +++ b/main.go @@ -48,6 +48,7 @@ var ( ProcessedIPMap = map[string]time.Time{} // 使用 map 存储已处理的 IP ProcessedMutex sync.Mutex // 互斥锁保护 ProcessedIPMap + local_ipv4_addr string ) // 启动子进程 @@ -237,7 +238,7 @@ func InitMap() { } func WriteLocalAddr() { - local_ipv4_addr := GetLocalIpv4Addr() // 本机地址 + local_ipv4_addr = GetLocalIpv4Addr() // 本机地址 // 将本机外网地址加入到已处理集合中 if local_ipv4_addr != "NULL" { //log.Printf("\033[33m %s 本机地址 \033[0m\n", ipStr) @@ -323,6 +324,10 @@ func RunMainProcess() { // 主进程逻辑 if !strings.Contains(position, "中国") && !strings.Contains(position, "内网") { // API 判断为国外 AddIPSet(IPSET_NAME, ipStr) // 添加 IP 到 ipset 集合 + + // 钉钉告警,废弃!钉钉可能限制文本长度,和发送次数! + // warning(ipStr, position) // 警告 IP 地域 + } else { log.Printf("\033[33m %s 离线库为国外, API 判断为国内, 标记为已处理\033[0m\n", ipStr) diff --git a/warning.go b/warning.go new file mode 100644 index 0000000..31dc5fd --- /dev/null +++ b/warning.go @@ -0,0 +1,83 @@ +package main + +import ( + "bytes" + "encoding/json" + "io" + "log" + "net/http" + "sync" + "time" +) + +var ( + WarningList = make(map[string]string) // 存储 IP 和位置的映射 + WarningListLock = sync.RWMutex{} + + dingtalkWebhook = "https://oapi.dingtalk.com/robot/send?access_token=7f069c672cb878987aa6772cca336740eece4ce36bde12b51b45e9f440e0565a" // 替换为你的 token +) + +// 发送钉钉 Markdown 消息 +func sendDingTalkMessage(title, text string) { + if len(text) > 1900 { + text = text[:1900] + "\n...(内容过长,已截断)" + } + + msg := map[string]interface{}{ + "msgtype": "markdown", + "markdown": map[string]string{ + "title": title, + "text": "### Warning " + title + "\n" + text, + }, + } + + jsonData, err := json.Marshal(msg) + if err != nil { + log.Println("JSON 编码失败:", err) + return + } + + client := &http.Client{Timeout: 5 * time.Second} + resp, err := client.Post(dingtalkWebhook, "application/json", bytes.NewBuffer(jsonData)) + if err != nil { + log.Println("发送钉钉消息失败:", err) + return + } + defer resp.Body.Close() + + body, _ := io.ReadAll(resp.Body) + var result map[string]interface{} + if err := json.Unmarshal(body, &result); err != nil { + log.Println("解析钉钉响应失败:", err) + return + } + + if result["errcode"].(float64) != 0 { + log.Println("钉钉返回错误:", result["errmsg"]) + } else { + log.Println("钉钉告警已发送成功") + } +} + +func warning(ipStr string, position string) { + WarningListLock.Lock() + defer WarningListLock.Unlock() + + WarningList[ipStr] = position + + if len(WarningList) == 1000 { + var content string + for ip, pos := range WarningList { + line := "- " + ip + ", " + pos + "\n" + content += line + log.Println(ip, pos) + } + + log.Println("警告列表已满,发送钉钉告警并清空 map") + + //go sendDingTalkMessage("⚠️ 告警列表达到上限"+local_ipv4_addr, content) + + // 清空 map + WarningList = make(map[string]string) + } +}