3

ターゲットの Oracle データベース サーバーがファイアウォールの外側に存在します。私は ssh トンネルを使用して、ファイアウォールを越えてサーバーに接続し、それをFriendly-serverと呼びます。次に、ローカルホストから DBI を使用して、別のサーバーに存在するターゲット データベースに接続し、それをtarget-dbserverと呼びます。同様の質問では、以下のコマンドラインを使用することをお勧めします。

これは、トンネルをセットアップするために使用する ssh コマンドです。

ssh -nN -L 1520:target-dbserver:1520 friendly-server

これを Ruby で実装したいので、net-ssh-gateway gem を使用しています。おそらく、ssh トンネリングがどのように機能するかを理解していないだけです。なぜなら、ゲートウェイを確立してから、その後に Friendly -serverへの 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
4

1 に答える 1

1

私の解決策は、ssh コマンドを fork し、終了したらその ssh プロセスを強制終了することです。

# obj_hash contains remote db details and a flag for when a tunnel is needed
local_port = 3535
if obj_hash[:tunnel]
  tunnel = fork do
    exec "ssh -nN -L #{local_port}:#{obj_hash[:server]}:#{obj_hash[:port]} #{obj_hash[:tunnel]} 2> /dev/null; "
  end
  Process.detach(tunnel)
end
# do stuff
Process.kill('HUP', tunnel) if tunnel

現在、トンネルが local_port で既に稼働しているかどうかを確認する方法がわからないため、完全な解決策ではありません。

于 2013-03-18T16:24:29.360 に答える