go小工具实现翻墙
Sep 17, 2016
最近在学习go, go语言给我最爽的是build后成一个文件, 无需额外的环境以来, 这对发布简直就爽歪歪了。
边学边玩的态度, 写了一个go小工具, 基于shawsocks页面实现自动翻墙。
原理分析
go中
net/http
去获取http://www.ishadowsocks.org/
页面内容。使用
regexp
包正则匹配主机, 端口, 密码等信息。构建shadowscoks配置文件结构, 自动写入到gui-config.json文件中。
重启shadowscoks, 是刚写好的gui-config.json生效。
以下是代码部分, 刚学, 多指教, 勿喷。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os/exec"
"regexp"
"strconv"
)
type GuiConfigStruct struct { // 定义gui-config结构
Configs []ServerItemStruct `json:"configs"`
Strategy *bool `json:"strategy"`
Index int `json:"index"`
Global bool `json:"global"`
Enabled bool `json:"enabled"`
ShareOverLan bool `json:"shareOverlan"`
IsDefault bool `json:"isDefault"`
LocalPort int `json:"localPort"`
PacUrl *string `json:"pacUrl"`
UseOnlinePac bool `json:"useOnlinePac"`
AvailabilityStatistics bool `json:"availabilityStatistics"`
}
type ServerItemStruct struct {
Server string `json:"server"`
Server_port int `json:"server_port"`
Password string `json:"password"`
Method string `json:"method"`
Remarks string `json:"remarks"`
}
type RemoteHostPortPassword struct { // 匹配远程页面主机, 端口, 密码
Host string
Port int
Password string
}
const SHADOWSOCKS_URL = "http://www.ishadowsocks.org/"
func main() {
//stopShadowsocks() // 关闭shadowscoks进程, 未成功.. 使用RunHiddenConsole.exe 执行start.bat来关闭
var contents string = httpGetUrl(SHADOWSOCKS_URL) // 获取远程页面内容
remoteHostPortPassword := matchHostAndPassword(contents) // 匹配主机,端口,密码
fmt.Println(remoteHostPortPassword)
defaultConfig := getGuiConfig() // 获取gui-config.json结构
rebuildConfig(&remoteHostPortPassword, &defaultConfig) // 重新赋远程获取的值
jsonBytes, err := json.Marshal(&defaultConfig)
if err != nil {
fmt.Println(err)
return
}
ioutil.WriteFile("gui-config.json", jsonBytes, 0777) // 写入gui-config.json文件
startShadowsocks() // 启动shadowocks进程
}
func stopShadowsocks() {
command := exec.Command("taskkill /F /IM shadowsocks.exe")
if err := command.Run(); err != nil {
fmt.Println(err)
}
}
func startShadowsocks() {
command := exec.Command("cmd", "/C", "shadowsocks.exe")
if err := command.Run(); err != nil {
fmt.Println(err)
}
}
func rebuildConfig(remoteHostPortPassword *RemoteHostPortPassword, guiConfig *GuiConfigStruct) {
guiConfig.Configs[0].Server = remoteHostPortPassword.Host
guiConfig.Configs[0].Server_port = remoteHostPortPassword.Port
guiConfig.Configs[0].Password = remoteHostPortPassword.Password
}
func httpGetUrl(url string) string {
response, error := http.Get(url)
if error != nil {
log.Fatal(error)
}
contents, error := ioutil.ReadAll(response.Body)
response.Body.Close()
if error != nil {
log.Fatal(error)
}
return string(contents)
}
func matchHostAndPassword(body string) RemoteHostPortPassword {
regexObj := regexp.MustCompile("C服务器地址:(?P<ip>\\w*\\.\\w*\\.\\w*).*\\n.*端口:(?P<port>\\d*).*\\n.*C密码:(?P<pwd>\\d*)")
matchArray := regexObj.FindStringSubmatch(body)
var matchLength int = len(matchArray)
resultSet := new(RemoteHostPortPassword)
if matchLength == 4 {
resultSet.Host = matchArray[1]
intPort, err := strconv.Atoi(matchArray[2])
if err != nil {
fmt.Println(err)
}
resultSet.Port = intPort
resultSet.Password = matchArray[3]
}
return *resultSet
}
func getGuiConfig() GuiConfigStruct {
/*
c, error := ioutil.ReadFile("gui-config.json")
if error != nil {
log.Fatal(error)
}
*/
var defaultConfig = GuiConfigStruct{
Strategy: nil,
Index: 0,
Global: false,
Enabled: true,
ShareOverLan: false,
IsDefault: false,
LocalPort: 1080,
PacUrl: nil,
UseOnlinePac: false,
AvailabilityStatistics: false,
}
defaultConfig.Configs = make([]ServerItemStruct, 1)
defaultConfig.Configs[0] = ServerItemStruct{
Server: "jp3.iss.tf",
Server_port: 10000,
Password: "luowen",
Method: "aes-256-cfb",
Remarks: "",
}
return defaultConfig
}