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

huangapple go评论76阅读模式
英文:

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中有没有实现这个的方法?

英文:

I used to use a batch script to create an SSH tunnel that would be usable as a socks5 proxy. Today, I thought I'd implement it in Go, both to learn the language and to remove the need for me to constantly run a batch script file whenever the connection drops.

Right now, how I do this is to use plink. The command to do this with plink is:

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

And here is my Go code:

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()
}

I would like to make this application self-contained, so that it doesn't rely on the existence of plink.exe to work.

Is there a way to achieve this in Go?

答案1

得分: 0

这可能不是最理想的方法,但你可以很容易地使用https://github.com/jteeuwen/go-bindata和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()
    }
}

这段代码会将plink.exe文件的内容加载到programBytes中,然后使用byteexec.New创建一个可执行程序对象be。接下来,使用be.Command创建一个命令对象cmd,并传入相应的参数。最后,使用cmd.CombinedOutput运行命令并获取输出结果。如果运行出错,会打印错误信息并重新运行runPlink函数。

英文:

This might not be ideal, but you could pretty easily use a combination of https://github.com/jteeuwen/go-bindata and https://github.com/getlantern/byteexec - essentially you would embed the plink executable inside of your own executable, then load it and run it with something like:

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()
    }
}

huangapple
  • 本文由 发表于 2015年10月24日 02:25:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/33309089.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定