前言
这个工具起因是看到了 soapffz 师傅写的 《搭建本地 ip 代理池》
通过注册表修改本地代理设置,从而自动修改代理访问站点
正好这几天在学习Go,想着自己也整一个,开搞开搞
环境
Windows10 1803
Chrome 76
Go
效果
使用方法如下:
proxy.exe -u http://127.0.0.1:5010/get_all/ -t 10
会从 http://127.0.0.1:5010/get_all/ 地址抓取ip代理,然后每隔 10 秒更换新代理,遍历结束后恢复原本代理设置
帮助:
C:\Users\xxx\proxy.exe -h
Usage of proxy.exe:
-c string
-c cls 重置代理设置为自动代理
-l int
循环次数 (default 1)
-t int
自动切换代理时间间隔 (default 30)
-u string
代理 Url,例如 http://127.0.0.1:5010/get_all
github:https://github.com/Lhaihai/Go_Auto_Proxy
目前比较遗憾的是获取到的IP不一定是HTTPS,如果师傅们有资源可以自行修改下 getproxy 函数和 Proxy_Pool 结构体
获取IP代理
逛了一圈下来,觉得 proxy_pool 使用起来效果不错
github:https://github.com/jhao104/proxy_pool
作者已经制作好docker,但还需要我们自己安装redis,那就整个redis的docker吧,可以直接docker run,但如果两个docker不在同一个C段,可以加上 --net=host 让docker能访问在主机的网络,但这样明显不太安全
启动redis
docker run -d --name redisDynamic redis:latest
docker pull jhao104/proxy_pool
拿到redis的ip,修改下面的db_host参数
docker inspect redisDynamic | grep IPAddress
docker run --env db_type=REDIS --env db_host=172.17.0.3 --env db_port=6379 --env db_password= -p 5010:5010 --net=host jhao104/proxy_pool
为什么不整个docker-compose呢,多方便
version: '2'
services:
web:
image: jhao104/proxy_pool
ports:
- "5010:5010"
environment:
- db_type=REDIS
- db_host=redis
- db_port=6379
- db_password=
depends_on:
- redis
links:
- redis:redis
redis:
image: redis:latest
复制上面内容到docker-compose.yml文件里,docker-compose up -d 启动即可
然后等几分钟,访问 ip:5010 即可
通过 /get_all 接口可以拿到所有代理的Json数据
json to go 可以根据 json 数据生成对应的 struct ,十分方便
https://mholt.github.io/json-to-go/
随便起个名字,就 Proxy_Pool ,关键代码如下,这样就解析好json的代理数据了,保存在 proxys 变量里
r, err := http.Get(Url)
if err != nil{
fmt.Println("超时")
}
defer r.Body.Close()
body, err := ioutil.ReadAll(r.Body)
data := string(body)
var proxys Proxy_Pool
_ = json.Unmarshal([]byte(data), &proxys)
检查IP可用性
虽然可以自己实现走代理访问站点检测一下,但在找代理的时候发现有帮忙代理检测的接口,还检测了匿名度和延迟,真好
关键代码
rooturl := "http://www.xdaili.cn/ipagent/checkIp/ipList?"
for _, r := range proxys{
if r.FailCount == 0 {
rooturl = rooturl+"ip_ports%5B%5D="+r.Proxy+"&"
}
}
data2 := Get(rooturl)
var f ipresult
_ = json.Unmarshal([]byte(data2), &f)
proxy := StoreProxy{}
fmt.Println(len(f.RESULT))
for _, r := range f.RESULT {
//如果Anony不为空且不为透明,延时不超过1s,就保存起来
if r.Anony != "\"透明\"" && r.Anony != "" && len(r.Time) < 6 {
proxy = append(proxy,r)
fmt.Println(r)
}
}
这样就拿到一些可以用的代理了,接下来就要修改本地代理设置了
Windows 10 修改代理
一般修改代理,操作就是刚开始用burpsuite的时候,打开internet设置 -> 连接 -> 局域网设置 -> 修改代理服务器为 127.0.0.1 8080
同时 IE 代理可以通过注册表去修改,位置是
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections
默认情况下有下面两个KEY
DefaultConnectionSettings
SavedLegacySettings
DefaultConnectionSettings:保存了浏览器当前配置的连接设置
SavedLegacySettings:是DefaultConnectionSettings的副本,不是默认连接外的网络 连接使用的配置
于是DefaultConnectionSettings和SavedLegacySettings的设置时一样的
接下来分析下怎么修改 DefaultConnectionSettings
打开代理和注册表,可以看到配置脚本和IP都存在注册表的数据里面
- 每个设置间隔三个00,即
000000
- 最开始46固定,然后间隔
- 第0x04位开始的 39 16 是自增位,可以设置为00
- 第0x08位 05 是代理开关设置,然后间隔
- 第0x0C位 0C 是后面IP的长度,然后间隔
- 第0x10位 开始ip:port地址,ip信息最后一位是指下一个间隔数据的长度,即
<local>
的长度(看下一张图),然后间隔 -
<local>
后固定2B结尾,然后间隔 - 最后是自动配置脚本链接
<local>
存在表示勾选了 对于本地地址不使用代理服务器
再讲讲代理开关设置
- 0F全部开启(ALL);01全部禁用(Off)
- 03使用代理服务器(ProxyOnly);05使用自动脚本(PacOnly);
- 07使用脚本和代理(ProxyAndPac);09打开自动检测设置(D);
- 0B打开自动检测并使用代理(DIP);0D打开自动检测并使用脚本(DS);
我们主要要修改 代理开关设置,IP长度,IP:Port地址
因为是要走代理服务器,所以代理开关设置为 03
原理大概讲清楚了,下面就来用 Go 修改注册表
Go 修改注册表
Go 有封装一个修改注册表的包:golang.org/x/sys/windows/registry
官方文档在这里:https://godoc.org/golang.org/x/sys/windows/registry#Key.GetBinaryValue
比如要获取 注册表 某个key的内容
func get_DefaultConnectionSettingsValue() string{
key, err := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections`, registry.ALL_ACCESS)
defer key.Close()
if err != nil{
panic(err)
}
s, _, _ := key.GetBinaryValue(`DefaultConnectionSettings`)
d := ""
for _,x := range s{
d = d + fmt.Sprintf("%02x",x)
}
return d
}
如果要修改内容,DefaultConnectionSettings 是 Binary 类型,用SetBinaryValue函数来设置,注意传入的是 []byte 类型的内容
func (k Key) SetBinaryValue(name string, value []byte) error
于是,封装个设置代理的函数
//传入要修改keyname和16进制字符串
// data 参数 举个例子:46000000431600000500000000000000070000003c6c6f63616c3e2b000000687474703a2f2f3132372e302e3
func set_proxy(keyname string,data string){
key, err := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections`, registry.ALL_ACCESS)
defer key.Close()
if err != nil{
panic(err)
}
//把16进制字符串转为byte切片
bytedata := []byte{}
for i:=0 ; i<len(data)-2; i=i+2{
t := data[i:i+2]
n, err := strconv.ParseUint(t, 16, 32)
if err != nil {
panic(err)
}
n2 := byte(n)
bytedata = append(bytedata,n2)
}
err = key.SetBinaryValue(keyname,bytedata)
if err != nil{
panic(err)
}
fmt.Println("代理设置成功")
}
接下来只要生成相应IP的设置数据即可,关键代码如下
ip := "127.0.0.1:8080"
p1 := d[:16] //460000003A160000
switch_proxy := "03" // d[16:18]
leng := fmt.Sprintf("%02x",(len(ip))) //如果ip长度小于16,前面补0
iphex := hex.EncodeToString([]byte(ip))
data := p1 + switch_proxy + "000000" + leng + "000000" + iphex + "070000003c6c6f63616c3e2b000000"
//调用上面写好的设置代理函数
set_proxy("DefaultConnectionSettings",data)
完整代码放在github上了:https://github.com/Lhaihai/Go_Auto_Proxy
参考文章
[1] 搭建本地 ip 代理池 (完结)
[2] Windows上利用Python自动切换代理IP
https://segmentfault.com/a/1190000004315166
[3] What is DefaultConnectionSettings key?
https://blogs.msdn.microsoft.com/askie/2017/06/20/what-is-defaultconnectionsettings-key/