有没有办法在 Go 中进行基于袜子的动态端口转发,就像 SSH 中的 -d 开关一样?

Is there a way to do dynamic socks-based port forwarding in Go, like the -d switch in SSH?

我曾经使用批处理脚本创建可用作 socks5 代理的 SSH 隧道。今天,我想我会在 Go 中实现它,既是为了学习这门语言,也是为了消除我在连接断开时不断地 运行 批处理脚本文件的需要。

现在,我的做法是使用 plink。使用 plink 执行此操作的命令是:

plink -N -C -D 8888 -pw password username@example.com

这是我的 Go 代码:

package main

import (
    "os"
    "os/exec"
    "log"
)

func runPlink() {
    command := exec.Command("plink.exe", "-N", "-C", "-D", "8888", "-pw", "password", "username@example.com")

    if output, err := command.CombinedOutput(); err != nil {
        log.Println(string(output), err.Error())
        runPlink()
    }
}

func main() {
    if _, err := os.Stat("plink.exe"); os.IsNotExist(err) {
        log.Fatalln("Cannot find plink.exe. Please copy it next to this application.")
    }

    runPlink()
}

我想让这个应用程序独立,这样它就不会依赖 plink.exe 的存在来工作。

有没有办法在 Go 中实现这个?

这可能不理想,但您可以很容易地使用 https://github.com/jteeuwen/go-bindata and https://github.com/getlantern/byteexec 的组合 - 本质上您可以将 plink 可执行文件嵌入到您自己的可执行文件中,然后加载它并 运行类似于:

func runPlink() {
    programBytes, err := Asset("plink.exe")
    be, err := byteexec.New(programBytes)
    if err != nil {
        log.Fatalf("Uh oh: %s", err)
    }
    cmd := be.Command("-N", "-C", "-D", "8888", "-pw", "password", "username@example.com")
    if output, err := cmd.CombinedOutput(); err != nil {
        log.Println(string(output), err.Error())
        runPlink()
    }
}