Net::SSH 2.0 (and friends)
At last! Net::SSH 2.0 is available! Also available are Net::SFTP 2.0, Net::SCP 1.0, Net::SSH::Gateway 1.0, and Net::SSH::Multi 1.0.
1 2 3 4 5
$ gem install net-ssh \ net-sftp \ net-scp \ net-ssh-gateway \ net-ssh-multi
All of these Ruby libraries are for communicating with remote servers via the SSH protocol in different ways.
Net::SSH and Net::SFTP are both significant upgrades from their previous incarnations; if you have used either library in the past, you’ll want to read the documentation (Net::SSH, Net::SFTP). The Net::SSH API is still fairly similar to the way it was before, but the Net::SFTP API is entirely different.
All have pretty complete RDoc documentation, so you should be able to employ “ri” to good effect to find your way around the libraries. (Try “ri Net::SSH”, for example, to get started.)
Per-library synopses follow.
This is a significant upgrade from Net::SSH 1.x. Changes from 1.x include (but are not limited to):
- Net::SSH 2.0 no longer requires the Needle dependency-injection library. This has made the library faster, lighter, and easier to understand.
- The “sync” and “sync-shell” services have been removed and will not return. (If you need the functionality of those services, I strongly encourage you to port them to Net::SSH 2 and release them as separate extensions.)
- Options in ~/.ssh/config files are (partially) supported, and are loaded by default now.
- The Net::SSH::start method now requires both a host and a username as the first two parameters, rather than inferring the username.
- There is now a Session#exec method that makes it easier than ever to just execute and interact with a command.
- Channel now sports an #on_process method that you can send a block to, which will be executed on every pass of the event loop.
- Channel#on_request now accepts a string to indicate which request you want to respond to.
- Channel open failures may be captured via Channel#on_open_failure.
- Lots, lots, LOTS, more—refer to the rdocs for all the gory details.
1 2 3 4 5 6
require 'net/ssh' Net::SSH.start('localhost', 'jamis') do |ssh| ssh.exec('hostname') # prints the results to $stdout ssh.loop end
This is a complete rewrite of the original Net::SFTP 1.x code, and shares very, very little in common with it. The new version has a much cleaner implementation and API, and provides some really handy methods for transferring files and directories.
1 2 3 4 5 6 7 8 9 10
require 'net/sftp' Net::SFTP.start('localhost', 'jamis') do |sftp| sftp.upload! "/local/file", "/remote/file" sftp.download! "/remote/file", "/local/file" sftp.file.open("/remote/file", "w") do |file| file.puts "here is some data" end end
This provides a way to transfer files and directories via the SCP protocol, over Net::SSH.
1 2 3 4 5 6
require 'net/scp' Net::SCP.start('localhost', 'jamis') do |scp| scp.upload! "/local/file", "/remote/file" scp.download! "/remote/file", "/local/file" end
This library makes it easy to tunnel connections though firewalls. You simply connect to the gateway machine, and then specify which ports you want forwarded.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
require 'net/ssh/gateway' gateway = Net::SSH::Gateway.new('host', 'user') gateway.ssh("host.private", "user") do |ssh| puts ssh.exec!("hostname") end gateway.open("host.private", 80) do |port| require 'net/http' Net::HTTP.get_print("127.0.0.1", "/path", port) end gateway.shutdown!
This library makes it simple to open multiple Net::SSH connections and tie them all together, running commands in parallel (much like Capistrano does).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
require 'net/ssh/multi' Net::SSH::Multi.start do |session| # access servers via a gateway session.via 'gateway', 'gateway-user' # define the servers we want to use session.use '[email protected]' session.use '[email protected]' # define servers in groups for more granular access session.group :app do session.use '[email protected]' session.use '[email protected]' end # execute commands on all servers session.exec "uptime" # execute commands on a subset of servers session.with(:app).exec "hostname" # run the aggregated event loop session.loop end
All this looks great! Your work on these libraries really helps Ruby be a successful language.
I have one suggestion, though: session.via(gateway info here) seems like it’s a perfect match for the decorator or wrapper pattern. That is, the following code makes more sense to me:
That is, session.via should return a new session object rather than being mutable. This would allow chained gateways, though I’m not really sure anybody needs that. The real advantage is the decrease on the conceptual weight of Session – it need only return a WrappedSession or a GatewaySessionWrapper or something instead of needing to keep track of the gateway information itself.
Bravo on the release!
2 May 2008
@James, thanks for the suggestion, I’ll take it under consideration. What session#via really does, though, is set the default gateway instance to use. You can specify per-session gateways with session.use(‘host’, ‘name’, :via => Net::SSH::Gateway.new(...)).
2 May 2008
Congrats Jamis!! This is awesome!
2 May 2008
Yeah this is great. Have been using v1 of Net::SSH & Net::SFTP quite a bit.
The cleaned up SFTP api is a nice touch – mimicing the Dir and File methods similar to how “zip/zipfilesystem” works makes it easy to write code that is agnostic of the method it uses to access files (local fs, zip, remote sftp, etc). Kind of a de-facto ruby vfs.
5 May 2008
I like how SSH:Multi + Rake gives you a very low-magic version of capistrano.
5 May 2008
I try to update my gem and not find the 2.0 version :
net-ssh (1.1.2, 1.1.1, 1.1.0, 1.0.10, 1.0.9, 1.0.8, 1.0.7, 1.0.6, 1.0.5, 1.0.4, 1.0.3, 1.0.2, 1.0.1, 1.0.0, 0.9.0, 0.6.0, 0.5.0, 0.1.0, 0.0.5, 0.0.4, 0.0.3, 0.0.2, 0.0.1) Net::SSH is a pure-Ruby implementation of the SSH2 client protocol.
Where is the 2.0 ??
6 May 2008
Solved with, gem update—system
Great work, thanks.
6 May 2008
net/ssh requires jruby-openssl when when running on JRuby, is there some way for it to be added as dependency on the net/ssh gem?
Also, running on JRuby+Windows I had to add ‘net/ssh/pageant.rb’ to $LOADED_FEATURES before requiring net/ssh, jruby does not have a ‘dl/import’
7 May 2008
Can you provide information on the SSH v1.1 methods that you have removed, and what equivalent methods should be used?
27 May 2008
I’ve been using Net::SSH for a while now with great success. For the first time today I attempted to setup a forwarded port to access mysql on a remote host that only listens to 127.0.0.1.
I can set the tunnel up fine and then access mysql using the standard mysql binary client, or I can setup the tunnel using ‘ssh’ itself and then access the database via ruby, but not both.
4 Jun 2008
Jamis, trying SSH 2.0.2 however I seem to have a different path set in my profile from when I used SSH 1.1.2, the path doesn’t contain sudo. This is using the same server and account.
9 Jun 2008
/usr/lib/ruby/gems/1.8/gems/net-ssh-2.0.2/lib/net/ssh/transport/algorithms.rb:192:in `prepare_preferred_algorithms!’: unsupported hmac algorithm: `[email protected]’ (NotImplementedError) from /usr/lib/ruby/gems/1.8/gems/net-ssh-2.0.2/lib/net/ssh/transport/algorithms.rb:185:in `each’ from /usr/lib/ruby/gems/1.8/gems/net-ssh-2.0.2/lib/net/ssh/transport/algorithms.rb:185:in `prepare_preferred_algorithms!’ from /usr/lib/ruby/gems/1.8/gems/net-ssh-2.0.2/lib/net/ssh/transport/algorithms.rb:96:in `initialize’ from /usr/lib/ruby/gems/1.8/gems/net-ssh-2.0.2/lib/net/ssh/transport/session.rb:77:in `new’ from /usr/lib/ruby/gems/1.8/gems/net-ssh-2.0.2/lib/net/ssh/transport/session.rb:77:in `initialize’ from /usr/lib/ruby/gems/1.8/gems/net-ssh-2.0.2/lib/net/ssh.rb:182:in `new’ from /usr/lib/ruby/gems/1.8/gems/net-ssh-2.0.2/lib/net/ssh.rb:182:in `start’ from /home/sysnjk/scripts/wlinstances.rb:7
17 Jun 2008
fixed it with
Net::SSH.start(hostname, username, :hmac => ‘hmac-md5’) do |ssh|
but i think [email protected] is quite common?
17 Jun 2008
However, I can’t find a way to put the :hmac option in net/ssh/multi.
17 Jun 2008
p.s. this makes net/ssh incompatible with the default solaris 10 install.
18 Jun 2008
@Anko, I’m afraid I’ve all but given up trying to keep any solaris flavor happy. They all seem to do their own thing. As for “[email protected]” being common, this is the first time in 4 years of working with Net::SSH that I’ve ever even heard of it. If you really want it supported, though, please look at providing a patch. I’d certainly consider one for that.
22 Jun 2008
Okay will do, but it might take some time as i don’t have solaris at home and finding work time for it is near impossible.
I’ve found a public domain umac implementation @ http://fastcrypto.org/ so i’ll start reading the ssh specs tonight :)
13 Jul 2008