Golang中的简单SSH端口转发
我正在尝试使用Go通过SSH创建(稍后关闭)一个简单的TCP端口转发。我不熟悉Golang和静态类型语言。(来自Ruby。) 在终端中,我只需运行ssh-l9000:localhost:9999user@server.com这就满足了我的需要。我想用Go以编程的方式做同样的事情 我试着用它作为起点,试着理解该做什么,但现在我有一堆混乱的代码,而这看起来实际上是一件非常简单的事情Golang中的简单SSH端口转发,go,Go,我正在尝试使用Go通过SSH创建(稍后关闭)一个简单的TCP端口转发。我不熟悉Golang和静态类型语言。(来自Ruby。) 在终端中,我只需运行ssh-l9000:localhost:9999user@server.com这就满足了我的需要。我想用Go以编程的方式做同样的事情 我试着用它作为起点,试着理解该做什么,但现在我有一堆混乱的代码,而这看起来实际上是一件非常简单的事情 任何帮助都将不胜感激!:-) 我终于想出了这个方法,我从一个IRC频道的schmichael那里得到了一些提示。谢谢大
任何帮助都将不胜感激!:-) 我终于想出了这个方法,我从一个IRC频道的schmichael那里得到了一些提示。谢谢大家 编辑:一点解释: 我遇到的大部分问题是,我没有意识到本地
net.Listener
(不仅仅是本地net.Conn
)需要设置来接收本地请求并在转发字节之前创建net.Conn
。
此外,端口转发和反向端口转发都存在,我以前没有详细考虑常规端口转发也会发送字节,因此将远程读卡器复制到本地写卡器不是我实现的,但这是非常必要的。
下面是一个尝试,以说明此代码的本质:
- 在本地端口9000上侦听
- 尝试从本地端口9000读取时:(
)listener.Accept()
- 接受连接并返回本地
和io.Reader
和io.Writer
- 连接到远程服务器并
- 连接到远程端口9999,返回
和io.Reader
io.Writer
- 持续将本地
字节复制到远程io.Reader
io.Writer
- 持续将远程
字节复制到本地io.Reader
io.Writer
package main
// Forward from local port 9000 to remote port 9999
import (
"io"
"log"
"net"
"golang.org/x/crypto/ssh"
)
var (
username = "root"
password = "password"
serverAddrString = "192.168.1.100:22"
localAddrString = "localhost:9000"
remoteAddrString = "localhost:9999"
)
func forward(localConn net.Conn, config *ssh.ClientConfig) {
// Setup sshClientConn (type *ssh.ClientConn)
sshClientConn, err := ssh.Dial("tcp", serverAddrString, config)
if err != nil {
log.Fatalf("ssh.Dial failed: %s", err)
}
// Setup sshConn (type net.Conn)
sshConn, err := sshClientConn.Dial("tcp", remoteAddrString)
// Copy localConn.Reader to sshConn.Writer
go func() {
_, err = io.Copy(sshConn, localConn)
if err != nil {
log.Fatalf("io.Copy failed: %v", err)
}
}()
// Copy sshConn.Reader to localConn.Writer
go func() {
_, err = io.Copy(localConn, sshConn)
if err != nil {
log.Fatalf("io.Copy failed: %v", err)
}
}()
}
func main() {
// Setup SSH config (type *ssh.ClientConfig)
config := &ssh.ClientConfig{
User: username,
Auth: []ssh.AuthMethod{
ssh.Password(password),
},
}
// Setup localListener (type net.Listener)
localListener, err := net.Listen("tcp", localAddrString)
if err != nil {
log.Fatalf("net.Listen failed: %v", err)
}
for {
// Setup localConn (type net.Conn)
localConn, err := localListener.Accept()
if err != nil {
log.Fatalf("listen.Accept failed: %v", err)
}
go forward(localConn, config)
}
}
我已经完成了一个简单的SSH端口转发工具,名为。 它提供HTTP代理而不是SOCKS代理,这与ssh-D非常相似 核心代码与damick的答案类似
ssh.Dial
到远程ssh服务器,并返回客户端
Client.Dial
转发任何您喜欢的内容
拨号从远程主机启动到addr的连接。结果连接的LocalAddr()和RemoteAddr()为零Client.Dial
连接到远程服务器Thorsten.我编写了一个名为gosstool的工具,通过这个工具,您可以轻松地使用Go通过SSH创建一个简单的TCP端口转发 我使用此工具实现了一个端口转发服务器示例项目:
您有多少乱码?感谢MichaelT,在下面的答案中,已成功删除并重新创建了乱码。谢谢你的帮助!你认为(在你下面的回答中)你能完成最终代码所需的步骤吗?根本原因是什么以及如何解决?我希望这些编辑能有所帮助。有这么多的变化,又一次的变化,很难规划我是如何到达那里的再次感谢。你能告诉我如何使动态转发工作吗?像宋承宪一样,我希望我能在那里帮助你,朋友,但我对袜子和其他东西还不够熟悉。也许对你有帮助。祝你好运,如果你得到它,请告诉我!请注意,
go.grypto
包现在托管在golang.org/x/crypto/ssh
,另外,为了让这个优秀的示例发挥作用(谢谢@damick!),您需要考虑将ssh.ClientAuth
与ssh.AuthMethod
交换,根据对包API的更改,我已经成功安装了mallory,但是当我运行命令:mallory-engine=ssh-remote时=ssh://root:123456789abc@104.207.140.29:22,我遇到了以下错误:提供了标记,但未定义:-mallory的引擎用法:-配置字符串配置文件(默认值“$HOME/.config/mallory.json”)-重新加载发送信号以重新加载配置文件-后缀字符串打印给定域的pulbic后缀希望您的帮助我可以连接用户和密码。感谢