ANN: ssh2 module

1,209 views
Skip to first unread message

mscdex

unread,
Nov 11, 2012, 6:00:07 PM11/11/12
to nodejs
Hello all!

I'm announcing the first version of my ssh2 module, now available on
npm.

ssh2 aims to be a complete SSH2 client written in pure JavaScript that
implements the SSH2 protocol (it does not shell out to a command-line
ssh client).

Currently it can execute one-off commands and start interactive shell
sessions. There are still several things to be implemented and
tweaked, but I think it's at least in a fairly usable and stable state
now.

Feel free to give it a whirl and report any bugs you may come across.


https://github.com/mscdex/ssh2 (`npm install ssh2`)

Alex Kocharin

unread,
Nov 11, 2012, 6:12:55 PM11/11/12
to nod...@googlegroups.com
Hi mscdex,


What about the server part? I've seen plenty of ssh clients, but I couldn't find an appropriate node ssh server module, so that could be useful.

--
// alex

12.11.2012, 03:00, "mscdex" <msc...@gmail.com>:
> --
> Job Board: http://jobs.nodejs.org/
> Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> You received this message because you are subscribed to the Google
> Groups "nodejs" group.
> To post to this group, send email to nod...@googlegroups.com
> To unsubscribe from this group, send email to
> nodejs+un...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/nodejs?hl=en?hl=en

mscdex

unread,
Nov 11, 2012, 6:59:26 PM11/11/12
to nodejs
On Nov 11, 6:13 pm, Alex Kocharin <a...@kocharin.ru> wrote:
> What about the server part? I've seen plenty of ssh clients, but I couldn't find an appropriate node ssh server module, so that could be useful.

I'm not really interested in writing an SSH server. Also, the other
SSH clients that are out there currently merely spin up 'ssh' as a
child process which isn't very efficient or easy to work with. My ssh2
module implements the SSH 2.0 protocol itself, so there are no child
processes involved.

Nathan Rajlich

unread,
Nov 11, 2012, 8:25:37 PM11/11/12
to nod...@googlegroups.com
Very nice stuff Brian!

dhruvbird

unread,
Nov 11, 2012, 11:24:36 PM11/11/12
to nod...@googlegroups.com
Really interesting - and useful!

Curious to know why you need both pub & priv key instead of just the priv-key.

mscdex

unread,
Nov 12, 2012, 1:23:28 AM11/12/12
to nodejs
On Nov 11, 11:24 pm, dhruvbird <dhruvb...@gmail.com> wrote:
> Curious to know why you need both pub & priv key instead of just the
> priv-key.

Currently AFAIK there is no way to generate a public key from a
private key with the existing crypto API. With that in mind, I am
planning on eventually doing the required calculations myself, but
there are other items on the TODO that have a higher priority at the
moment.
Message has been deleted

mscdex

unread,
Nov 15, 2012, 9:25:11 AM11/15/12
to nodejs
v0.0.2 is now out on npm and supports more functionality, including:

* port/connection forwarding in both directions

* sending local terminal window resize notifications to the server

* sending POSIX signals to the server

* encrypted private keys

* stream cipher support

Tim Caswell

unread,
Nov 15, 2012, 12:24:18 PM11/15/12
to nod...@googlegroups.com
Great work!  I've been wanting something like this for a long time.  One quick question though.  Is it possible to both spawn a child process and use it's stdio as raw binary data (no tty metadata) *and* spawn a tty powered child (like bash -l) in the same connection?  I never could find a way to do this with shelling out to ssh, but maybe by implementing the protocol you have more flexibility is what can be done.


mscdex

unread,
Nov 15, 2012, 4:20:50 PM11/15/12
to nodejs
On Nov 15, 12:24 pm, Tim Caswell <t...@creationix.com> wrote:
> Great work!  I've been wanting something like this for a long time.  One
> quick question though.  Is it possible to both spawn a child process and
> use it's stdio as raw binary data (no tty metadata) *and* spawn a tty
> powered child (like bash -l) in the same connection?  I never could find a
> way to do this with shelling out to ssh, but maybe by implementing the
> protocol you have more flexibility is what can be done.

Yes, all of the functionality you see can be done within the same
connection to the server because SSH2 allows multiplexing. For
example, you could have 10 ptys open while executing 75 child
processes and forwarding connections to the server.

Matt

unread,
Nov 15, 2012, 5:04:21 PM11/15/12
to nod...@googlegroups.com
You can reuse the same connection with the ssh binary using this in your .ssh/config:

  ControlMaster auto
  ControlPath /tmp/ssh_mux_%h_%p_%r

The second time you connect to the same host it will re-use the open connection. Including if you do scp/rsync -e ssh.

