英文:
Go x/crypto/ssh -- How to establish ssh connection to private instance over a bastion node
问题
我想实现以下场景:
在AWS上,我有一个VPC,其中部署了一个公共子网和一个私有子网。在公共子网中,我有一个"堡垒机"实例,而在私有子网中,有一个运行一些服务的节点(也称为"服务实例")。
通过使用*nux ssh命令,我可以从我的本地笔记本连接到"服务实例",像这样:
ssh -t -o ProxyCommand="ssh -i <key> ubuntu@<bastion-ip> nc %h %p" -i <key> ubuntu@<service-instance-ip>
我有一个Go程序,想要做以下事情:
- 从"本地笔记本"通过"堡垒机"ssh连接到"服务实例"
- 使用连接会话运行一些命令(例如"ls -l")
- 将文件从"本地笔记本"上传到"服务实例"
我尝试过,但无法实现与以下命令相同的过程:
ssh -t -o ProxyCommand="ssh -i <key> ubuntu@<bastion-ip> nc %h %p" -i <key> ubuntu@<service-instance-ip>
有人可以帮助我提供一个示例吗?
谢谢!
顺便说一下,我找到了这个链接:
https://github.com/golang/go/issues/6223,这意味着肯定可以做到,对吗?
英文:
I want to implement this scenario:
On AWS, I have a VPC, in which it is deployed a public and private subnet. In the public subnet, I have a "bastion" instance, while in private subnet, there is one node running some services(AKA "service instance").
By using *nux ssh command, I can do things like this to connect to the "service instance" from my local laptop:
ssh -t -o ProxyCommand="ssh -i <key> ubuntu@<bastion-ip> nc %h %p" -i <key> ubuntu@<service-instance-ip>
I have a Go program, and want to do the following things:
> 1. ssh connect to the "service instance" from "local laptop" over the "bastion"
> 2. use the connection session to run some commands (e.g. "ls -l")
> 3. upload files from "local laptop" to "service instance"
I've tried but not able to implement the same process as doing
ssh -t -o ProxyCommand="ssh -i <key> ubuntu@<bastion-ip> nc %h %p" -i <key> ubuntu@<service-instance-ip>
Could anyone help to show me an example?
Thanks!
BTW, I found this:
https://github.com/golang/go/issues/6223, which means it is definately able to do that, right?
答案1
得分: 22
你可以直接使用"x/crypto/ssh"而不使用nc
命令来完成这个操作,因为有一种方法可以从远程主机拨号连接并将其呈现为net.Conn
。
一旦你拥有一个ssh.Client
,你可以使用Dial
方法在你和最终主机之间获得一个虚拟的net.Conn
。然后,你可以使用ssh.NewClientConn
将其转换为一个新的ssh.Conn
,并使用ssh.NewClient
创建一个新的ssh.Client
。
// 连接到堡垒主机
bClient, err := ssh.Dial("tcp", bastionAddr, config)
if err != nil {
log.Fatal(err)
}
// 从堡垒主机拨号连接到服务主机
conn, err := bClient.Dial("tcp", serviceAddr)
if err != nil {
log.Fatal(err)
}
ncc, chans, reqs, err := ssh.NewClientConn(conn, serviceAddr, config)
if err != nil {
log.Fatal(err)
}
sClient := ssh.NewClient(ncc, chans, reqs)
// sClient 是通过堡垒主机连接到服务主机的 ssh 客户端
英文:
You can do this even more directly with the "x/crypto/ssh" without the nc
command, since there is a method to dial a connection from the remote host and presents it as a net.Conn
.
Once you have an ssh.Client
, you can use the Dial
method to get a virtual net.Conn
between you and the final host. You can then turn that into a new ssh.Conn
with ssh.NewClientConn
, and create a new ssh.Client
with ssh.NewClient
// connect to the bastion host
bClient, err := ssh.Dial("tcp", bastionAddr, config)
if err != nil {
log.Fatal(err)
}
// Dial a connection to the service host, from the bastion
conn, err := bClient.Dial("tcp", serviceAddr)
if err != nil {
log.Fatal(err)
}
ncc, chans, reqs, err := ssh.NewClientConn(conn, serviceAddr, config)
if err != nil {
log.Fatal(err)
}
sClient := ssh.NewClient(ncc, chans, reqs)
// sClient is an ssh client connected to the service host, through the bastion host.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论