[ANN] Net::SSH 0.0.3

Net::SSH is a Ruby implementation of the SSH2 client protocol.

   http://rubyforge.org/projects/net-ssh

You asked for it, and you got it! Version 0.0.3 now supports port forwarding. You can enable forwarding both from local to remote ports, and vice versa (corresponding to the -L and -R options of ssh). Also, you can programmatically mimic connection to/from ports, using handler objects.

Here's a quick demo of port forwarding:

   Net::SSH.start( 'localhost' ) do |session|
     manager = Net::SSH::Service::PortForwardManager.new( session )

     manager.forward_local( 12345, 'www.yahoo.com', 80 )
     manager.forward_local( 12346, 'www.google.com', 80 )

     session.main_loop { true }
   end

See the "examples" subdirectory for more examples.

This release also allows clients to specify their preferred SSH algorithms. This means you can (for example) enable zlib compression of the data stream. See the examples subdirectory for an example of how to do this.

A few other fixes have been made, though the code is still far from perfect, or complete. More work needs to be done on:

   - increasing the coverage of the SFTP protocol
   - supporting ssh-agent if one is running
   - supporting private keys with key/value pairs in their headers
   - implementing a synchronous version of Net::SSH::Session

Try it out and let me know what you like/don't like. Wishlists are accepted, as well. :slight_smile: As usual, any version of Ruby < 1.8.2 will need to have the patched version of OpenSSL, also available from the Net::SSH downloads page.

···

--
Jamis Buck
jgb3@email.byu.edu
http://www.jamisbuck.org/jamis

"I use octal until I get to 8, and then I switch to decimal."

Jamis Buck wrote:

Net::SSH is a Ruby implementation of the SSH2 client protocol.

  http://rubyforge.org/projects/net-ssh

You asked for it, and you got it! Version 0.0.3 now supports port forwarding. You can enable forwarding both from local to remote ports, and vice versa (corresponding to the -L and -R options of ssh). Also, you can programmatically mimic connection to/from ports, using handler objects.

Here's a quick demo of port forwarding:

  Net::SSH.start( 'localhost' ) do |session|
    manager = Net::SSH::Service::PortForwardManager.new( session )

    manager.forward_local( 12345, 'www.yahoo.com', 80 )
    manager.forward_local( 12346, 'www.google.com', 80 )

    session.main_loop { true }
  end

See the "examples" subdirectory for more examples.

This release also allows clients to specify their preferred SSH algorithms. This means you can (for example) enable zlib compression of the data stream. See the examples subdirectory for an example of how to do this.

A few other fixes have been made, though the code is still far from perfect, or complete. More work needs to be done on:

  - increasing the coverage of the SFTP protocol
  - supporting ssh-agent if one is running
  - supporting private keys with key/value pairs in their headers
  - implementing a synchronous version of Net::SSH::Session

Try it out and let me know what you like/don't like. Wishlists are accepted, as well. :slight_smile: As usual, any version of Ruby < 1.8.2 will need to have the patched version of OpenSSL, also available from the Net::SSH downloads page.

Wow, that was fast! We requested some of these features just days ago!

Quick question: after we establish port forwarding, how difficult is it (or how easy) to terminate or re-establish it? For example, if we're port forwarding to a machine with dynamic IP and detect that its address changed after the initial port-forwarding was established.

Thanks!!!

Jamis Buck wrote:

Net::SSH is a Ruby implementation of the SSH2 client protocol.

A few other fixes have been made, though the code is still far from perfect, or complete. More work needs to be done on:

  - increasing the coverage of the SFTP protocol

I'm looking forward to this one, Jamis.

Thanks for all your hard work.

Jamey

Confidentiality Notice: This email message, including any attachments, is for the sole use of the intended recipient(s) and may contain confidential and/or privileged information. If you are not the intended recipient(s), you are hereby notified that any dissemination, unauthorized review, use, disclosure or distribution of this email and any materials contained in any attachments is prohibited. If you receive this message in error, or are not the intended recipient(s), please immediately notify the sender by email and destroy all copies of the original message, including attachments.

Hi,

I installed net-ssh right now and wanted to try the example you
provided in your mail. I got the following error:

