├── .github └── workflows │ └── go.yml ├── .idea ├── .gitignore ├── .name ├── Gofreeproxy.iml ├── modules.xml └── vcs.xml ├── config.ini ├── console └── console.go ├── fofa └── fofa.go ├── go.mod ├── go.sum ├── hunter └── hunter.go ├── image ├── img.png ├── proxyissus.png └── use.gif ├── main ├── clash.go └── main.go ├── proxy.txt ├── quake └── quake.go ├── queue └── GoroutinePool.go └── readme.md /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Build and Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Set up Go 14 | uses: actions/setup-go@v4 15 | with: 16 | go-version: 1.2.2 17 | 18 | 19 | - name: Checkout code 20 | uses: actions/checkout@v3 21 | 22 | - name: Testpwd 23 | run: go env -w GO111MODULE=on 24 | 25 | - name: GetEnv 26 | run: go env 27 | 28 | - name: Build for Windows 29 | run: GOOS=windows GOARCH=amd64 go build -o gofreeproxy-windows-amd64.exe 30 | 31 | - name: Build for Linux 32 | run: GOOS=linux GOARCH=amd64 go build -o gofreeproxy-linux-amd64 33 | 34 | - name: Build for macOS 35 | run: GOOS=darwin GOARCH=amd64 go build -o gofreeproxy-darwin-amd64 36 | - name: Zip binaries 37 | run: | 38 | zip gofreeproxy-windows-amd64.zip gofreeproxy-windows-amd64.exe 39 | zip gofreeproxy-linux-amd64.zip gofreeproxy-linux-amd64 40 | zip gofreeproxy-darwin-amd64.zip gofreeproxy-darwin-amd64 41 | 42 | - name: Create release 43 | id: create_release 44 | uses: actions/create-release@v1 45 | env: 46 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 47 | with: 48 | tag_name: ${{ github.ref }} 49 | release_name: Release ${{ github.ref }} 50 | draft: false 51 | prerelease: false 52 | 53 | - name: Upload Windows binary 54 | uses: actions/upload-release-asset@v1 55 | env: 56 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 57 | with: 58 | upload_url: ${{ steps.create_release.outputs.upload_url }} 59 | asset_path: ./gofreeproxy-windows-amd64.zip 60 | asset_name: gofreeproxy-windows-amd64.zip 61 | asset_content_type: application/zip 62 | 63 | - name: Upload Linux binary 64 | uses: actions/upload-release-asset@v1 65 | env: 66 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 67 | with: 68 | upload_url: ${{ steps.create_release.outputs.upload_url }} 69 | asset_path: ./gofreeproxy-linux-amd64.zip 70 | asset_name: gofreeproxy-linux-amd64.zip 71 | asset_content_type: application/zip 72 | 73 | - name: Upload macOS binary 74 | uses: actions/upload-release-asset@v1 75 | env: 76 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 77 | with: 78 | upload_url: ${{ steps.create_release.outputs.upload_url }} 79 | asset_path: ./gofreeproxy-darwin-amd64.zip 80 | asset_name: gofreeproxy-darwin-amd64.zip 81 | asset_content_type: application/zip 82 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # 默认忽略的文件 2 | /shelf/ 3 | /workspace.xml 4 | # Datasource local storage ignored files 5 | /dataSources/ 6 | /dataSources.local.xml 7 | # 基于编辑器的 HTTP 客户端请求 8 | /httpRequests/ 9 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | Gofreeproxy -------------------------------------------------------------------------------- /.idea/Gofreeproxy.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /config.ini: -------------------------------------------------------------------------------- 1 | Email= 2 | Fofa_token= 3 | Fofa_timeout=20 4 | Quake_token= 5 | Quake_timeout=20 6 | Hunter_token= 7 | Hunter_timeout=20 8 | Maxpage=10 -------------------------------------------------------------------------------- /console/console.go: -------------------------------------------------------------------------------- 1 | package console 2 | 3 | import ( 4 | "Gofreeproxy/fofa" 5 | "Gofreeproxy/hunter" 6 | "Gofreeproxy/quake" 7 | "Gofreeproxy/queue" 8 | "bufio" 9 | "fmt" 10 | "github.com/gookit/color" 11 | "io" 12 | "log" 13 | "math/rand" 14 | "net" 15 | "net/http" 16 | "net/url" 17 | "os" 18 | "os/exec" 19 | "runtime" 20 | "strconv" 21 | "strings" 22 | "sync" 23 | "time" 24 | ) 25 | 26 | var liveres []string 27 | 28 | func changesocks(ws *net.TCPConn) { 29 | socksproxy := liveres[rand.Intn(len(liveres))] 30 | color.RGBStyleFromString("249,134,134").Printf(fmt.Sprintf("\u001B[2K\r[+]当前使用代理%s", socksproxy)) 31 | defer ws.Close() 32 | //socks, err := net.Dial("tcp", "221.217.53.107:1080") 33 | socks, err := net.DialTimeout("tcp", socksproxy, 5*time.Second) 34 | //socks, err := net.Dial("tcp", socksproxy) 35 | if err != nil { 36 | log.Println("dial socks error:", err) 37 | for i := 0; i < len(liveres); i++ { 38 | if liveres[i] == socksproxy { 39 | liveres = append(liveres[:i], liveres[i+1:]...) 40 | } 41 | } 42 | changesocks(ws) 43 | return 44 | } 45 | defer socks.Close() 46 | var wg sync.WaitGroup 47 | ioCopy := func(dst io.Writer, src io.Reader) { 48 | defer wg.Done() 49 | io.Copy(dst, src) 50 | } 51 | wg.Add(2) 52 | go ioCopy(socks, ws) 53 | go ioCopy(ws, socks) 54 | wg.Wait() 55 | } 56 | 57 | func RemoveDuplicates(arr []string) []string { 58 | encountered := map[string]bool{} // 用于记录已经遇到的元素 59 | result := []string{} // 存储去重后的结果 60 | 61 | for _, value := range arr { 62 | if !encountered[value] { 63 | encountered[value] = true 64 | result = append(result, value) 65 | } 66 | } 67 | 68 | return result 69 | } 70 | func Strartsocks(port, host string) { 71 | listener, err := net.Listen("tcp", host+":"+port) 72 | if err != nil { 73 | log.Fatal(err) 74 | } 75 | optSys := runtime.GOOS 76 | if strings.Contains(optSys, "linux") || strings.Contains(optSys, "darwin") { 77 | //执行clear指令清除控制台 78 | cmd := exec.Command("clear") 79 | cmd.Stdout = os.Stdout 80 | err = cmd.Run() 81 | if err != nil { 82 | log.Println("cmd:", err) 83 | } 84 | } else { 85 | //执行clear指令清除控制台 86 | cmd := exec.Command("cmd", "/c", "cls") 87 | cmd.Stdout = os.Stdout 88 | err = cmd.Run() 89 | if err != nil { 90 | log.Println("cmd:", err) 91 | } 92 | } 93 | color.RGBStyleFromString("237,64,35").Printf("[+]一共获取存活代理:%d条\r\n", len(liveres)) 94 | color.RGBStyleFromString("237,64,35").Println("[+]开始监听socks端口: " + host + ":" + port) 95 | 96 | for { 97 | conn, err := listener.Accept() 98 | if err != nil { 99 | continue 100 | } 101 | go changesocks(conn.(*net.TCPConn)) 102 | } 103 | } 104 | func IsProxy(proxyIp string, Time int) (isProxy bool) { 105 | proxyUrl := fmt.Sprintf("socks5://%s", proxyIp) 106 | proxy, err := url.Parse(proxyUrl) 107 | if err != nil { 108 | return false 109 | } 110 | netTransport := &http.Transport{ 111 | Proxy: http.ProxyURL(proxy), 112 | } 113 | client := &http.Client{ 114 | Timeout: time.Duration(Time) * time.Second, //设置连接超时时间 115 | Transport: netTransport, 116 | } 117 | 118 | res, err := client.Get("http://myip.ipip.net") 119 | if err != nil { 120 | return false 121 | } else { 122 | defer res.Body.Close() 123 | if res.StatusCode == 200 { 124 | body, err := io.ReadAll(res.Body) 125 | if err == nil && strings.Contains(string(body), "当前 IP") { 126 | fmt.Printf("\u001B[2K\r[+]%s", string(body)) 127 | return true 128 | } else { 129 | return false 130 | } 131 | } else { 132 | return false 133 | } 134 | } 135 | } 136 | 137 | func Startgetsocks(Coroutine int, Time int, useFofa bool, useQuake bool, useHunter bool, renew bool) { 138 | GETRES := []string{} 139 | if useFofa { 140 | fofakeys := "protocol=\"socks5\" && \"Method:No Authentication(0x00)\"" 141 | FOFA := fofa.Fafaall(fofakeys) 142 | GETRES = append(GETRES, FOFA...) 143 | color.RGBStyleFromString("237,64,35").Printf("[+]从fofa获取代理:%d条", len(FOFA)) 144 | } 145 | if useQuake { 146 | quakekeys := "service:\"socks5\" and response:\"Accepted Auth Method: 0x0\"" 147 | QUAKE := quake.Quakeall(quakekeys) 148 | GETRES = append(GETRES, QUAKE...) 149 | color.RGBStyleFromString("237,64,35").Printf("[+]从hunter获取代理:%d条", len(QUAKE)) 150 | } 151 | if useHunter { 152 | hunterkeys := "protocol==\"socks5\"&&protocol.banner=\"Method: 0x00 (No authentication)\"" 153 | HUNTER := hunter.Hunterall(hunterkeys) 154 | GETRES = append(GETRES, HUNTER...) 155 | color.RGBStyleFromString("237,64,35").Printf("[+]从hunter获取代理:%d条", len(HUNTER)) 156 | } 157 | color.RGBStyleFromString("244,211,49").Println("\r\n[+]开始存活性检测") 158 | GETRES = RemoveDuplicates(GETRES) 159 | pool := queue.New(Coroutine) 160 | currentdata := 0 161 | tempsocks := "" 162 | fmt.Print("\033[s") 163 | for i := 0; i < len(GETRES); i++ { 164 | pool.Add(1) 165 | tempsocks = GETRES[i] 166 | go func(tempsocks string) { 167 | flag := IsProxy(tempsocks, Time) 168 | if flag == true { 169 | liveres = append(liveres, tempsocks) 170 | } 171 | currentdata = currentdata + 1 172 | pool.Done() 173 | fmt.Printf("\u001B[2K\r[+]已检测%.2f%%,当前检测IP为:%s", float32(currentdata*100)/float32(len(GETRES)), tempsocks) 174 | }(tempsocks) 175 | 176 | } 177 | 178 | pool.Wait() 179 | fmt.Println("总共获取到代理地址:" + strconv.Itoa(len(GETRES))) 180 | Writeproxytxt(liveres, renew) 181 | } 182 | 183 | func Readfileproxy(Coroutine int, Time int) { 184 | var fileproxy []string 185 | fi, err := os.Open("proxy.txt") 186 | if err != nil { 187 | log.Println(err) 188 | } 189 | 190 | // 创建 Reader 191 | r := bufio.NewReader(fi) 192 | for { 193 | line, err := r.ReadString('\n') 194 | line = strings.TrimSpace(line) 195 | if err != nil && err != io.EOF { 196 | log.Println(err) 197 | } 198 | if err == io.EOF { 199 | break 200 | } 201 | fileproxy = append(fileproxy, line) 202 | } 203 | fileproxy = RemoveDuplicates(fileproxy) 204 | pool := queue.New(Coroutine) 205 | currentdata := 0 206 | tempsocks := "" 207 | fmt.Print("\033[s") 208 | for i := 0; i < len(fileproxy); i++ { 209 | pool.Add(1) 210 | tempsocks = fileproxy[i] 211 | go func(tempsocks string) { 212 | //lag := sockslivecheck(tempsocks, client, req) 213 | flag := IsProxy(tempsocks, Time) 214 | if flag == true { 215 | liveres = append(liveres, tempsocks) 216 | } 217 | currentdata = currentdata + 1 218 | pool.Done() 219 | fmt.Printf("\u001B[2K\r[+]已检测%.2f%%,%s", float32(currentdata*100)/float32(len(fileproxy)), "当前检测IP:"+tempsocks) 220 | }(tempsocks) 221 | 222 | } 223 | 224 | pool.Wait() 225 | color.RGBStyleFromString("237,64,35").Printf("[+]一共获取存活代理:%d条", len(liveres)) 226 | fmt.Println(liveres) 227 | } 228 | func Writeproxytxt(livesocks []string, renew bool) (flag bool) { 229 | var file *os.File 230 | var err error 231 | if renew { 232 | file, err = os.OpenFile("proxy.txt", os.O_WRONLY|os.O_CREATE, 0666) 233 | } else { 234 | file, err = os.OpenFile("proxy.txt", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666) 235 | } 236 | // 指定模式打开文件 追加 文件不存在则创建 237 | 238 | // 打开异常检测 239 | if err != nil { 240 | fmt.Printf("open file failed, err: %v\n", err) 241 | return false 242 | } 243 | 244 | // 延后关闭文件 245 | defer func(file *os.File) { 246 | err = file.Close() 247 | if err != nil { 248 | fmt.Printf("close file failed, err: %v\n", err) 249 | return 250 | } 251 | }(file) 252 | // 方式一 以二进制形式 写入数据到文件 253 | for i := 0; i < len(livesocks); i++ { 254 | _, err = file.Write([]byte(livesocks[i] + "\n")) 255 | if err != nil { 256 | return false 257 | } 258 | } 259 | return true 260 | } 261 | -------------------------------------------------------------------------------- /fofa/fofa.go: -------------------------------------------------------------------------------- 1 | package fofa 2 | 3 | import ( 4 | "bufio" 5 | "crypto/tls" 6 | "encoding/base64" 7 | "encoding/json" 8 | "fmt" 9 | "github.com/gookit/color" 10 | "io" 11 | "log" 12 | "net/http" 13 | "os" 14 | "path/filepath" 15 | "reflect" 16 | "runtime" 17 | "strconv" 18 | "strings" 19 | "time" 20 | ) 21 | 22 | type Config struct { 23 | Email string 24 | Hunter_token string 25 | Quake_token string 26 | Quake_timeout string 27 | Hunter_timeout string 28 | Fofa_token string 29 | Fofa_timeout string 30 | Maxpage string 31 | } 32 | 33 | type AutoGenerated struct { 34 | Mode string `json:"mode"` 35 | Error bool `json:"error"` 36 | Query string `json:"query"` 37 | Page int `json:"page"` 38 | Size int `json:"size"` 39 | Results [][]string `json:"results"` 40 | } 41 | 42 | // 获取当前执行程序所在的绝对路径 43 | func GetCurrentAbPathByExecutable() string { 44 | exePath, err := os.Executable() 45 | if err != nil { 46 | log.Fatal(err) 47 | } 48 | res, _ := filepath.EvalSymlinks(filepath.Dir(exePath)) 49 | return res 50 | } 51 | 52 | func GetConfig() Config { 53 | //创建一个空的结构体,将本地文件读取的信息放入 54 | c := &Config{} 55 | //创建一个结构体变量的反射 56 | cr := reflect.ValueOf(c).Elem() 57 | //打开文件io流 58 | optSys := runtime.GOOS 59 | path := "" 60 | if optSys == "windows" { 61 | path = GetCurrentAbPathByExecutable() + "\\config.ini" 62 | } else { 63 | path = GetCurrentAbPathByExecutable() + "/config.ini" 64 | } 65 | f, err := os.Open(path) 66 | if err != nil { 67 | //log.Fatal(err) 68 | color.RGBStyleFromString("244,211,49").Println("[Error] Fofa configuration file error!!!") 69 | os.Exit(1) 70 | } 71 | defer func() { 72 | if err = f.Close(); err != nil { 73 | log.Fatal(err) 74 | } 75 | }() 76 | //我们要逐行读取文件内容 77 | s := bufio.NewScanner(f) 78 | for s.Scan() { 79 | //以=分割,前面为key,后面为value 80 | var str = s.Text() 81 | var index = strings.Index(str, "=") 82 | var key = str[0:index] 83 | var value = str[index+1:] 84 | //通过反射将字段设置进去 85 | cr.FieldByName(key).Set(reflect.ValueOf(value)) 86 | } 87 | err = s.Err() 88 | if err != nil { 89 | log.Fatal(err) 90 | } 91 | //返回Config结构体变量 92 | return *c 93 | } 94 | 95 | func fofa_api(keyword string, email string, key string, page int, size int) string { 96 | input := []byte(keyword) 97 | encodeString := base64.StdEncoding.EncodeToString(input) 98 | api_request := fmt.Sprintf("https://fofa.info/api/v1/search/all?email=%s&page=%d&size=%d&key=%s&qbase64=%s&fields=ip,host,title,port,protocol", strings.Trim(email, " "), page, size, strings.Trim(key, " "), encodeString) 99 | return api_request 100 | } 101 | 102 | func fofahttp(url string, timeout string) *AutoGenerated { 103 | var itime, err = strconv.Atoi(timeout) 104 | if err != nil { 105 | log.Println("fofa超时参数错误: ", err) 106 | } 107 | transport := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}} 108 | client := &http.Client{ 109 | Timeout: time.Duration(itime) * time.Second, 110 | Transport: transport, 111 | } 112 | req, err := http.NewRequest("GET", url, nil) 113 | if err != nil { 114 | log.Fatal(err) 115 | } 116 | req.Header.Set("Accept", "*/*;q=0.8") 117 | req.Header.Set("Connection", "close") 118 | req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36") 119 | resp, err := client.Do(req) 120 | if err != nil { 121 | log.Fatal(err) 122 | } 123 | defer resp.Body.Close() 124 | result, _ := io.ReadAll(resp.Body) 125 | res := &AutoGenerated{} 126 | json.Unmarshal(result, &res) 127 | return res 128 | } 129 | 130 | func Fafaall(keyword string) (urls []string) { 131 | color.RGBStyleFromString("244,211,49").Println("请耐心等待fofa搜索......") 132 | fofa := GetConfig() 133 | url := fofa_api(keyword, fofa.Email, fofa.Fofa_token, 1, 1000) 134 | res := fofahttp(url, fofa.Fofa_timeout) 135 | pagelength := res.Size/1000 + 1 136 | for _, value := range res.Results { 137 | urls = append(urls, value[1]) 138 | } 139 | Maxpage, _ := strconv.Atoi(fofa.Maxpage) 140 | if pagelength > 1 { 141 | for i := 2; i <= pagelength && i <= Maxpage; i++ { 142 | fmt.Println("正在请求第" + strconv.Itoa(i) + "页数据") 143 | url = fofa_api(keyword, fofa.Email, fofa.Fofa_token, i, 1000) 144 | res = fofahttp(url, fofa.Fofa_timeout) 145 | if len(res.Results) > 0 { 146 | for _, value := range res.Results { 147 | urls = append(urls, value[1]) 148 | } 149 | } 150 | } 151 | } 152 | 153 | return urls 154 | } 155 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module Gofreeproxy 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/briandowns/spinner v1.19.0 7 | github.com/gookit/color v1.5.1 8 | gopkg.in/yaml.v2 v2.4.0 9 | ) 10 | 11 | require ( 12 | github.com/fatih/color v1.7.0 // indirect 13 | github.com/mattn/go-colorable v0.1.2 // indirect 14 | github.com/mattn/go-isatty v0.0.8 // indirect 15 | github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect 16 | golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect 17 | ) 18 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/briandowns/spinner v1.19.0 h1:s8aq38H+Qju89yhp89b4iIiMzMm8YN3p6vGpwyh/a8E= 2 | github.com/briandowns/spinner v1.19.0/go.mod h1:mQak9GHqbspjC/5iUx3qMlIho8xBS/ppAL/hX5SmPJU= 3 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 4 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= 6 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= 7 | github.com/gookit/color v1.5.1 h1:Vjg2VEcdHpwq+oY63s/ksHrgJYCTo0bwWvmmYWdE9fQ= 8 | github.com/gookit/color v1.5.1/go.mod h1:wZFzea4X8qN6vHOSP2apMb4/+w/orMznEzYsIHPaqKM= 9 | github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= 10 | github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 11 | github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= 12 | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 13 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 14 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 15 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 16 | github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= 17 | github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= 18 | github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= 19 | github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= 20 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 21 | golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 22 | golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg= 23 | golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 24 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 25 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 26 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 27 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 28 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 29 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 30 | -------------------------------------------------------------------------------- /hunter/hunter.go: -------------------------------------------------------------------------------- 1 | package hunter 2 | 3 | import ( 4 | "bufio" 5 | "crypto/tls" 6 | "encoding/base64" 7 | "encoding/json" 8 | "fmt" 9 | "github.com/gookit/color" 10 | "io" 11 | "log" 12 | "net/http" 13 | "os" 14 | "path/filepath" 15 | "reflect" 16 | "runtime" 17 | "strconv" 18 | "strings" 19 | "time" 20 | ) 21 | 22 | type Config struct { 23 | Email string 24 | Hunter_token string 25 | Quake_token string 26 | Quake_timeout string 27 | Hunter_timeout string 28 | Fofa_token string 29 | Fofa_timeout string 30 | Maxpage string 31 | } 32 | 33 | type AutoGenerated struct { 34 | Code int `json:"code"` 35 | Data struct { 36 | AccountType string `json:"account_type"` 37 | Total int `json:"total"` 38 | Time int `json:"time"` 39 | Arr []struct { 40 | IsRisk string `json:"is_risk"` 41 | Url string `json:"url"` 42 | Ip string `json:"ip"` 43 | Port int `json:"port"` 44 | WebTitle string `json:"web_title"` 45 | Domain string `json:"domain"` 46 | IsRiskProtocol string `json:"is_risk_protocol"` 47 | Protocol string `json:"protocol"` 48 | BaseProtocol string `json:"base_protocol"` 49 | StatusCode int `json:"status_code"` 50 | Component interface{} `json:"component"` 51 | Os string `json:"os"` 52 | Company string `json:"company"` 53 | Number string `json:"number"` 54 | Country string `json:"country"` 55 | Province string `json:"province"` 56 | City string `json:"city"` 57 | UpdatedAt string `json:"updated_at"` 58 | IsWeb string `json:"is_web"` 59 | AsOrg string `json:"as_org"` 60 | Isp string `json:"isp"` 61 | Banner string `json:"banner"` 62 | } `json:"arr"` 63 | ConsumeQuota string `json:"consume_quota"` 64 | RestQuota string `json:"rest_quota"` 65 | SyntaxPrompt string `json:"syntax_prompt"` 66 | } `json:"data"` 67 | Message string `json:"message"` 68 | } 69 | 70 | // 获取当前执行程序所在的绝对路径 71 | func GetCurrentAbPathByExecutable() string { 72 | exePath, err := os.Executable() 73 | if err != nil { 74 | log.Fatal(err) 75 | } 76 | res, _ := filepath.EvalSymlinks(filepath.Dir(exePath)) 77 | return res 78 | } 79 | 80 | func GetConfig() Config { 81 | //创建一个空的结构体,将本地文件读取的信息放入 82 | c := &Config{} 83 | //创建一个结构体变量的反射 84 | cr := reflect.ValueOf(c).Elem() 85 | //打开文件io流 86 | optSys := runtime.GOOS 87 | path := "" 88 | if optSys == "windows" { 89 | path = GetCurrentAbPathByExecutable() + "\\config.ini" 90 | } else { 91 | path = GetCurrentAbPathByExecutable() + "/config.ini" 92 | } 93 | f, err := os.Open(path) 94 | if err != nil { 95 | //log.Fatal(err) 96 | color.RGBStyleFromString("244,211,49").Println("[Error] Hunter configuration file error!!!") 97 | os.Exit(1) 98 | } 99 | defer func() { 100 | if err = f.Close(); err != nil { 101 | log.Fatal(err) 102 | } 103 | }() 104 | //我们要逐行读取文件内容 105 | s := bufio.NewScanner(f) 106 | for s.Scan() { 107 | //以=分割,前面为key,后面为value 108 | var str = s.Text() 109 | var index = strings.Index(str, "=") 110 | var key = str[0:index] 111 | var value = str[index+1:] 112 | //通过反射将字段设置进去 113 | cr.FieldByName(key).Set(reflect.ValueOf(value)) 114 | } 115 | err = s.Err() 116 | if err != nil { 117 | log.Fatal(err) 118 | } 119 | //返回Config结构体变量 120 | return *c 121 | } 122 | 123 | func hunter_api(keyword string, key string, page int, size int) string { 124 | input := []byte(keyword) 125 | encodeString := base64.StdEncoding.EncodeToString(input) 126 | nowTime := time.Now() 127 | endtime := nowTime.Format("2006-01-02") 128 | starttime := nowTime.AddDate(0, -1, 0).Format("2006-01-02") 129 | api_request := fmt.Sprintf("https://hunter.qianxin.com/openApi/search?api-key=%s&search=%s&page=%s&page_size=%s&is_web=3&port_filter=false&start_time=%s&end_time=%s", strings.Trim(key, " "), encodeString, strconv.Itoa(page), strconv.Itoa(size), starttime, endtime) 130 | return api_request 131 | } 132 | 133 | func hunterhttp(url string, timeout string) *AutoGenerated { 134 | var itime, err = strconv.Atoi(timeout) 135 | if err != nil { 136 | log.Println("hunter超时参数错误: ", err) 137 | } 138 | transport := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}} 139 | client := &http.Client{ 140 | Timeout: time.Duration(itime) * time.Second, 141 | Transport: transport, 142 | } 143 | req, err := http.NewRequest("GET", url, nil) 144 | if err != nil { 145 | log.Fatal(err) 146 | } 147 | req.Header.Set("Accept", "*/*;q=0.8") 148 | req.Header.Set("Connection", "close") 149 | req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36") 150 | resp, err := client.Do(req) 151 | if err != nil { 152 | log.Fatal(err) 153 | } 154 | defer resp.Body.Close() 155 | result, _ := io.ReadAll(resp.Body) 156 | res := &AutoGenerated{} 157 | json.Unmarshal(result, &res) 158 | return res 159 | } 160 | 161 | func Hunterall(keyword string) (urls []string) { 162 | color.RGBStyleFromString("244,211,49").Println("请耐心等待hunter搜索......") 163 | hunter := GetConfig() 164 | url := hunter_api(keyword, hunter.Hunter_token, 1, 100) 165 | res := hunterhttp(url, hunter.Hunter_timeout) 166 | pagelength := res.Data.Total/100 + 1 167 | for _, value := range res.Data.Arr { 168 | urls = append(urls, value.Ip+":"+strconv.Itoa(value.Port)) 169 | } 170 | Maxpage, _ := strconv.Atoi(hunter.Maxpage) 171 | if pagelength > 1 { 172 | for i := 2; i <= pagelength && i <= Maxpage*10; i++ { 173 | fmt.Println("正在请求第" + strconv.Itoa(i) + "页数据") 174 | url = hunter_api(keyword, hunter.Hunter_token, i, 100) 175 | res = hunterhttp(url, hunter.Hunter_timeout) 176 | if len(res.Data.Arr) > 0 { 177 | for _, value := range res.Data.Arr { 178 | urls = append(urls, value.Ip+":"+strconv.Itoa(value.Port)) 179 | } 180 | } 181 | } 182 | } 183 | 184 | return urls 185 | } 186 | -------------------------------------------------------------------------------- /image/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ja9er/Gofreeproxy/868c974131bd0e1805c4317394ab58e0b10c78fe/image/img.png -------------------------------------------------------------------------------- /image/proxyissus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ja9er/Gofreeproxy/868c974131bd0e1805c4317394ab58e0b10c78fe/image/proxyissus.png -------------------------------------------------------------------------------- /image/use.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ja9er/Gofreeproxy/868c974131bd0e1805c4317394ab58e0b10c78fe/image/use.gif -------------------------------------------------------------------------------- /main/clash.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "gopkg.in/yaml.v2" 6 | "io/ioutil" 7 | "log" 8 | ) 9 | 10 | func checkError(err error) { 11 | if err != nil { 12 | log.Println(err) 13 | } 14 | } 15 | 16 | // 代理节点 17 | type nodes struct { 18 | Nodename string `yaml:"name"` 19 | Nodeport int `yaml:"port"` 20 | NodeServer string `yaml:"server"` 21 | Nodetype string `yaml:"type"` 22 | } 23 | 24 | // 代理组 25 | type proxy_groups struct { 26 | Name string `yaml:"name"` 27 | Interval int `yaml:"interval"` 28 | Node []string `yaml:"proxies"` 29 | Strategy string `yaml:"strategy"` 30 | Type string `yaml:"type"` 31 | Url string `yaml:"url"` 32 | } 33 | 34 | // 基础配置 35 | type setconf struct { 36 | Allowlan bool `yaml:"allow-lan"` 37 | Port int `yaml:"port"` 38 | Socksport int `yaml:"socks-port"` 39 | Redirport int `yaml:"redir-port"` 40 | Mode string `yaml:"mode"` 41 | Loglevel string `yaml:"log-level"` 42 | Externalcontroller string `yaml:"external-controller"` 43 | Proxies []nodes `yaml:"proxies"` 44 | Proxygroup []proxy_groups `yaml:"proxy-groups"` 45 | Rules []string `yaml:"rules"` 46 | } 47 | 48 | // 写入yaml 49 | func writeToXml(src string, Nodeall []nodes) { 50 | fmt.Printf("v: %v\n", Nodeall) 51 | stu := &setconf{ 52 | Allowlan: true, 53 | Port: 7890, 54 | Socksport: 7891, 55 | Redirport: 7892, 56 | Mode: "global", 57 | Loglevel: "info", 58 | Externalcontroller: "127.0.0.1:9090", 59 | Proxies: Nodeall, 60 | Proxygroup: []proxy_groups{{ 61 | "负载模式", 100, []string{"测试节点1", "测试节点2"}, 62 | "round-robin", "load-balance", "https://www.baidu.com/"}}, 63 | Rules: []string{ 64 | "DOMAIN-SUFFIX,google.com,DIRECT", 65 | "DOMAIN-KEYWORD,google,DIRECT", 66 | "DOMAIN,google.com,DIRECT", 67 | "DOMAIN-SUFFIX,ad.com,REJECT", 68 | "GEOIP,CN,DIRECT", "MATCH,DIRECT"}, 69 | } 70 | data, err := yaml.Marshal(stu) 71 | checkError(err) 72 | err = ioutil.WriteFile(src, data, 0777) 73 | checkError(err) 74 | } 75 | 76 | func main() { 77 | var node = []nodes{ 78 | {"测试节点1", 7845, "8.8.8.8", "socks5"}, 79 | {"测试节点2", 7845, "8.8.8.8", "socks5"}, 80 | } 81 | //node := nodes{"2133",7845,"8.8.8.8","socks5"} 82 | src := "test1.yaml" 83 | writeToXml(src, node) 84 | } 85 | -------------------------------------------------------------------------------- /main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "Gofreeproxy/console" 5 | "flag" 6 | "fmt" 7 | ) 8 | 9 | var ( 10 | Fofa bool 11 | Quake bool 12 | Hunter bool 13 | Renew bool 14 | Port string 15 | Host string 16 | File bool 17 | Coroutine int 18 | Time int 19 | logo = " _________ ____ ____ _______ ____ _\n/ __/ _ \\/ __\\/ __\\/ _ \\ \\//\\ \\//\n| | | / \\|| \\/|| \\/|| / \\|\\ / \\ / \n| |_// \\_/|| __/| /| \\_/|/ \\ / / \n\\____\\____/\\_/ \\_/\\_\\\\____/__/\\\\/_/ \n " 20 | ) 21 | 22 | func main() { 23 | fmt.Println(logo) 24 | flag.BoolVar(&Fofa, "fofa", false, "\n使用-fofa参数可从fofa收集资产获取公开代理使用") 25 | flag.BoolVar(&Hunter, "hunter", false, "\n使用-hunter参数可从fofa收集资产获取公开代理使用") 26 | flag.BoolVar(&Quake, "quake", false, "\n使用-quake参数可从hunter收集资产获取公开代理使用") 27 | flag.StringVar(&Host, "h", "127.0.0.1", "\n使用自定义本地服务监听地址,默认为127.0.0.1") 28 | flag.BoolVar(&Renew, "renew", false, "\n当启用-fofa或-quake或-hunter参数时是否对现有proxy.txt进行重写,默认为否") 29 | flag.BoolVar(&File, "f", false, "\n使用-f参数可读取当前目录下的proxy.txt,获取其中的代理使用") 30 | flag.StringVar(&Port, "p", "1080", "\n使用-p参数自定义本地服务端口,默认为1080") 31 | flag.IntVar(&Coroutine, "c", 200, "\n使用-c参数可设置验证代理的协程数量,默认为200") 32 | flag.IntVar(&Time, "t", 10, "\n使用-t参数可设置验证代理的超时时间,默认为10秒") 33 | flag.Parse() 34 | 35 | if Fofa || Quake || Hunter { 36 | console.Startgetsocks(Coroutine, Time, Fofa, Quake, Hunter, Renew) 37 | console.Strartsocks(Port, Host) 38 | } else if File == true { 39 | console.Readfileproxy(Coroutine, Time) 40 | console.Strartsocks(Port, Host) 41 | } else { 42 | flag.Usage() 43 | fmt.Println("请输入参数") 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /proxy.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ja9er/Gofreeproxy/868c974131bd0e1805c4317394ab58e0b10c78fe/proxy.txt -------------------------------------------------------------------------------- /quake/quake.go: -------------------------------------------------------------------------------- 1 | package quake 2 | 3 | import ( 4 | "bufio" 5 | "bytes" 6 | "crypto/tls" 7 | "encoding/json" 8 | "fmt" 9 | "github.com/gookit/color" 10 | "io" 11 | "log" 12 | "net/http" 13 | "os" 14 | "path/filepath" 15 | "reflect" 16 | "runtime" 17 | "strconv" 18 | "strings" 19 | "time" 20 | ) 21 | 22 | type Config struct { 23 | Email string 24 | Hunter_token string 25 | Quake_token string 26 | Quake_timeout string 27 | Hunter_timeout string 28 | Fofa_token string 29 | Fofa_timeout string 30 | Maxpage string 31 | } 32 | 33 | type QuakeData struct { 34 | Query string `json:"query"` 35 | Start int `json:"start"` 36 | Size int `json:"size"` 37 | } 38 | 39 | type AutoGenerated struct { 40 | Code int `json:"code"` 41 | Message string `json:"message"` 42 | Data []struct { 43 | Hostname string `json:"hostname"` 44 | Org string `json:"org"` 45 | Port int `json:"port"` 46 | Service struct { 47 | Response string `json:"response"` 48 | ResponseHash string `json:"response_hash"` 49 | Name string `json:"name"` 50 | Version string `json:"version"` 51 | Socks5 struct { 52 | AuthAcceptedMethod string `json:"auth_accepted_method"` 53 | Version int `json:"version"` 54 | } `json:"socks5"` 55 | } `json:"service"` 56 | Ip string `json:"ip"` 57 | OsVersion string `json:"os_version"` 58 | OsName string `json:"os_name"` 59 | Location struct { 60 | Owner string `json:"owner"` 61 | ProvinceCn string `json:"province_cn"` 62 | ProvinceEn string `json:"province_en"` 63 | Isp string `json:"isp"` 64 | CountryEn string `json:"country_en"` 65 | DistrictCn string `json:"district_cn"` 66 | Gps []float64 `json:"gps"` 67 | StreetCn string `json:"street_cn"` 68 | CityEn string `json:"city_en"` 69 | DistrictEn string `json:"district_en"` 70 | CountryCn string `json:"country_cn"` 71 | StreetEn string `json:"street_en"` 72 | CityCn string `json:"city_cn"` 73 | CountryCode string `json:"country_code"` 74 | Asname string `json:"asname"` 75 | SceneCn string `json:"scene_cn"` 76 | SceneEn string `json:"scene_en"` 77 | Radius int `json:"radius"` 78 | } `json:"location"` 79 | IsIpv6 bool `json:"is_ipv6"` 80 | Transport string `json:"transport"` 81 | Time time.Time `json:"time"` 82 | Asn int `json:"asn"` 83 | } `json:"data"` 84 | Meta struct { 85 | Pagination struct { 86 | Count int `json:"count"` 87 | PageIndex int `json:"page_index"` 88 | PageSize int `json:"page_size"` 89 | Total int `json:"total"` 90 | } `json:"pagination"` 91 | } `json:"meta"` 92 | } 93 | 94 | // 获取当前执行程序所在的绝对路径 95 | func GetCurrentAbPathByExecutable() string { 96 | exePath, err := os.Executable() 97 | if err != nil { 98 | log.Fatal(err) 99 | } 100 | res, _ := filepath.EvalSymlinks(filepath.Dir(exePath)) 101 | return res 102 | } 103 | 104 | func GetConfig() Config { 105 | //创建一个空的结构体,将本地文件读取的信息放入 106 | c := &Config{} 107 | //创建一个结构体变量的反射 108 | cr := reflect.ValueOf(c).Elem() 109 | //打开文件io流 110 | optSys := runtime.GOOS 111 | path := "" 112 | if optSys == "windows" { 113 | path = GetCurrentAbPathByExecutable() + "\\config.ini" 114 | } else { 115 | path = GetCurrentAbPathByExecutable() + "/config.ini" 116 | } 117 | f, err := os.Open(path) 118 | if err != nil { 119 | //log.Fatal(err) 120 | color.RGBStyleFromString("244,211,49").Println("[Error] Quake configuration file error!!!") 121 | os.Exit(1) 122 | } 123 | defer func() { 124 | if err = f.Close(); err != nil { 125 | log.Fatal(err) 126 | } 127 | }() 128 | //我们要逐行读取文件内容 129 | s := bufio.NewScanner(f) 130 | for s.Scan() { 131 | //以=分割,前面为key,后面为value 132 | var str = s.Text() 133 | var index = strings.Index(str, "=") 134 | var key = str[0:index] 135 | var value = str[index+1:] 136 | //通过反射将字段设置进去 137 | cr.FieldByName(key).Set(reflect.ValueOf(value)) 138 | } 139 | err = s.Err() 140 | if err != nil { 141 | log.Fatal(err) 142 | } 143 | //返回Config结构体变量 144 | return *c 145 | } 146 | 147 | func quake_api(keyword string, start int, size int) QuakeData { 148 | reqData := QuakeData{} 149 | reqData.Query = keyword 150 | reqData.Start = start 151 | reqData.Size = size 152 | 153 | return reqData 154 | } 155 | 156 | func quakehttp(postdata QuakeData, key string, timeout string) *AutoGenerated { 157 | var itime, err = strconv.Atoi(timeout) 158 | if err != nil { 159 | log.Println("quake超时参数错误: ", err) 160 | } 161 | transport := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}} 162 | client := &http.Client{ 163 | Timeout: time.Duration(itime) * time.Second, 164 | Transport: transport, 165 | } 166 | url := "https://quake.360.cn/api/v3/search/quake_service" 167 | payload, _ := json.Marshal(postdata) 168 | req, err := http.NewRequest("POST", url, bytes.NewBuffer(payload)) 169 | if err != nil { 170 | log.Fatal(err) 171 | } 172 | req.Header.Set("content-type", "application/json") 173 | req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36") 174 | req.Header.Set("X-QuakeToken", key) 175 | resp, err := client.Do(req) 176 | if err != nil { 177 | log.Fatal(err) 178 | } 179 | defer resp.Body.Close() 180 | result, _ := io.ReadAll(resp.Body) 181 | res := &AutoGenerated{} 182 | json.Unmarshal(result, &res) 183 | return res 184 | } 185 | 186 | func Quakeall(keyword string) (urls []string) { 187 | color.RGBStyleFromString("244,211,49").Println("请耐心等待quake搜索......") 188 | quake := GetConfig() 189 | postdata := quake_api(keyword, 0, 500) 190 | res := quakehttp(postdata, quake.Quake_token, quake.Quake_timeout) 191 | pagelength := res.Meta.Pagination.Total/500 + 1 192 | for _, value := range res.Data { 193 | urls = append(urls, value.Ip+":"+strconv.Itoa(value.Port)) 194 | } 195 | Maxpage, _ := strconv.Atoi(quake.Maxpage) 196 | if pagelength > 1 { 197 | for i := 1; i <= pagelength && i <= Maxpage*2; i++ { 198 | fmt.Println("正在请求第" + strconv.Itoa(i) + "页数据") 199 | postdata = quake_api(keyword, i*500, 500) 200 | res = quakehttp(postdata, quake.Quake_token, quake.Quake_timeout) 201 | if len(res.Data) > 0 { 202 | for _, value := range res.Data { 203 | urls = append(urls, value.Ip+":"+strconv.Itoa(value.Port)) 204 | } 205 | } else { 206 | break 207 | } 208 | } 209 | } 210 | 211 | return urls 212 | } 213 | -------------------------------------------------------------------------------- /queue/GoroutinePool.go: -------------------------------------------------------------------------------- 1 | package queue 2 | 3 | import "sync" 4 | 5 | /* 6 | 协程池相关 7 | */ 8 | type Pool struct { 9 | queue chan int 10 | wg *sync.WaitGroup 11 | } 12 | 13 | // New 新建一个协程池 14 | func New(size int) *Pool { 15 | if size <= 0 { 16 | size = 1 17 | } 18 | return &Pool{ 19 | queue: make(chan int, size), 20 | wg: &sync.WaitGroup{}, 21 | } 22 | } 23 | 24 | // Add 新增一个执行 25 | func (p *Pool) Add(delta int) { 26 | // delta为正数就添加 27 | for i := 0; i < delta; i++ { 28 | p.queue <- 1 29 | } 30 | // delta为负数就减少 31 | for i := 0; i > delta; i-- { 32 | <-p.queue 33 | } 34 | p.wg.Add(delta) 35 | } 36 | 37 | // Done 执行完成减一 38 | func (p *Pool) Done() { 39 | <-p.queue 40 | p.wg.Done() 41 | } 42 | func (p *Pool) Wait() { 43 | p.wg.Wait() 44 | } 45 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Gofreeproxy ![](https://img.shields.io/badge/%E8%AF%AD%E8%A8%80-golang-brightgreen)![](https://img.shields.io/github/downloads/ja9er/Gofreeproxy/total) ![GitHub Repo stars](https://img.shields.io/github/stars/ja9er/Gofreeproxy) 2 | 3 | ## 4 | [![Stargazers over time](https://starchart.cc/ja9er/Gofreeproxy.svg)](https://starchart.cc/ja9er/Gofreeproxy) 5 | 6 | 配置好config.ini中关于fofa的参数\ 7 | usage: 8 | > -f 使用-f参数可读取当前目录下的proxy.txt,获取其中的代理使用\ 9 | -fofa 使用-fofa参数可从fofa收集资产获取公开代理使用\ 10 | > -c 使用-c参数可设置验证代理的协程数量,默认为200\ 11 | > -t 使用-t参数可设置验证代理的超时时间,默认为10秒\ 12 | > 成功后socks代理监听1080端口即可 13 | 14 | 效果: 15 | ![](image/img.png) 16 | 17 | ![](image/use.gif) 18 | 19 | 修改(bug)日志: 20 | >1.增加了自定义并发数量以及代理存活验证时间 \ 21 | 2.优化了控制台显示 \ 22 | 3.修复了从fofa获取代理卡在98%的问题,大概是因为超时机制没生效导致卡顿 \ 23 | 4.修复了mac下无法读取config.ini以及无法写入proxy.txt的问题 [[fix issues#2]](https://github.com/ja9er/Gofreeproxy/issues/2)\ 24 | 5.优化控制台显示,修复了覆盖字符串未完全的bug\ 25 | ![](image/proxyissus.png) 26 | --------------------------------------------------------------------------------