我的目标 Oracle 数据库服务器存在于防火墙之外。我使用 ssh 隧道连接到防火墙之外的服务器,称之为friendly-server。然后从我的本地主机,我使用 DBI 连接到另一台服务器上存在的目标数据库,称之为target-dbserver。类似的问题建议使用下面的命令行。
这是我用来设置隧道的 ssh 命令:
ssh -nN -L 1520:target-dbserver:1520 friendly-server
我想在 Ruby 中实现这个,所以我使用了net-ssh-gateway gem。我可能只是不了解 ssh 隧道是如何工作的,因为我看不到如何建立网关,然后建立随后的 ssh 到友好服务器,我看不到如何建立与目标数据库的 DBI 连接-数据库服务器。
# Set up the gateway. The gem will find an unused port.
gateway = Net::SSH::Gateway.new('friendly-server', 'user')
# Establish ssh connection
gateway.ssh('friendly-server', 'user') do |ssh|
# now how to make DBI connection to target-dbserver ?
end
试过这个失败了,因为 DBI 调用如何知道使用隧道?
gateway = Net::SSH::Gateway.new('friendly-server', 'user')
gateway.ssh('friendly-server', 'user') do |ssh|
db = DBI.connect('target server connection string', 'user','password')
end
使用gateway.open
方法。这对我来说似乎是合乎逻辑的,但是当我尝试通过本地主机(网关)通过 DBI 连接到目标数据库时它总是挂起。我认为可能是因为该.open
方法建立了与我不想要的 targetdb 的 ssh 连接。我希望与 dbtarget 的唯一联系是 DBI 连接。
# open gateway from localhost to bastion
gateway = Net::SSH::Gateway.new('friendly-server', 'user')
# Opens a new port on the local host and forwards it to the given host/port
# via the gateway host.
gateway.open(targetdb, 1520) do |port|
db = DBI.connect(localhost, port, sid)
end
更新
无法让网关或 net-ssh forward_local 为我工作。沮丧的我选择fork
了 ssh 隧道。不理想但暂时有效。如果使用本地端口,那么我想捕获该错误,但不知道如何使用此方法。
tunnel = fork do
exec 'ssh -nN -L 1520:targetdb:1520 friendly-server'
end
Process.detach(tunnel)
#do stuff
Process.kill('HUP', tunnel) if tunnel