Reputation: 2836
I was looking for a way to SSH to a jumpoff server using ruby and from that server SSH to another server. The jumpoff server is the only server with access to the final server. I was trying Net::SSH but I can't seem to get an SSH connection from within the established SSH connection.
irb(main):021:0> require "net/ssh"
=> false
irb(main):022:0> Net::SSH.start("10.10.10.10", "admin") do |ssh|
irb(main):023:1* result = ssh.exec!("mm | grep 'dv ' | awk '{print $1}'").strip
irb(main):024:1> p "Going to try to login to #{result}"
irb(main):025:1> Net::SSH.start(result, "admin") do |ssh1|
irb(main):026:2* hostname = ssh1.exec!("hostname")
irb(main):027:2> p "In #{hostname}"
irb(main):029:2> end
irb(main):030:1> end
"Going to try to login to vz-int-api02"
SocketError: initialize: name or service not known
from org/jruby/ext/socket/RubyTCPSocket.java:129:in `initialize'
from org/jruby/RubyIO.java:1178:in `open'
from /usr/local/jruby-1.7.9/lib/ruby/gems/shared/gems/net-ssh-2.9.2 /lib/net/ssh/transport/session.rb:70:in `initialize'
from org/jruby/ext/timeout/Timeout.java:105:in `timeout'
from /usr/local/jruby-1.7.9/lib/ruby/gems/shared/gems/net-ssh-2.9.2 /lib/net/ssh/transport/session.rb:67:in `initialize'
from /usr/local/jruby-1.7.9/lib/ruby/gems/shared/gems/net-ssh-2.9.2 /lib/net/ssh.rb:207:in `start'
from (irb):25:in `evaluate'
from /usr/local/jruby-1.7.9/lib/ruby/gems/shared/gems/net-ssh-2.9.2 /lib/net/ssh.rb:215:in `start'
from (irb):22:in `evaluate'
from org/jruby/RubyKernel.java:1119:in `eval'
from org/jruby/RubyKernel.java:1519:in `loop'
from org/jruby/RubyKernel.java:1282:in `catch'
from org/jruby/RubyKernel.java:1282:in `catch'
from /usr/local/jruby-1.7.9/bin/irb:13:in `(root)'
I also tried running the SSH connection directly from the established SSH connection but there seems to be no way to initiate an new session from a session object:
irb(main):035:1> ssh.start(result, "admin") do |ssh1|
gives:
NoMethodError: undefined method `start' for #<Net::SSH::Connection::Session:0x5b11d0d8>
I'm probably tackling this from the wrong angle but I could not find anyone who wanted to SSH from a SSH connection.
Upvotes: 0
Views: 853
Reputation: 84114
You can do this with SSH port forwarding. Net::SSH gateway does this for you, but it's easy enough to do yourself.
It basically has some code that looks like this:
Net::SSH.start(...) do |ssh|
ssh.forward(12345, "internal host", 22)
ssh.loop { true }
end
That sets up the tunnel and then you make a new SSH connection to locahost port 12345.
Upvotes: 1
Reputation: 24551
This is possible, but you should use SSH's built-in ProxyCommand
setting to do it. If you have an ~/.ssh/config
file, then Net::SSH
will use that. For instance it could look like this:
Host the.protected.box
Hostname 10.10.10.20
ProxyCommand ssh 10.10.10.10 nc %h %p 2> /dev/null
Then you can say:
Net::SSH.start('the.protected.box', 'admin')
and the proxying will just work.
If you run into issues it is often easier to debug this using the ssh
command-line tool before translating your work into Ruby.
If you don't want to use ~/.ssh/config
, you can set up a proxy command in code instead:
require 'net/ssh/proxy/command'
proxy = Net::SSH::Proxy::Command.new('ssh 10.10.10.10 nc %h %p 2>/dev/null')
Net::SSH.start('10.10.10.20', 'admin', proxy: proxy)
Upvotes: 1