diff --git a/curl.go b/curl.go index 31930a0..373c81a 100644 --- a/curl.go +++ b/curl.go @@ -10,82 +10,106 @@ import ( "time" ) -type IPInfo struct { - Msg string `json:"msg"` - Data struct { - Continent string `json:"continent"` - Country string `json:"country"` - } `json:"data"` +// Response 结构体用于存储整个JSON响应 +type JSON struct { + Code string `json:"code"` + Data Data `json:"data"` + IP string `json:"ip"` +} + +// Data 结构体用于存储"data"字段下的详细信息 +type Data struct { + Continent string `json:"continent"` + Country string `json:"country"` + Zipcode string `json:"zipcode"` + Owner string `json:"owner"` + Isp string `json:"isp"` + Adcode string `json:"adcode"` + Prov string `json:"prov"` + City string `json:"city"` + District string `json:"district"` } func isValidIP(ip string) bool { return net.ParseIP(ip) != nil } -func curl_(ip string) (string, error) { +func curl_(IP_ADDR string) (string, error) { + var ( + err error + URL_ADDR string - var err error - var url string + HTTP_RESP *http.Response + HTTP_Request *http.Request + HTTP_BODY []byte + HTTP_CLIENT *http.Client + HTPP_JSON JSON + ) - if !isValidIP(ip) { - log.Printf("无效的 IP 地址: %s", ip) + if !isValidIP(IP_ADDR) { + log.Printf("无效的 IP 地址: %s", IP_ADDR) } // 目标 URL - url = "https://qifu.baidu.com/ip/geo/v1/district?ip=" + ip + URL_ADDR = "https://qifu.baidu.com/ip/geo/v1/district?ip=" + IP_ADDR // 创建 HTTP 请求 - req, err := http.NewRequest("GET", url, nil) + HTTP_Request, err = http.NewRequest("GET", URL_ADDR, nil) if err != nil { log.Printf("创建请求时出错: %v", err) } // 设置请求头 - req.Header.Set("User-Agent", "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Mobile Safari/537.36") - req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7") - req.Header.Set("Accept-Encoding", "gzip, deflate, br, zstd") - req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8") - req.Header.Set("Cache-Control", "max-age=0") - req.Header.Set("Connection", "keep-alive") - req.Header.Set("Cookie", "BIDUPSID=04922F7E0DDC6A5B7E0BA15C33FD2176; PSTM=1722408897; BAIDUID=8313999060289847CAE0A6F34A9C4206:FG=1; Hm_lvt_edc762f9f8f5f525fad4770a32b5edda=1724987641; Hm_lvt_28a17f66627d87f1d046eae152a1c93d=1724987645; AGL_USER_ID=186badbd-dd36-4d39-89f4-8d2aa7a01414; BDUSS=1pvWmdhYThIelRSS1NuQkJESHNYV0REcG9teXMxOW9VaURTU2tyRlZTZ3Z4dmhtRVFBQUFBJCQAAAAAAAAAAAEAAADGRkRexaPT8cHrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC850WYvOdFmM") - req.Header.Set("Host", "qifu.baidu.com") - req.Header.Set("Sec-Ch-Ua", `"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"`) - req.Header.Set("Sec-Ch-Ua-Mobile", "?1") - req.Header.Set("Sec-Ch-Ua-Platform", `"Android"`) - req.Header.Set("Sec-Fetch-Dest", "document") - req.Header.Set("Sec-Fetch-Mode", "navigate") - req.Header.Set("Sec-Fetch-Site", "none") - req.Header.Set("Sec-Fetch-User", "?1") - req.Header.Set("Upgrade-Insecure-Requests", "1") + HTTP_Request.Header.Set("User-Agent", "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Mobile Safari/537.36") + HTTP_Request.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7") + HTTP_Request.Header.Set("Accept-Encoding", "gzip, deflate, br, zstd") + HTTP_Request.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8") + HTTP_Request.Header.Set("Cache-Control", "max-age=0") + HTTP_Request.Header.Set("Connection", "keep-alive") + HTTP_Request.Header.Set("Cookie", "BIDUPSID=04922F7E0DDC6A5B7E0BA15C33FD2176; PSTM=1722408897; BAIDUID=8313999060289847CAE0A6F34A9C4206:FG=1; Hm_lvt_edc762f9f8f5f525fad4770a32b5edda=1724987641; Hm_lvt_28a17f66627d87f1d046eae152a1c93d=1724987645; AGL_USER_ID=186badbd-dd36-4d39-89f4-8d2aa7a01414; BDUSS=1pvWmdhYThIelRSS1NuQkJESHNYV0REcG9teXMxOW9VaURTU2tyRlZTZ3Z4dmhtRVFBQUFBJCQAAAAAAAAAAAEAAADGRkRexaPT8cHrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC850WYvOdFmM") + HTTP_Request.Header.Set("Host", "qifu.baidu.com") + HTTP_Request.Header.Set("Sec-Ch-Ua", `"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"`) + HTTP_Request.Header.Set("Sec-Ch-Ua-Mobile", "?1") + HTTP_Request.Header.Set("Sec-Ch-Ua-Platform", `"Android"`) + HTTP_Request.Header.Set("Sec-Fetch-Dest", "document") + HTTP_Request.Header.Set("Sec-Fetch-Mode", "navigate") + HTTP_Request.Header.Set("Sec-Fetch-Site", "none") + HTTP_Request.Header.Set("Sec-Fetch-User", "?1") + HTTP_Request.Header.Set("Upgrade-Insecure-Requests", "1") // 创建 HTTP 客户端并设置超时时间 - client := &http.Client{Timeout: 10 * time.Second} + HTTP_CLIENT = &http.Client{Timeout: 10 * time.Second} // 发送请求 - resp, err := client.Do(req) + HTTP_RESP, err = HTTP_CLIENT.Do(HTTP_Request) if err != nil { log.Printf("发送请求时出错: %v", err) } - defer resp.Body.Close() + defer HTTP_RESP.Body.Close() // 检查 HTTP 响应状态码 - if resp.StatusCode != http.StatusOK { - log.Printf("HTTP 请求失败,状态码: %d", resp.StatusCode) + if HTTP_RESP.StatusCode != http.StatusOK { + log.Printf("HTTP 请求失败,状态码: %d", HTTP_RESP.StatusCode) } // 读取响应体 - body, err := io.ReadAll(resp.Body) + HTTP_BODY, err = io.ReadAll(HTTP_RESP.Body) if err != nil { log.Printf("读取响应体时出错: %v", err) } // 解析 JSON 数据 - var ipInfo IPInfo - if err := json.Unmarshal(body, &ipInfo); err != nil { - log.Printf("解析 JSON 时出错: %v", err) + err = json.Unmarshal(HTTP_BODY, &HTPP_JSON) + if err != nil { + fmt.Println("Error parsing JSON:", err) } + /* + if HTPP_JSON.Code == "Success" { + fmt.Printf("%s%s\n", HTPP_JSON.Data.Continent, HTPP_JSON.Data.Country) + } else { + fmt.Printf("Error!\n") + } + */ - //fmt.Printf("%s%s\n", ipInfo.Data.Continent, ipInfo.Data.Country) - - return fmt.Sprintf("%s%s\n", ipInfo.Data.Continent, ipInfo.Data.Country), err + return fmt.Sprintf("%s%s\n", HTPP_JSON.Data.Continent, HTPP_JSON.Data.Country), err } diff --git a/denyip b/denyip index 7dae176..35111c1 100644 Binary files a/denyip and b/denyip differ diff --git a/ip2region.go b/ip2region.go index 932e44d..0dcd7b5 100644 --- a/ip2region.go +++ b/ip2region.go @@ -14,7 +14,6 @@ func ip2region(ip string) (string, error) { } defer searcher.Close() - // 备注:并发使用,每个 goroutine 需要创建一个独立的 searcher 对象。 // 1、从 dbPath 加载整个 xdb 到内存 @@ -34,9 +33,6 @@ func ip2region(ip string) (string, error) { fmt.Printf("failed to SearchIP(%s): %s\n", ip, err) } - //tStart := time.Time{} - //fmt.Printf("{region: %s, took: %s}\n", region, time.Since(tStart)) - // 备注:并发使用,用整个 xdb 缓存创建的 searcher 对象可以安全用于并发。 return region, err diff --git a/ipset.go b/ipset.go index 8313c5d..48d64ae 100644 --- a/ipset.go +++ b/ipset.go @@ -80,6 +80,7 @@ func IsIpset(setName string) int { return 0 } +// 添加 Iptables 规则 func iptables_add(setName string) error { cmd := exec.Command("sh", "-c", fmt.Sprintf("iptables -A INPUT -p tcp -m set --match-set %s src -j DROP", setName)) @@ -97,6 +98,7 @@ func iptables_add(setName string) error { return err } +// 删除 Iptables 规则 func iptables_del(setName string) error { cmd := exec.Command("sh", "-c", fmt.Sprintf("iptables -D INPUT -p tcp -m set --match-set %s src -j DROP", setName)) @@ -114,6 +116,24 @@ func iptables_del(setName string) error { return err } +// 打印 Iptables 规则 +func iptables_list() error { + cmd := exec.Command("sh", "-c", "iptables -L -v -n --line-numbers") + + var stdout, stderr bytes.Buffer + cmd.Stdout = &stdout + cmd.Stderr = &stderr + + err := cmd.Run() + if err != nil { + log.Printf("cmd.Run() failed with %v, stderr: %s\n", err, stderr.String()) + err = fmt.Errorf("failed to execute command: %w, stderr: %s", err, stderr.String()) + } + + fmt.Print(stdout.String()) + return err +} + /* func main() { // 创建 IPSet,但即使出错也继续执行 diff --git a/main.go b/main.go index 562fb15..0c0955e 100644 --- a/main.go +++ b/main.go @@ -132,8 +132,6 @@ func startDaemon() { // 子进程逻辑 func runChildProcess() { - fmt.Println("子进程启动中...") - sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) @@ -146,8 +144,7 @@ func runChildProcess() { fmt.Printf("子进程收到信号: %v,准备退出...\n", sig) return case <-ticker.C: - fmt.Println("子进程正在运行...") - fmt.Println("子进程接收到的参数:", os.Args) + } } } @@ -175,11 +172,10 @@ func runMainProcess() { // 主进程逻辑 for { IpMutex.Lock() // 锁定互斥锁 if IpList.Len() > 0 { // 链表不为空 - e1 := IpList.Front() // 获取链表第一个元素 + e1 := IpList.Front() // 获取链表第一个元素 + region, _ := ip2region(e1.Value.(net.IP).String()) // 离线Ip位置库初步判断地域 - region, _ := ip2region(e1.Value.(net.IP).String()) - - log.Printf("当前 Ipset 链 %s %d\n", IPSET_NAME, func() int { + log.Printf("当前 Ipset 链 %s %d\n", IPSET_NAME, func() int { // 打印 当前 Ipset 链长度 _len, _err := NumIPSet(IPSET_NAME) if _err == nil { return _len @@ -191,8 +187,8 @@ func runMainProcess() { // 主进程逻辑 if position, err := curl_(e1.Value.(net.IP).String()); err != nil { //判断地域 log.Printf("获取Ip地域出错: %v", err) } else { - log.Printf("curl_ %s 位置 %s\n", e1.Value.(net.IP).String(), position) // 打印地域 - AddIPSet(IPSET_NAME, e1.Value.(net.IP).String()) // 添加 Ip 到 ipset 集合 + log.Printf("\033[31m%s %s\033[0m\n", e1.Value.(net.IP).String(), position) // 打印地域 + AddIPSet(IPSET_NAME, e1.Value.(net.IP).String()) // 添加 Ip 到 ipset 集合 IpList.Remove(e1) // 移除第一个元素 } @@ -247,10 +243,9 @@ func handleCmd() { flag.BoolVar(&InterfacesList, "l", false, "列出可用的网络接口") Protocol = flag.String("f", "tcp", "指定 BPF 过滤器") PcapFile = flag.String("o", "", "保存捕获数据的输出文件(可选)") - flag.StringVar(&instruction, "s", "", "-s start 启动 Iptables 规则\n-s stop 停止 Iptables 规则") + flag.StringVar(&instruction, "s", "", "-s start 启动 Iptables 规则\n-s stop 停止 Iptables 规则\n-s list 打印 Iptables 规则") flag.BoolVar(&help, "h", false, "") flag.BoolVar(&help, "help", false, "帮助信息") - flag.Parse() if help { @@ -261,6 +256,7 @@ func handleCmd() { "\tDate: 20250102\n") flag.Usage() + fmt.Printf("\n") os.Exit(0) } @@ -281,6 +277,12 @@ func handleCmd() { iptables_del(_name) } os.Exit(0) + case "l": + fallthrough + case "list": + fmt.Println("打印 Iptables 规则") + _ = iptables_list() + os.Exit(0) default: log.Fatalf("未知的操作: %s. 请使用 'start' 或 'stop'.", instruction) }