├── .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  
2 |
3 | ##
4 | [](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 | 
16 |
17 | 
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 | 
26 |
--------------------------------------------------------------------------------