sshtest.rb:6: uninitialized constant
Net::SSH::Service::PortForwardManager (NameError)
        from sshtest.rb:4:in `start'
        from sshtest.rb:4

I'd be glad if you could help me get this to work.

regards,
jochen

Jamis Buck <jgb3@email.byu.edu> wrote in message news:<40F197E2.7030409@email.byu.edu>...

···

Net::SSH is a Ruby implementation of the SSH2 client protocol.

   http://rubyforge.org/projects/net-ssh

You asked for it, and you got it! Version 0.0.3 now supports port
forwarding. You can enable forwarding both from local to remote ports,
and vice versa (corresponding to the -L and -R options of ssh). Also,
you can programmatically mimic connection to/from ports, using handler
objects.

Here's a quick demo of port forwarding:

   Net::SSH.start( 'localhost' ) do |session|
     manager = Net::SSH::Service::PortForwardManager.new( session )

     manager.forward_local( 12345, 'www.yahoo.com', 80 )
     manager.forward_local( 12346, 'www.google.com', 80 )

     session.main_loop { true }
   end

See the "examples" subdirectory for more examples.

This release also allows clients to specify their preferred SSH
algorithms. This means you can (for example) enable zlib compression of
the data stream. See the examples subdirectory for an example of how to
do this.

A few other fixes have been made, though the code is still far from
perfect, or complete. More work needs to be done on:

   - increasing the coverage of the SFTP protocol
   - supporting ssh-agent if one is running
   - supporting private keys with key/value pairs in their headers
   - implementing a synchronous version of Net::SSH::Session

Try it out and let me know what you like/don't like. Wishlists are
accepted, as well. :slight_smile: As usual, any version of Ruby < 1.8.2 will need to
have the patched version of OpenSSL, also available from the Net::SSH
downloads page.

Randy Lawrence wrote:

Wow, that was fast! We requested some of these features just days ago!

I aim to please. :slight_smile:

Quick question: after we establish port forwarding, how difficult is it (or how easy) to terminate or re-establish it? For example, if we're port forwarding to a machine with dynamic IP and detect that its address changed after the initial port-forwarding was established.

Not hard at all. Supposing you started a forward request via:

   manager.forward_local( 12345, '1.2.3.4', 1122 )

Then, when you want to change the address that is being forwarded to:

   manager.cancel_forward_local( 12345, '1.2.3.4', 1122 )
   manager.forward_local( 12345, '1.2.3.5', 1122)

And away you go!

Someday all of this will be properly documented. In the meantime, the methods themselves have been commented--just run rdoc on the sources and you'll get a nice document. Once I'm out of the 0.0.x series, I'll sit down and write a users guide for all this stuff. In the meantime, the API is almost guaranteed to change before then...

Thanks!!!

You're welcome!

···

--
Jamis Buck
jgb3@email.byu.edu
http://www.jamisbuck.org/jamis

"I use octal until I get to 8, and then I switch to decimal."

Jochen Immend?rfer wrote:

Hi,

I installed net-ssh right now and wanted to try the example you
provided in your mail. I got the following error:

sshtest.rb:6: uninitialized constant
Net::SSH::Service::PortForwardManager (NameError)
        from sshtest.rb:4:in `start'
        from sshtest.rb:4

I'd be glad if you could help me get this to work.

regards,
jochen

Just be sure to require 'net/ssh/service/forward' first:

   require 'net/ssh/service/forward'
   p Net::SSH::Service::PortForwardManager

I figured port forwarding would be an "optional" service, which people should explicitly require before using. This keeps the overhead of requiring 'net/ssh' low.

Again, sorry for the lack of documentation. :frowning:

···

--
Jamis Buck
jgb3@email.byu.edu
http://www.jamisbuck.org/jamis

"I use octal until I get to 8, and then I switch to decimal."

Jamis Buck wrote:

Randy Lawrence wrote:

Wow, that was fast! We requested some of these features just days ago!

I aim to please. :slight_smile:

Quick question: after we establish port forwarding, how difficult is it (or how easy) to terminate or re-establish it? For example, if we're port forwarding to a machine with dynamic IP and detect that its address changed after the initial port-forwarding was established.

Not hard at all. Supposing you started a forward request via:

  manager.forward_local( 12345, '1.2.3.4', 1122 )

Then, when you want to change the address that is being forwarded to:

  manager.cancel_forward_local( 12345, '1.2.3.4', 1122 )
  manager.forward_local( 12345, '1.2.3.5', 1122)

And away you go!