(I know that doesn't quite answer your question, but it's a useful tidbit a lot of people don't know)

mscdex

unread,
Nov 18, 2012, 4:38:33 PM11/18/12
to nodejs
v0.1.0 is now out on npm and includes support for SFTP (protocol
version 3 -- what OpenSSH uses (and others use at a minimum)).

mscdex

unread,
Nov 27, 2012, 9:48:16 AM11/27/12
to nodejs
v0.1.3 is now out on npm and includes support for ssh-agent
authentication, host fingerprint verification, and automatic
generation of the public key from a private key.

Charlie Robbins

unread,
Nov 27, 2012, 10:17:24 AM11/27/12
to nod...@googlegroups.com
Very nice work mscdex. I owe you a case of beer. Seriously.


mscdex

unread,
Dec 13, 2012, 3:29:28 PM12/13/12
to nodejs
v0.1.8 is now out on npm. Highlights since v0.1.3:

* Various bug fixes
* SFTP has createReadStream and createWriteStream now
* Keepalive support

Also, I wrote a fairly simple little script that uses ssh2 to exec()
on multiple servers in parallel for those who may be interested:
https://gist.github.com/4279365. I've been using it myself to easily
perform one-off tasks like git pulls, updating node, etc.

马涛

unread,
Dec 13, 2012, 10:35:02 PM12/13/12
to nodejs, msc...@gmail.com
thanks, and how to enable dynamic forward port like "ssh -D1080", can you give a demo ?


2012/12/14 mscdex <msc...@gmail.com>

mscdex

unread,
Dec 13, 2012, 10:57:15 PM12/13/12
to nodejs
On Dec 13, 10:35 pm, 马涛 <iwa...@gmail.com> wrote:
> thanks, and how to enable dynamic forward port like "ssh -D1080", can you
> give a demo ?

Dynamic port forwarding is not something that is supported by this
module. Basically what that requires is writing a SOCKS proxy
implementation -- something that's really outside the scope of this
project. Once you write that (there may be some SOCKS modules worth
looking at on npm), you can easily hook it up to this module and
initiate the outbound connections using forwardOut() and then piping
the data.

马涛

unread,
Dec 14, 2012, 3:52:35 AM12/14/12
to nodejs
thanks, I‘ll try that


2012/12/14 mscdex <msc...@gmail.com>

mscdex

unread,
Mar 4, 2013, 2:03:00 PM3/4/13
to nodejs
On Mar 4, 12:09 pm, Mark Cantrell <mark.e.cantr...@gmail.com> wrote:
>         c.forwardOut('localhost', 8089, 'skynetHost', 8080, function(err,
> stream) {

Does it work if you use IP addresses instead of hostnames?

Also what do you mean by it doesn't work? Is an error thrown? Are
certain callbacks not executed?

Mark Cantrell

unread,
Apr 9, 2013, 9:56:23 AM4/9/13
to nod...@googlegroups.com
Once we switched sshd back to 22 instead of 443 then everything 'worked' as expected.  The forwarded port was now available locally.

When using 443 there were no errors, but the forwarded port did not respond or show up in netstat.  It could have been something in our network.  sshd was running on ubuntu server.  Once again switching to 22 seems to have resolved whatever the issue was.


Thanks!
Mark

Mark Cantrell

unread,
Apr 23, 2013, 9:02:34 AM4/23/13
to nod...@googlegroups.com
Update:443 works fine now too, using ips seems to have resolved whatever the issue was.

Jochen Delabie

unread,
Apr 30, 2013, 2:27:14 PM4/30/13
to nod...@googlegroups.com
Would be nice if there was a nodejs ssh server, so we can use it to run tests against.

mscdex

unread,
Apr 30, 2013, 2:47:16 PM4/30/13
to nodejs
On Apr 30, 2:27 pm, Jochen Delabie <jochendela...@gmail.com> wrote:
> Would be nice if there was a nodejs ssh server, so we can use it to run
> tests against.

FWIW here is one that is seeing some active development:
https://github.com/danopia/sshd.js

mscdex

unread,
Apr 30, 2013, 2:49:51 PM4/30/13
to nodejs

cesdaile

unread,
Oct 8, 2014, 8:55:43 PM10/8/14
to nod...@googlegroups.com
Hoping someone may have an example using ssh2 where they are receiving cli output from a remote server that requires interaction - for example the output in a paged format by default.

Typical space to move forward a page as shown below:

--More-- (q) quit (u) pageup (/) search (n) repeat

I attempted to set the server to not page but I am finding the ssh2 client is choking on the output when there is more than 500 lines being returned so I am reconsidering going interactive and trying to page through the data as required.

I am using the conn.shell(function(err, stream) to setup an interactive session but I am not clear on how to expect the paging prompt and then stream.write(' ') to continue the paging through the output data.

mscdex

unread,
Oct 9, 2014, 8:11:13 AM10/9/14
to nod...@googlegroups.com
On Wednesday, October 8, 2014 8:55:43 PM UTC-4, cesdaile wrote:

I attempted to set the server to not page but I am finding the ssh2 client is choking on the output when there is more than 500 lines being returned so I am reconsidering going interactive and trying to page through the data as required.


Can you explain what you mean by "choking on the output"? This gist[1] works for me.

[1] https://gist.github.com/anonymous/3954981240f92b2df32b

cesdaile

unread,
Oct 10, 2014, 1:46:41 AM10/10/14
to nod...@googlegroups.com
Thanks for the pointer on how to handle the paged output. I will definitely give this a try but my preference would be to process the entire command output with paging disabled on the server.

What I meant by 'choking' is that I am seeing a premature close on the stream when the output exceeds approx. 400 lines. Smaller output sizes seem to complete reliably and I can parse the entire command output without any troubles.

I am seeing the following logs to console based off some of the examples posted on github:

Stream :: exit :: code: 1, signal: undefined


Stream :: close 


Hoping you can spot what i am missing in my setup on the ssh2 client below.

mscdex

unread,
Oct 10, 2014, 8:04:04 AM10/10/14
to nod...@googlegroups.com
On Friday, October 10, 2014 1:46:41 AM UTC-4, cesdaile wrote:
What I meant by 'choking' is that I am seeing a premature close on the stream when the output exceeds approx. 400 lines. Smaller output sizes seem to complete reliably and I can parse the entire command output without any troubles.

I haven't experienced that at all. Are you using the latest version of ssh2?

Also, I don't think you need to use `shell()` for your purposes. I think `exec()` should work fine, you just have to prefix your actual command with "no paging;" (assuming that is a valid remote command) since it seems like that's what you're currently trying to do. Your script should be something as simple as this (substituting the 'cat /var/log/messages' with your `cmd` variable): https://gist.github.com/anonymous/1a786c62927c632a23ed

cesdaile

unread,
Oct 10, 2014, 4:29:50 PM10/10/14
to nod...@googlegroups.com
Yep on the current version of ssh2 - just installed this week.

Ok - I think I am closer to figuring this out now with your help.

The code on your gist works just as expected on a regular centos host but when I try it against my target server the exec option does trigger. The difference I suspect is that my target server is an embedded device and maybe it has some funky terminal settings I am not accounting for.

The ssh login presents a banner and prompt as follows:

Last login: Fri Oct 10 12:19:01 2014 from 10.240.106.106



(console) #


I seem to only have success when using shell and performing a stream.write with \n to execute the desired commands.

Jeremy Darling

unread,
Oct 10, 2014, 6:39:12 PM10/10/14
to nodejs
You may have to specify your shell on your embedded device.  What device and shell are you using?

You received this message because you are subscribed to the Google Groups "nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nodejs+un...@googlegroups.com.
To post to this group, send email to nod...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/ad22bb9e-804c-4aab-8b06-6bc81989a682%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Louis Santillan

unread,
Oct 10, 2014, 7:41:45 PM10/10/14
to nod...@googlegroups.com
Also, if you're using a board with a new/exotic BSP, exec() (in libc)
may not be implemented fully or may be simply stubbed for cross
compilation.
> https://groups.google.com/d/msgid/nodejs/CAAhs7EiCNQ2L0PJvvmJ%2B7%2BDoKo1MwgpxyauqV0uhOqe98yyBUA%40mail.gmail.com.

cesdaile

unread,
Oct 11, 2014, 2:23:25 PM10/11/14
to nod...@googlegroups.com
The target server is a network firewall from Aruba - similar to a Cisco IOS cli. I am trying to figure out what shell it presents to the ssh session.

I am hoping once I have this information i can match the settings in the {pty . . .} object as part of the conn.shell() or conn.exec() cal

Aria Stewart

unread,
Oct 11, 2014, 3:38:59 PM10/11/14
to nod...@googlegroups.com

> On 11 Oct 2014, at 14:23, cesdaile <cesd...@gmail.com> wrote:
>
> The target server is a network firewall from Aruba - similar to a Cisco IOS cli. I am trying to figure out what shell it presents to the ssh session.
>
> I am hoping once I have this information i can match the settings in the {pty . . .} object as part of the conn.shell() or conn.exec()cal


Ah, I wondered if that was a router you were connecting to.

Does it support both shell and exec?

Louis Santillan

unread,
Oct 11, 2014, 6:09:02 PM10/11/14
to nod...@googlegroups.com
It is very likely that your router has its user's shell pointed at  /bin/false or /sbin/nologin.
--
Job board: http://jobs.nodejs.org/
New group rules: https://gist.github.com/othiym23/9886289#file-moderation-policy-md
Old group rules: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
---
You received this message because you are subscribed to the Google Groups "nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nodejs+un...@googlegroups.com.
To post to this group, send email to nod...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/EE4F7244-4425-45A7-BC9F-4F9B757FBC91%40nbtsc.org.
Reply all
Reply to author
Forward
0 new messages