dte*_*ell 5 c++ ssh portforwarding libssh
问题
我尝试使用libssh和libssh-C++-wrapper进行本地端口转发。我的目的是通过 SSH 将localhost:3306服务器localhost:3307上的端口转发到我的机器上,以通过 MySQL 连接到localhost:3307.
void ssh_session::forward(){
ssh::Channel channel(this->session);
//remotehost, remoteport, localhost, localport
channel.openForward("localhost",3306,"localhost",3307);
std::cout<< "Channel is " << (channel.isOpen()?"open!":"closed!") << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
withsession在ssh::Channel类型为 的构造函数中ssh::Session。
上面的代码打印Channel is open!. 如果我尝试localhost:3307使用MySQL Connector/C++ 连接,我会得到
错误 2003 (HY000):无法连接到“127.0.0.1”上的 MySQL 服务器 (61)
观察
$ ssh -L 3307:localhost:3306 me@myserver.com一切正常,我可以连接。ssh::Session session在构造函数中使用used 或ssh::Channel channel执行远程 shell 命令,一切正常,因此会话很好!libsshpp.hpp因为许多公共成员函数没有记录在案,您必须查看源代码)表明这ssh::Channel::openForward()是 C 函数的包装器ssh_channel_open_forward()ssh_channel_open_forward()状态
警告
此函数不会绑定本地端口,也不会自动将套接字的内容转发到通道。为此,您仍然必须使用 channel_read 和 channel_write。
我认为这可能会导致问题。我通过读取和写入没有问题,ssh:Channel但这不是 MySQL Connector/C++ 的工作方式。
题
我怎样才能实现通用 shell 命令产生的相同行为
$ ssh -L 3307:localhost:3306 me@myserver.com
Run Code Online (Sandbox Code Playgroud)
使用libssh?
警告
该函数不会绑定本地端口,也不会自动将套接字的内容转发到通道。为此,您仍然必须使用channel_read和channel_write。
这告诉您需要编写自己的本地套接字代码。不幸的是,它不适合你。
最简单的实现是bind本地套接字,并用于ssh_select侦听事件(例如,新连接accept、套接字或通道事件)。您可以将套接字fds a 和ssh_channels 保存在向量中以便于管理。
当你收到任何事件时,只需以非阻塞方式循环所有操作,即
accept一个新的连接,并将 fd 和一个新的 ssh_channel (在您的问题中创建)附加到您的向量中。read所有套接字fd,并将任何内容转发到相应的 ssh 通道ssh_channel_write(确保将 setsockopt SO_RCVTIMEO 设置为 0)ssh_channel_read_nonblocking转发到套接字。fdwrite还需要处理各处的错误,并关闭相应的fd和ssh_channel。
总的来说,对于 StackOverflow 的答案来说,代码可能太多了,但如果有时间,我可能会回来添加它。
所有这些的诱人替代方案是使用&ssh -L ...作为子进程运行,避免所有样板套接字代码,并从高效、无错误的实现中受益。forkexec