Someday all of this will be properly documented. In the meantime, the methods themselves have been commented--just run rdoc on the sources and you'll get a nice document. Once I'm out of the 0.0.x series, I'll sit down and write a users guide for all this stuff. In the meantime, the API is almost guaranteed to change before then...

Thanks!!!

You're welcome!

Beautiful! This opens up a lot of possibilities.

Thanks a million!!!

Possibly stupid question - why's this not cancel_forward_local(12345)?
Can a single local port be bound to multiple remote ports?

martin

···

Jamis Buck <jgb3@email.byu.edu> wrote:

   manager.cancel_forward_local( 12345, '1.2.3.4', 1122 )
   manager.forward_local( 12345, '1.2.3.5', 1122)

Thank you for the quick reply. The additional require made it work for me.

But another question:

I've got my system configured with public and private keys the way that I can
connect without password. Itworks from the command-line.

But

  Net::SSH.start('localhost')

produces the error:

OpenSSL::PKey::PKeyError: wrong public key type
        from /usr/lib/ruby/gems/1.8/gems/net-ssh-0.0.3/lib/net/ssh/service/userauth.rb:207:in
`sign'
        from /usr/lib/ruby/gems/1.8/gems/net-ssh-0.0.3/lib/net/ssh/service/userauth.rb:207:in
`try_publickey_auth_with'
        from /usr/lib/ruby/gems/1.8/gems/net-ssh-0.0.3/lib/net/ssh/service/userauth.rb:181:in
`try_publickey_auth'
        from /usr/lib/ruby/gems/1.8/gems/net-ssh-0.0.3/lib/net/ssh/service/userauth.rb:180:in
`each'
        from /usr/lib/ruby/gems/1.8/gems/net-ssh-0.0.3/lib/net/ssh/service/userauth.rb:180:in
`try_publickey_auth'
        from /usr/lib/ruby/gems/1.8/gems/net-ssh-0.0.3/lib/net/ssh/service/userauth.rb:114:in
`process'
        from /usr/lib/ruby/gems/1.8/gems/net-ssh-0.0.3/lib/net/ssh.rb:123:in
`open'
        from /usr/lib/ruby/gems/1.8/gems/net-ssh-0.0.3/lib/net/ssh.rb:67:in
`start'
        from (irb):2

what is the 'right' public key type? I created my keys with

  ssh-keygen -t dsa

Is that wrong?

regards,
jochen

···

Am Montag 12 Juli 2004 17:25 schrieb Jamis Buck:

Just be sure to require 'net/ssh/service/forward' first:

   require 'net/ssh/service/forward'
   p Net::SSH::Service::PortForwardManager

I figured port forwarding would be an "optional" service, which people
should explicitly require before using. This keeps the overhead of
requiring 'net/ssh' low.

Again, sorry for the lack of documentation. :frowning:

Martin DeMello wrote:

···

Jamis Buck <jgb3@email.byu.edu> wrote:

  manager.cancel_forward_local( 12345, '1.2.3.4', 1122 )
  manager.forward_local( 12345, '1.2.3.5', 1122)

Possibly stupid question - why's this not cancel_forward_local(12345)?
Can a single local port be bound to multiple remote ports?

An excellent point, Martin. It seems like there was a compelling reason to do it the way I did...but I just woke up and can't seem to pull it from the fog.

At any rate, if I can't remember that compelling reason, I'll certainly reduce the parameters for cancel_forward_local to what you recommended.

Thanks for pointing it out. :slight_smile:

--
Jamis Buck
jgb3@email.byu.edu
http://www.jamisbuck.org/jamis

"I use octal until I get to 8, and then I switch to decimal."

Jochen Immendörfer wrote:

Thank you for the quick reply. The additional require made it work for me.

But another question:

I've got my system configured with public and private keys the way that I can connect without password. Itworks from the command-line.

But

  Net::SSH.start('localhost')

produces the error:

