【问题标题】:create a background ssh tunnel in ruby在 ruby​​ 中创建一个后台 ssh 隧道
【发布时间】:2016-10-25 09:54:24
【问题描述】:

我的 oracle 数据库只能通过跳转服务器访问并且是负载平衡的。结果,我在 bash 中运行了以下后台隧道命令:

ssh ${jumpoffUser}@${jumpoffIp} -L1521:ont-db01-vip:1521 -L1522:ont-db02-vip:1521 -fN

在我使用 sqlplus 在数据库上运行命令之前,如下所示:

sqlplus #{@sqlUsername}/#{@sqlPassword}@'#{@sqlUrl}' @scripts/populateASDB.sql

这一切都很好。

现在我想 rubisize 这个过程。

在查找有关 ruby​​ 的文档时,我找不到如何将隧道置于后台(这是我的偏好),但我找到了有关本地端口转发的文档,我认为它可以模拟上述隧道和后续的 sqlplus 命令。

这是我的代码:

Net::SSH.start( @jumpoffIp, @jumpoffUser ) do |session|
  session.forward.local( 1521, 'ont-db01-vip', 1521 )
  session.forward.local( 1522, 'ont-db02-vip', 1521 )
  puts "About to populateDB"
  res = %x[sqlplus #{@sqlUsername}/#{@sqlPassword}@'#{@sqlUrl}' @scripts/populateASDB.sql > output.txt]
  puts "populateDb output #{res}"
  session.loop
end

当我运行上面的命令时,我得到了“About to populateDB”这一行,但它挂在 sqlplus 命令的实际运行上。我的端口转发代码是否有问题或如何输入以下内容:

ssh ${jumpoffUser}@${jumpoffIp} -L1521:ont-db01-vip:1521 -L1522:ont-db02-vip:1521 -fN

进入 ruby​​ 代码?

一个

【问题讨论】:

  • net-ssh.github.io/ssh/v1/chapter-4.html#s1 ⇐ 为什么你期望你在running ruby​​ process的子shell中执行的命令知道你刚刚建立的SSH隧道?
  • 隧道应该通过跳转将我机器上的端口绑定到数据库服务器上的端口。这在 bash 中有效。然后对 localhost:1521 的调用无缝地转到 ont-db01-vip:1521 并且对 localhost:1522 的调用无缝地转到 ont-db02-vip:1521
  • 子shell正在我的机器上工作,它应该有端口绑定

标签: ruby portforwarding ssh-tunnel


【解决方案1】:

尝试使用这个 gem:https://github.com/net-ssh/net-ssh-gateway/

require 'net/ssh/gateway'

gateway = Net::SSH::Gateway.new(@jumpoffIp, @jumpoffUser)
gateway.open('ont-db01-vip', 1521, 1521)
gateway.open('ont-db02-vip', 1521, 1521)

res = %x[sqlplus #{@sqlUsername}/#{@sqlPassword}@'#{@sqlUrl}' @scripts/populateASDB.sql > output.txt]
puts "populateDb output #{res}"

gateway.shutdown!

【讨论】:

    【解决方案2】:

    你有两个问题。

    1) 您需要使用 'session.loop { true }' 以便会话真正循环

    2) 在 sqlplus 命令完成之前,您不会开始循环会话,但 sqlplus 需要会话循环(转发已启动)。

    所以我建议使用 Thread.new 创建一个后台线程,然后在 sqlplus 完成后终止该线程。

    【讨论】:

    • 感谢您的回答!
    【解决方案3】:

    感谢大卫的回答,我想出了以下几点:

    Net::SSH.start(ip_addr, 'user') do |session|
    session.forward.local( 9090, 'localhost', 9090 )
      # Need to run the event loop in the background for SSH callbacks to work
      t = Thread.new {
        session.loop { true }
      }
      commands.each  do | command |
        command.call(9090)
      end
    
      Thread.kill(t)
    end
    

    【讨论】:

      猜你喜欢
      • 2016-01-15
      • 1970-01-01
      • 2021-11-02
      • 1970-01-01
      • 2019-06-04
      • 2012-03-28
      • 2014-10-02
      • 1970-01-01
      相关资源
      最近更新 更多