2 回答
TA贡献1862条经验 获得超7个赞
我答应提供我的例子,它来了。基本上我的解决方案建立了一个到远程服务器的 ssh 隧道并通过这个隧道查询远程数据库。ssh 隧道是解决方案的一部分。
我必须做的第一件事是将 PuTTY .ppk 私钥文件转换为有效的 OpenSSH .pem 密钥文件。这可以使用 PuTTYgen 中的导出功能轻松完成。因为我想支持密码加密的私钥,所以我还需要一个函数来解密密钥并将其从解密的原始格式重新格式化为 golang.org/x/crypto/ssh/ParsePrivateKey 接受的有效格式,这是获取用于身份验证的签名者列表。
解决方案本身由包含在两个文件中的包组成。应用程序的主要部分在 main.go 中完成,其中包含所有相关的数据分配以及与数据库查询相关的代码。与 ssh 隧道和密钥处理相关的所有内容都包含在 sshTunnel.go 中。
该解决方案不提供安全密码存储的机制,也不要求输入密码。密码在代码中提供。但是,实现密码请求的回调方法并不会太复杂。
请注意:从性能角度来看,这不是一个理想的解决方案。它还缺乏适当的错误处理。我已经提供了这个例子。
该示例是一个经过测试且有效的示例。我在 Windows 8.1 PC 上开发并使用了它。数据库服务器位于远程 Linux 系统上。您需要更改的只是 main.go 中的数据和查询部分。
TA贡献1828条经验 获得超13个赞
好吧,我认为你可以做到“全围棋”。
SSH 部分和端口转发
我喜欢的东西就这样(我没有谷歌更好的例子)。
请注意此代码的两个问题:
它实际上并不正确:它在接受客户端连接之前连接到远程套接字 ,而它应该相反:接受客户端连接到端口转发的本地套接字,然后使用活动的 SSH 会话连接到远程套接字,如果成功, 生成两个 goroutines 以在这两个套接字之间铲除数据。
在配置 SSH 客户端时,它出于未知原因明确允许基于密码的身份验证。您不需要这个,因为您使用的是基于公钥的身份验证。
一个可能会绊倒您的障碍是管理对您的 SSH 密钥的访问。它的问题在于一个好的密钥应该受密码保护。
你说密钥的密码“存储在价值中”,老实说,我不知道“价值”是什么。
在我使用的系统上,SSH 客户端要么要求输入密码来解密密钥,要么使用所谓的“SSH 代理”:
在基于 Linux 的系统上,它通常是
ssh-agent
在后台工作的 OpenSSH二进制文件,它通过 Unix 域套接字访问,并通过检查名为SSH_AUTH_SOCK
.在 Windows 上,我使用 PuTTY,它有自己的代理
pageant.exe
. 我不知道 PuTTY SSH 客户端使用哪种方式来定位它。
要访问 OpenSSH 代理,golang.org/x/crypto/ssh
提供agent
可用于定位代理并与之通信的子包。如果您需要从 获取密钥pageant
,恐怕您需要弄清楚使用什么协议并实现它。
MySQL部分
下一步是将其与go-sql-driver
.
我会以最简单的方式开始:
当您的 SSH 端口转发工作时,让它在本地主机上的随机端口上侦听传入连接。当连接打开时,从返回的连接对象中获取端口。
使用该端口号构建连接字符串以传递给
sql.DB
您将创建以使用的实例go-sql-driver
。
然后驱动程序将连接到您的端口转发端口,您的 SSH 层将完成剩下的工作。
在您完成这项工作后,我将探讨您选择的驱动程序是否允许进行一些更细粒度的调整,例如允许您直接将一个io.ReadWriter
(打开的套接字)的实例传递给它,以便您可以完全跳过端口转发设置和只需生成通过 SSH 转发的新 TCP 连接,即跳过“本地侦听”步骤。
- 2 回答
- 0 关注
- 220 浏览
添加回答
举报