OpenSSL::PKey::PKeyError: wrong public key type
        from /usr/lib/ruby/gems/1.8/gems/net-ssh-0.0.3/lib/net/ssh/service/userauth.rb:207:in `sign'
        from /usr/lib/ruby/gems/1.8/gems/net-ssh-0.0.3/lib/net/ssh/service/userauth.rb:207:in `try_publickey_auth_with'
        from /usr/lib/ruby/gems/1.8/gems/net-ssh-0.0.3/lib/net/ssh/service/userauth.rb:181:in `try_publickey_auth'
        from /usr/lib/ruby/gems/1.8/gems/net-ssh-0.0.3/lib/net/ssh/service/userauth.rb:180:in `each'
        from /usr/lib/ruby/gems/1.8/gems/net-ssh-0.0.3/lib/net/ssh/service/userauth.rb:180:in `try_publickey_auth'
        from /usr/lib/ruby/gems/1.8/gems/net-ssh-0.0.3/lib/net/ssh/service/userauth.rb:114:in `process'
        from /usr/lib/ruby/gems/1.8/gems/net-ssh-0.0.3/lib/net/ssh.rb:123:in `open'
        from /usr/lib/ruby/gems/1.8/gems/net-ssh-0.0.3/lib/net/ssh.rb:67:in `start'
        from (irb):2

what is the 'right' public key type? I created my keys with

  ssh-keygen -t dsa

Is that wrong?

Woops. My bad. Apparently you can't use public/private key authentication using a dsa key right now. I'll work on that. I just need to not use the 'sign' method of the key object, since that doesn't work for all key types...

