使用gost进行vps/内网穿透
项目地址:
go-gost/gost: GO Simple Tunnel - a simple tunnel written in golang
官方文档: 快速开始 - GOST
vps
Sever端
azure 上的 Linux服务器
- 下载 gost文件
wget https://github.com/ginuerzh/gost/releases/download/v2.12.0/gost_2.12.0_linux_amd64.tar.gz
# 加解压
tar -xzvf gost_2.12.0_linux_amd64.tar.gz -C ../scr/
启动Linux端服务的命令
screen -S gost
/home/azureuser/my_vpn/scr/gost -L mwss://账号:密码@IP地址:2123
设置开机自启动
在 azure 上设置定时开关机可以减少费用,反正有白嫖时长,不用白不用
sudo vi /etc/systemd/system/myrun.service
编写相应的服务
[Unit]
Description=Run my script at boot
[Service]
Type=simple
ExecStart=/bin/bash /home/youruser/run.sh
Restart=on-failure
User=youruser
[Install]
WantedBy=multi-user.target
赋予你的脚本执行权
chmod +x /home/youruser/run.sh
启用并启动服务:
sudo systemctl daemon-reload
sudo systemctl enable myrun
sudo systemctl start myrun
Client端
下载预编译版本,或手动编译
gost -L=:6666 -F=mwss://账号:密码@xx.xx.xx.xx.99:2123
go脚本
使用go编写一个简单的启动脚本在 windows 上使用
自动启动代理转发
package main
import (
"fmt"
"os"
"os/exec"
"os/signal"
"syscall"
"gopkg.in/yaml.v2"
)
// Config 结构体对应 config.yml
type Config struct {
VPNPort int `yaml:"vpn_port"`
JPIP string `yaml:"jp_ip"`
RemoteServerPort int `yaml:"remote_server_port"`
RemoteUserName string `yaml:"remote_user_name"`
RemoteUserPasswd string `yaml:"remote_user_passwd"`
}
func setProxy(port int) error {
addr := fmt.Sprintf("127.0.0.1:%d", port)
cmd := exec.Command("reg", "add", "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", "/v", "ProxyEnable", "/t", "REG_DWORD", "/d", "1", "/f")
if err := cmd.Run(); err != nil {
return err
}
cmd = exec.Command("reg", "add", "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", "/v", "ProxyServer", "/t", "REG_SZ", "/d", addr, "/f")
return cmd.Run()
}
func unsetProxy() error {
cmd := exec.Command("reg", "add", "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", "/v", "ProxyEnable", "/t", "REG_DWORD", "/d", "0", "/f")
return cmd.Run()
}
func setGitProxy(port int) error {
addr := fmt.Sprintf("http://127.0.0.1:%d", port)
cmd := exec.Command("git", "config", "--global", "http.proxy", addr)
if err := cmd.Run(); err != nil {
return err
}
cmd = exec.Command("git", "config", "--global", "https.proxy", addr)
return cmd.Run()
}
func unsetGitProxy() error {
cmd := exec.Command("git", "config", "--global", "--unset", "http.proxy")
cmd.Run() // 忽略错误,可能未设置
cmd = exec.Command("git", "config", "--global", "--unset", "https.proxy")
cmd.Run()
return nil
}
func main() {
// 读取配置文件
// configData, err := ioutil.ReadFile("config.yml")
configData, err := os.ReadFile("config.yml")
if err != nil {
fmt.Println("读取配置文件失败:", err)
return
}
var cfg Config
if err := yaml.Unmarshal(configData, &cfg); err != nil {
fmt.Println("解析配置文件失败:", err)
return
}
port := cfg.VPNPort
ip := cfg.JPIP
user := cfg.RemoteUserName
passwd := cfg.RemoteUserPasswd
remotePort := cfg.RemoteServerPort
fmt.Println("使用的IP:", ip)
// 1. 设置系统代理
if err := setProxy(port); err != nil {
fmt.Println("设置代理失败:", err)
return
}
fmt.Printf("系统代理已启用: 127.0.0.1:%d\n", port)
// 1.1 设置git全局代理
if err := setGitProxy(port); err != nil {
fmt.Println("设置git代理失败:", err)
return
}
fmt.Println("git全局代理已启用")
// 信号处理,确保中断时关闭代理
sigs := make(chan os.Signal, 1)
done := make(chan struct{})
signal.Notify(sigs, os.Interrupt, syscall.SIGTERM, syscall.SIGINT)
go func() {
<-sigs
fmt.Println("\n检测到中断信号,正在关闭系统代理和git代理...")
unsetProxy()
unsetGitProxy()
close(done)
}()
// 2. 启动gost(前台运行,退出后再关闭代理)
gostArg := fmt.Sprintf("-F=mwss://%s:%s@%s:%d", user, passwd, ip, remotePort)
cmd := exec.Command("./gost", fmt.Sprintf("-L=:%d", port), gostArg)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
if err := cmd.Run(); err != nil {
fmt.Println("gost 运行出错:", err)
}
// 3. 关闭系统代理和git代理(正常退出时)
// 如果是正常退出(非信号),done 还未关闭,需要手动关闭代理
select {
case <-done:
// 已经通过信号关闭,无需重复
default:
unsetProxy()
unsetGitProxy()
fmt.Println("系统代理和git代理已关闭")
close(done)
}
}
# 本地的vpn端口
vpn_port: xxx
# 远程服务器端口
jp_ip: xxx
remote_server_port: xxx
# 远程服务器的用户名
remote_user_name: xxx
remote_user_passwd: xxx