Golang SSH隧道和ProxyJump

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

Golang SSH tunneling and ProxyJump

问题

我需要执行与以下命令等效的Go代码:

ssh -L 9999:192.168.1.1:80 -J root@[IPv6地址] myuser@100.1.1.100

我甚至不确定从哪里开始。我在网上找不到任何示例,我感到困惑。

有人知道如何在Go中实现这个吗?

英文:

What I need is to perform the equivalent of the following command but in Go code:

ssh -L 9999:192.168.1.1:80 -J root@[IPv6 address] myuser@100.1.1.100

I'm not even sure where to start with this one.
I haven't been able to find any examples online and I'm at a loss.

Does anyone know how this could be done in Go?

答案1

得分: 3

package main

import (
	"io"
	"log"
	"net"

	"golang.org/x/crypto/ssh"
)

func main() {
	client, err := ssh.Dial("tcp", "100.1.1.100:22", &ssh.ClientConfig{
		User:            "root",
		Auth:            []ssh.AuthMethod{ssh.Password("")},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	})
	if err != nil {
		log.Panicln(err)
		return
	}
	log.Println("初始化 SSH 客户端")

	ln, err := net.Listen("tcp", ":9999")
	if err != nil {
		log.Panicln(err)
		return
	}
	log.Println("本地监听")

	for {
		localconn, err := ln.Accept()
		if err != nil {
			log.Panicln(err)
			return
		}

		sshconn, err := client.DialTCP("", nil, &net.TCPAddr{IP: net.ParseIP("192.168.1.1"), Port: 80})
		if err != nil {
			log.Panicln(err)
			return
		}

		// 本地 <--> 远程
		go func() {
			errc := make(chan error, 1)
			spc := switchProtocolCopier{user: localconn, backend: sshconn}
			go spc.copyToBackend(errc)
			go spc.copyFromBackend(errc)
			log.Printf("停止连接错误: %v\n", <-errc)
		}()
	}
}

// switchProtocolCopier 存在的目的是为了让代理数据的 goroutine 在堆栈中有良好的命名。
type switchProtocolCopier struct {
	user, backend io.ReadWriter
}

func (c switchProtocolCopier) copyFromBackend(errc chan<- error) {
	_, err := io.Copy(c.user, c.backend)
	errc <- err
}

func (c switchProtocolCopier) copyToBackend(errc chan<- error) {
	_, err := io.Copy(c.backend, c.user)
	errc <- err
}
英文:
package main

import (
	&quot;io&quot;
	&quot;log&quot;
	&quot;net&quot;

	&quot;golang.org/x/crypto/ssh&quot;
)

func main() {
	client, err := ssh.Dial(&quot;tcp&quot;, &quot;100.1.1.100:22&quot;, &amp;ssh.ClientConfig{
		User:            &quot;root&quot;,
		Auth:            []ssh.AuthMethod{ssh.Password(&quot;&quot;)},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	})
	if err != nil {
		log.Panicln(err)
		return
	}
	log.Println(&quot;init ssh client&quot;)

	ln, err := net.Listen(&quot;tcp&quot;, &quot;:9999&quot;)
	if err != nil {
		log.Panicln(err)
		return
	}
	log.Println(&quot;local listen&quot;)

	for {
		localconn, err := ln.Accept()
		if err != nil {
			log.Panicln(err)
			return
		}

		sshconn, err := client.DialTCP(&quot;&quot;, nil, &amp;net.TCPAddr{IP: net.ParseIP(&quot;192.168.1.1&quot;), Port: 80})
		if err != nil {
			log.Panicln(err)
			return
		}

		// local &lt;--&gt; remote
		go func() {
			errc := make(chan error, 1)
			spc := switchProtocolCopier{user: localconn, backend: sshconn}
			go spc.copyToBackend(errc)
			go spc.copyFromBackend(errc)
			log.Printf(&quot;stop conn error: %v\n&quot;, &lt;-errc)
		}()
	}
}

// switchProtocolCopier exists so goroutines proxying data back and
// forth have nice names in stacks.
type switchProtocolCopier struct {
	user, backend io.ReadWriter
}

func (c switchProtocolCopier) copyFromBackend(errc chan&lt;- error) {
	_, err := io.Copy(c.user, c.backend)
	errc &lt;- err
}

func (c switchProtocolCopier) copyToBackend(errc chan&lt;- error) {
	_, err := io.Copy(c.backend, c.user)
	errc &lt;- err
}

huangapple
  • 本文由 发表于 2022年10月28日 04:31:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/74227986.html
匿名

发表评论

匿名网友

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

确定