Look for a fix in 0.0.4... In the meantime, keys generated using 'ssh-keygen -t rsa' should work fine. (If they don't, let me know, because they work for me.)

···

--
Jamis Buck
jgb3@email.byu.edu
http://www.jamisbuck.org/jamis

"I use octal until I get to 8, and then I switch to decimal."

well, what if you have multiple local interfaces ?

···

il Mon, 12 Jul 2004 22:50:51 +0900, Jamis Buck <jgb3@email.byu.edu> ha scritto::

Martin DeMello wrote:

Jamis Buck <jgb3@email.byu.edu> wrote:

  manager.cancel_forward_local( 12345, '1.2.3.4', 1122 )
  manager.forward_local( 12345, '1.2.3.5', 1122)

Possibly stupid question - why's this not cancel_forward_local(12345)?
Can a single local port be bound to multiple remote ports?

An excellent point, Martin. It seems like there was a compelling reason
to do it the way I did...but I just woke up and can't seem to pull it
from the fog.

Ok, I build myself a pair of rsa keys and now it works.

Btw. thank you very much for net-ssh!! It really rocks!!

···

Woops. My bad. Apparently you can't use public/private key
authentication using a dsa key right now. I'll work on that. I just need
to not use the 'sign' method of the key object, since that doesn't work
for all key types...

Look for a fix in 0.0.4... In the meantime, keys generated using
'ssh-keygen -t rsa' should work fine. (If they don't, let me know,
because they work for me.)

gabriele renzi wrote:

il Mon, 12 Jul 2004 22:50:51 +0900, Jamis Buck <jgb3@email.byu.edu> ha
scritto::

Martin DeMello wrote:

manager.cancel_forward_local( 12345, '1.2.3.4', 1122 )
manager.forward_local( 12345, '1.2.3.5', 1122)

Possibly stupid question - why's this not cancel_forward_local(12345)?
Can a single local port be bound to multiple remote ports?

An excellent point, Martin. It seems like there was a compelling reason to do it the way I did...but I just woke up and can't seem to pull it

from the fog.

well, what if you have multiple local interfaces ?

Hmmm. I'm pretty sure that wasn't the compelling reason I had thought of, but it is compelling. Would support for multiple local interfaces be a good thing? Or would that overly complicate the Net::SSH interface?

···

Jamis Buck <jgb3@email.byu.edu> wrote:

--
Jamis Buck
jgb3@email.byu.edu
http://www.jamisbuck.org/jamis

"I use octal until I get to 8, and then I switch to decimal."

I think that multiple interface may be needed, but maybe not.
But It just fits perfectly with a default argument to let the
interface unchanged :slight_smile:

···

il Tue, 13 Jul 2004 07:25:28 +0900, Jamis Buck <jgb3@email.byu.edu> ha scritto::

Hmmm. I'm pretty sure that wasn't the compelling reason I had thought
of, but it is compelling. Would support for multiple local interfaces be
a good thing? Or would that overly complicate the Net::SSH interface?

What does forwarding a local port to several remote ports even mean?
Can it be done with 'ssh'? I think this question has been asked but
not answered.

Gavin

···

On Tuesday, July 13, 2004, 5:32:22 PM, gabriele wrote:

il Tue, 13 Jul 2004 07:25:28 +0900, Jamis Buck <jgb3@email.byu.edu> ha
scritto::

Hmmm. I'm pretty sure that wasn't the compelling reason I had thought
of, but it is compelling. Would support for multiple local interfaces be
a good thing? Or would that overly complicate the Net::SSH interface?

I think that multiple interface may be needed, but maybe not.
But It just fits perfectly with a default argument to let the
interface unchanged :slight_smile:

Gavin Sinclair wrote:

What does forwarding a local port to several remote ports even mean?
Can it be done with 'ssh'? I think this question has been asked but
not answered.

I'm pretty certain it cannot be done with 'ssh'. I, too, can't quite grasp what that would accomplish. I'm thinking I'll reduce the arguments of "cancel_forward_local" to simply the port that is being forwarded, to keep the interface simple.

If anyone has any strong arguments as to why that should not be done, please let me know. Support for multiple network interfaces would be interesting, but not perhaps practical. If it ever becomes an issue, perhaps I could create some "special-purpose" methods for that. I'd like to keep the common case simple, though.

···

--
Jamis Buck
jgb3@email.byu.edu
http://www.jamisbuck.org/jamis

"I use octal until I get to 8, and then I switch to decimal."

Why not just have the IP address be an optional call to the
forward/cancel_forward methods? It could default to '0.0.0.0' (or
similar), meaning 'all interfaces'.

Lennon

···

On Tue, 13 Jul 2004 23:49:54 +0900, Jamis Buck <jgb3@email.byu.edu> wrote:

Gavin Sinclair wrote:
> What does forwarding a local port to several remote ports even mean?
> Can it be done with 'ssh'? I think this question has been asked but
> not answered.

I'm pretty certain it cannot be done with 'ssh'. I, too, can't quite
grasp what that would accomplish. I'm thinking I'll reduce the arguments
of "cancel_forward_local" to simply the port that is being forwarded, to
keep the interface simple.

If anyone has any strong arguments as to why that should not be done,
please let me know. Support for multiple network interfaces would be
interesting, but not perhaps practical. If it ever becomes an issue,
perhaps I could create some "special-purpose" methods for that. I'd like
to keep the common case simple, though.

--
Jamis Buck
jgb3@email.byu.edu
http://www.jamisbuck.org/jamis

"I use octal until I get to 8, and then I switch to decimal."

Of course I mean the local IP address...not much use in trying to
guess the remote address!

Lennon

···

On Tue, 13 Jul 2004 11:28:24 -0700, Lennon Day-Reynolds <rcoder@gmail.com> wrote:

Why not just have the IP address be an optional call to the
forward/cancel_forward methods? It could default to '0.0.0.0' (or
similar), meaning 'all interfaces'.

Lennon

On Tue, 13 Jul 2004 23:49:54 +0900, Jamis Buck <jgb3@email.byu.edu> wrote:
> Gavin Sinclair wrote:
> > What does forwarding a local port to several remote ports even mean?
> > Can it be done with 'ssh'? I think this question has been asked but
> > not answered.
>
> I'm pretty certain it cannot be done with 'ssh'. I, too, can't quite
> grasp what that would accomplish. I'm thinking I'll reduce the arguments
> of "cancel_forward_local" to simply the port that is being forwarded, to
> keep the interface simple.
>
> If anyone has any strong arguments as to why that should not be done,
> please let me know. Support for multiple network interfaces would be
> interesting, but not perhaps practical. If it ever becomes an issue,
> perhaps I could create some "special-purpose" methods for that. I'd like
> to keep the common case simple, though.
>
>
>
> --
> Jamis Buck
> jgb3@email.byu.edu
> http://www.jamisbuck.org/jamis
>
> "I use octal until I get to 8, and then I switch to decimal."
>
>

Lennon Day-Reynolds wrote:

Why not just have the IP address be an optional call to the
forward/cancel_forward methods? It could default to '0.0.0.0' (or
similar), meaning 'all interfaces'.

Lennon

That's a good idea. However, it would mean the local port would be the first parameter, and the local interface would be the last parameter (since it is optional)...

OR (duh) I guess I could say: if 3 parameters, then the local interface would be the default, and if 4 parameters then the local interface is the second parameter...

Hmmm. That's not hard at all to do. Thanks, Lennon!

The cancel_forward_local method would then accept one required parameter, and one optional parameter: the local port, and local interface.

···

--
Jamis Buck
jgb3@email.byu.edu
http://www.jamisbuck.org/jamis

"I use octal until I get to 8, and then I switch to decimal."