gost

  1. 使用gost进行vps/内网穿透
  2. vps
    1. Sever端
    2. Client端
    3. go脚本
  3. 内网穿透

使用gost进行vps/内网穿透

项目地址:

go-gost/gost: GO Simple Tunnel - a simple tunnel written in golang

官方文档: 快速开始 - GOST

vps

Sever端

azure 上的 Linux服务器

  1. 下载 gost文件

地址为:Releases · ginuerzh/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 

内网穿透

github