如何使用 Ruby 进行动态端口转发
Posted
技术标签:
【中文标题】如何使用 Ruby 进行动态端口转发【英文标题】:How to do dynamic port forwarding using Ruby 【发布时间】:2019-11-22 13:49:17 【问题描述】:如何在 Ruby 上进行 SSH 动态端口转发?
我尝试使用诸如“net/ssh/socks”和“net/ssh/gateway”之类的 gem,但看起来它们已经过时了,因为我什至不需要它们。
我需要做的就是运行这个 shell 命令
ssh -D 5555 user@host -f -N
并接收该进程的PID。
我也尝试使用Kernel#system
和Kernel#spawn
。
例如:
pid = spawn("ssh -D 5555 user@host -f -N")
Process.wait pid
这对我来说很好,但是返回的 PID 总是比启动的进程的实际 PID 少 3 个单位。例如返回的PID为1555
,真实的PID为1558
。
另一个问题:为什么 PID 的差异总是 3,是否还有其他差异?我可以可靠地使用pid + 3
吗?
【问题讨论】:
如何确定“真实PID”?我无法重现此 PID 问题,因为 SSH 在运行时不应分叉。如果你这样做pid = spawn "sleep 300"
会发生什么?那你得到正确的PID了吗?另外:你如何检查正确的 PID,你正在运行什么命令。最好将此信息添加到问题中。
【参考方案1】:
使用 SSH 二进制文件
您正在使用-f
(fork) 运行 SSH。在 Ruby 中,Kernel.spawn
会自动将进程分叉到后台,因此您不需要使用-f
。如果使用-f
会造成双叉的情况,这就是PID异常的原因。
这应该足以让它工作:
pid = spawn("ssh -N -D 5555 user@host")
将 Net::SSH 与 Net::SSH::Socks 结合使用
如果您想使用net-ssh-socks
,则必须手动克隆存储库,因为 Rubygems 版本尚未针对最新的 Net::SSH 进行更新。
git clone https://github.com/cristianbica/net-ssh-socks
假设您克隆到运行脚本所在的同一文件夹中,那么您的 Ruby 代码将如下所示:
$:.push('net-ssh-socks/lib') # Add the cloned repo to load path
require 'net/ssh/socks'
ssh = Net::SSH.start('host', 'user')
ssh.forward.socks(5555)
ssh.loop true
【讨论】:
谢谢!这解决了 PID 的问题。所以在 Ruby 中,这似乎是动态端口转发的最合适的选项。 好像是这样。net-ssh-socks
gem 仅与 Net::SSH
2.0.24(当前版本 5.x.x)兼容。如果您愿意使用该版本(例如在 Bundler 的帮助下),那么它可能也可以工作。
Daniel 看到我的编辑。我添加了另一个似乎也适用于最新 Net::SSH 版本的选项。
非常感谢!我会在测试后立即给您反馈。以上是关于如何使用 Ruby 进行动态端口转发的主要内容,如果未能解决你的问题,请参考以下文章