英文:
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 (
	"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("init ssh client")
	ln, err := net.Listen("tcp", ":9999")
	if err != nil {
		log.Panicln(err)
		return
	}
	log.Println("local listen")
	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
		}
		// local <--> remote
		go func() {
			errc := make(chan error, 1)
			spc := switchProtocolCopier{user: localconn, backend: sshconn}
			go spc.copyToBackend(errc)
			go spc.copyFromBackend(errc)
			log.Printf("stop conn error: %v\n", <-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<- 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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论