Host-based ssh authentication using nodejs - node.js

I have installed the ssh2 package for node but can not get the host based authentication working.
var Connection = require('./node_modules/bis-package/node_modules/ssh2');
var conn = new Connection();
conn.on('ready', function() {
conn.exec('cmviewcl -v -f line', function(err, stream) {
if (err) throw err;
stream.on('exit', function(code, signal) {
console.log('Stream :: exit :: code: ' + code + ', signal: ' + signal);
}).on('close', function() {
console.log('Stream :: close');
conn.end();
}).on('data', function(data) {
console.log('STDOUT: ' + data);
}).stderr.on('data', function(data) {
console.log('STDERR: ' + data);
});
});
}).connect({
host: 'server',
port: 22,
username: 'root'
});
I get the following error
Error: Authentication failure. Available authentication methods: publickey,gssapi-with-mic,password,hostbased
at Connection._tryNextAuth (/opt/bis/node/node_modules/bis-package/node_modules/ssh2/lib/Connection.js:1010:13)
at onUSERAUTH_FAILURE (/opt/bis/node/node_modules/bis-package/node_modules/ssh2/lib/Connection.js:2449:8)
at Parser.<anonymous> (/opt/bis/node/node_modules/bis-package/node_modules/ssh2/lib/Connection.js:141:5)
at Parser.emit (events.js:98:17)
at Parser.parsePacket (/opt/bis/node/node_modules/bis-package/node_modules/ssh2/lib/Parser.js:488:12)
at Parser.execute (/opt/bis/node/node_modules/bis-package/node_modules/ssh2/lib/Parser.js:249:14)
at Socket.<anonymous> (/opt/bis/node/node_modules/bis-package/node_modules/ssh2/lib/Connection.js:536:18)
at Socket.emit (events.js:95:17)
at Socket.<anonymous> (_stream_readable.js:748:14)
at Socket.emit (events.js:92:17)
We use host based authentication which allows us password free logins. In Perl I use the following:
my( $SSH ) = "/usr/bin/ssh -t -o PreferredAuthentications=hostbased 2>/dev/null";
$run->run( map { qq{$SSH $_ "$CMD"} } #hosts );
I am not sure how I could do that with the nodejs ssh2 package.
Any idea how I could do that?

There is no support for hostbased authentication yet. I plan to add support for it in the upcoming next major release. The relevant issue is here.

Related

Download from FTP with Node JS

I need help downloading more than one file from a remote FTP using Node js, the code is the following.
const FTPClient = require('ftp');
let ftp_client = new FTPClient();
const fs = require("fs");
let ftpConfig = {
host: "remoteHost",
port: 21,
user: 'username',
password: 'password',
}
//create a connection to ftp server
ftp_client.connect(ftpConfig);
ftp_client.on('ready', function() {
ftp_client.get('/file1.csv', function(err, stream) {
if (err) throw err;
//stream.once('close', function() { ftp_client.end(); });
stream.pipe(fs.createWriteStream('file1.csv'));
});
ftp_client.get('/dir/file2.dat', function(err, stream) {
if (err) throw err;
//stream.once('close', function() { ftp_client.end(); });
stream.pipe(fs.createWriteStream('file2.dat'));
});
ftp_client.get('/dir/file3.dat', function(err, stream) {
if (err) throw err;
stream.once('close', function() { ftp_client.end(); });
stream.pipe(fs.createWriteStream('file3.dat'));
});
});
And the error
Error: Unable to make data connection
at Socket.<anonymous> (C:\Proyectos\descargar_file\node_modules\ftp\lib\connection.js:935:10)
at Object.onceWrapper (events.js:421:28)
at Socket.emit (events.js:327:22)
at Object.cb (C:\Proyectos\descargar_file\node_modules\ftp\lib\connection.js:575:18)
at Parser.<anonymous> (C:\Proyectos\descargar_file\node_modules\ftp\lib\connection.js:117:20)
at Parser.emit (events.js:315:20)
at Parser._write (C:\Proyectos\descargar_file\node_modules\ftp\lib\parser.js:59:10)
at doWrite (_stream_writable.js:403:12)
at writeOrBuffer (_stream_writable.js:387:5)
at Parser.Writable.write (_stream_writable.js:318:11)
It is already downloading the 3 files, but also showing that error, so how can I correct this to do it in a safer way?
I also would like to add a console log while the process is downloading each file.
Thanks!

cannot connect to Gmail using imap

I am trying to view the contents of the emails received in my gmail inbox using imap but when I'm running the code, I am getting the following error.
ERROR
Error [ERR_STREAM_DESTROYED]: Cannot call write after a stream was destroyed
at doWrite (_stream_writable.js:427:19)
at clearBuffer (_stream_writable.js:551:7)
at Socket.Writable.uncork (_stream_writable.js:325:7)
at JSStreamSocket.doWrite (internal/js_stream_socket.js:162:17)
at JSStream.onwrite (internal/js_stream_socket.js:20:57)
at Socket.ondata (internal/js_stream_socket.js:64:22)
at Socket.emit (events.js:210:5)
at addChunk (_stream_readable.js:309:12)
at readableAddChunk (_stream_readable.js:290:11)
at Socket.Readable.push (_stream_readable.js:224:10) {
code: 'ERR_STREAM_DESTROYED',
source: 'socket'
}
events.js:187
throw er; // Unhandled 'error' event
^
Error: self signed certificate
at TLSSocket.onConnectSecure (_tls_wrap.js:1321:34)
at TLSSocket.emit (events.js:210:5)
at TLSSocket._finishInit (_tls_wrap.js:794:8)
at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:608:12)
at Socket.ondata (internal/js_stream_socket.js:64:22)
at Socket.emit (events.js:210:5)
at addChunk (_stream_readable.js:309:12)
at readableAddChunk (_stream_readable.js:290:11)
at Socket.Readable.push (_stream_readable.js:224:10)
at TCP.onStreamRead (internal/stream_base_commons.js:182:23)
Emitted 'error' event on Connection instance at:
at TLSSocket._onError (C:\Users\debdutgoswami\node_modules\imap\lib\Connection.js:151:10)
at TLSSocket.emit (events.js:210:5)
at emitErrorNT (internal/streams/destroy.js:92:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
code: 'DEPTH_ZERO_SELF_SIGNED_CERT',
source: 'socket'
}
CODE
var Imap = require('imap'),
inspect = require('util').inspect;
var imap = new Imap({
user: 'mygmailname#gmail.com',
password: 'mygmailpassword',
host: 'imap.gmail.com',
port: 993,
tls: true
});
function openInbox(cb) {
imap.openBox('INBOX', true, cb);
}
imap.once('ready', function() {
openInbox(function(err, box) {
if (err) throw err;
var f = imap.seq.fetch('1:3', {
bodies: 'HEADER.FIELDS (FROM TO SUBJECT DATE)',
struct: true
});
f.on('message', function(msg, seqno) {
console.log('Message #%d', seqno);
var prefix = '(#' + seqno + ') ';
msg.on('body', function(stream, info) {
var buffer = '';
stream.on('data', function(chunk) {
buffer += chunk.toString('utf8');
});
stream.once('end', function() {
console.log(prefix + 'Parsed header: %s', inspect(Imap.parseHeader(buffer)));
});
});
msg.once('attributes', function(attrs) {
console.log(prefix + 'Attributes: %s', inspect(attrs, false, 8));
});
msg.once('end', function() {
console.log(prefix + 'Finished');
});
});
f.once('error', function(err) {
console.log('Fetch error: ' + err);
});
f.once('end', function() {
console.log('Done fetching all messages!');
imap.end();
});
});
});
imap.once('error', function(err) {
console.log(err);
});
imap.once('end', function() {
console.log('Connection ended');
});
imap.connect();
I had the same issue for quite a long while... The real problem here is that, there is a complaint for self signed certificate and I got a way out. Just under your tls: true which is the self signed certificate, inside your var imap= new imap({ //inside here }) add a line: tlsOptions: { rejectUnauthorized: false } And you're good to go, the rest of the code is correct
You may also have to allow "less secure apps" on the account, see https://myaccount.google.com/lesssecureapps
I also have an issue and I just discovered that Google had disable "less secure apps" since june 2022.
Simple user/password login to GMAIL has been disabled for good.
I had same issue and resovled it by:
Google setting:
Enable two factor authtentification
generate application password
Gmail settings:
Enable IMAP in gmail settings
names could be little bit different as I was not using english version of google so the "names" are my translation ...

How to make a SSH to postgres server with help of ssh2 library and query using pg libary?

I am trying to make a connection to Postgres remote host using the SSH tunnel from node application(library:ssh2) and query the data(lib:pg).
Before I used mysql2(node library) make a tunnel using ssh2(node library) and connected to Mysql remote host as well as able to query the data. But I want to do the same in Postgres remote host I am not able to connect to it.
pg Client obj config does not support the stream from ssh2 forwardOut..!
Or, Is there any library available to make this happen instead of that ssh2, pg
PS: In mysql2 when I try to make a connection with a mysql config with stream: stream key value.
var Clientssh = require('ssh2').Client;
var conn = new Clientssh();
conn.on('ready', function() {
console.log('Client :: ready');
conn.forwardOut(
'127.0.0.1',
5434,
'localhost',
5432,
function(err, stream) {
if (err) throw err;
let conf = {
host: 'localhost',
port: 5434,
user: 'test',
database: 'test',
password: 'test'
}
let remoteConnection = new Client(conf);
remoteConnection.connect(function(err) {
if (err) {
console.log(err);
console.log("Unable to connect to postgre");
res.send(err);
} else {
remoteConnection.query('SELECT * FROM test', function(err, testResult) {
remoteConnection.end();
if (err) {
console.log("Unable to fetch data");
res.send(err);
} else {
console.log("Succcess");
res.send(testResult);
}
});
}
});
});
}).connect({
host: 'hostaddress',
port: 'hostport',
username: 'hostusername',
privateKey: require('fs').readFileSync('path/for/key')
});
It shows the Connection terminated unexpectedly from this line
Client :: ready
Error: Connection terminated unexpectedly
at Connection.con.once (/node-postgres/node_modules/pg/lib/client.js:235:9)
at Object.onceWrapper (events.js:286:20)
at Connection.emit (events.js:198:13)
at Channel.<anonymous> (/node-postgres/node_modules/pg/lib/connection.js:131:10)
at Channel.emit (events.js:203:15)
at endReadableNT (_stream_readable.js:1129:12)
at process._tickCallback (internal/process/next_tick.js:63:19)
Unable to connect to postgre

npm package to ssh to a server without password nodejs

I am using ssh2 package to ssh to a server.
By default when I connect to the server from cmd line, I don't have to pass in the password as we have ssh keys shared.
I connect at ssh abcuser#server and I am automatically connected.
But using ssh2, if I dont give password, it complains saying - Error: All configured authentication methods failed
Below is my code-
conn.exec(request.scriptName, function(err, stream) {
if(err){
logger.error('Failed to execute via ssh. ERROR: '+ err);
logger.exitAfterFlush(1);
}
stream.on('close', function(code, signal) {
conn.end();
}).on('data', function(data) {
let outputJson = JSON.parse(data.toString());
logger.info('Task Succeeded', {'output':outputJson});
logger.exitAfterFlush(0);
}).stderr.on('data', function(data) {
let details = {'details':data.toString()};
logger.error('Task Failed',{'output':details});
logger.exitAfterFlush(1);
});
});
}).connect({
host: request.hostName,
port: 22,
username: abcuser
});
Can anyone suggest how I can resolve this?

Using npm package ssh2 within an Angular2 application running under electron

I want to create an Angular2 service which uses the npm package ssh2 - https://www.npmjs.com/package/ssh2.
I have installed and configured it as I would expect - the code for my service can be seen below (this code is based on the first example shown on the ssh2 npm site and github repo(the only change being I am using a password rather than a key for authentication)):
const Client = require('ssh2').Client;
const fs = require('fs');
import { NextObserver } from 'rxjs/Observer';
import { Observable } from 'rxjs/Rx';
export class SSHClient {
username: string;
password: string;
host: string;
port: number;
ssh: any;
constructor() {
}
init(username, password, host, port) {
console.log("initiating SSH connection to:" + host + "on port:" + port);
this.username = username;
this.password = password;
this.host = host;
this.port = port;
console.log("Connecting now...");
var conn = new Client();
conn.on('ready', function() {
console.log('Client :: ready');
conn.exec('uptime', function(err, stream) {
if (err) throw err;
stream.on('close', function(code, signal) {
console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
conn.end();
}).on('data', function(data) {
console.log('STDOUT: ' + data);
}).stderr.on('data', function(data) {
console.log('STDERR: ' + data);
});
});
}).connect({
host: this.host,
port: this.port,
username: this.username,
password: this.password
});
console.log("SSH Client created and demo has run");
}
}
I make my call to the service as per this from within my component:
this.ssh.init("username","password","my.little.host",22);
And I expect to get back the output of the uptime command having executed over SSH on my server - via the console. However instead of that - I get this:
EXCEPTION: Uncaught (in promise): Error: Error in ./ServerBrowserComponent class ServerBrowserComponent_Host - inline template:0:0 caused by: Cannot read property 'connect' of undefined
TypeError: Cannot read property 'connect' of undefined
at SSHClient.init (file:///Users/myapp/build/app.js:40259:12)
at new ServerBrowserComponent (file:///Users/myapp/build/app.js:34158:19)
at new Wrapper_ServerBrowserComponent (/AppModule/ServerBrowserComponent/wrapper.ngfactory.js:7:18)
at DebugAppView._View_ServerBrowserComponent_Host0.createInternal (/AppModule/ServerBrowserComponent/host.ngfactory.js:16:38)
at DebugAppView.AppView.create (file:///Users/myapp/build/app.js:27754:26)
at DebugAppView.create (file:///Users/myapp/build/app.js:27954:49)
at ComponentFactory.create (file:///Users/myapp/build/app.js:24393:41)
at ViewContainerRef_.createComponent (file:///Users/myapp/build/app.js:23441:50)
at RouterOutlet.activate (file:///Users/myapp/build/app.js:72709:45)
at ActivateRoutes.placeComponentIntoOutlet (file:///Users/myapp/build/app.js:72207:21)
ORIGINAL STACKTRACE:
Error: Uncaught (in promise): Error: Error in ./ServerBrowserComponent class ServerBrowserComponent_Host - inline template:0:0 caused by: Cannot read property 'connect' of undefined
TypeError: Cannot read property 'connect' of undefined
at SSHClient.init (ssh.service.ts:49)
at new ServerBrowserComponent (server.browser.component.ts:31)
at new Wrapper_ServerBrowserComponent (wrapper.ngfactory.js:7)
at DebugAppView._View_ServerBrowserComponent_Host0.createInternal (host.ngfactory.js:16)
at DebugAppView.AppView.create (core.umd.js:9170)
at DebugAppView.create (core.umd.js:9370)
at ComponentFactory.create (core.umd.js:5809)
at ViewContainerRef_.createComponent (core.umd.js:4857)
at RouterOutlet.activate (router.umd.js:3457)
at ActivateRoutes.placeComponentIntoOutlet (router.umd.js:2955)
at resolvePromise (zone-node.js:468)
at zone-node.js:445
at ZoneDelegate.invoke (zone-node.js:232)
at Object.onInvoke (core.umd.js:6206)
at ZoneDelegate.invoke (zone-node.js:231)
at Zone.run (zone-node.js:114)
at zone-node.js:502
at ZoneDelegate.invokeTask (zone-node.js:265)
at Object.onInvokeTask (core.umd.js:6197)
at ZoneDelegate.invokeTask (zone-node.js:264)
Unhandled Promise rejection: Error in ./ServerBrowserComponent class ServerBrowserComponent_Host - inline template:0:0 caused by: Cannot read property 'connect' of undefined ; Zone: angular ; Task: Promise.then ; Value: ViewWrappedError TypeError: Cannot read property 'connect' of undefined
at SSHClient.init (file:///Users/myapp/build/app.js:40259:12)
at new ServerBrowserComponent (file:///Users/myapp/build/app.js:34158:19)
at new Wrapper_ServerBrowserComponent (/AppModule/ServerBrowserComponent/wrapper.ngfactory.js:7:18)
at DebugAppView._View_ServerBrowserComponent_Host0.createInternal (/AppModule/ServerBrowserComponent/host.ngfactory.js:16:38)
at DebugAppView.AppView.create (file:///Users/myapp/build/app.js:27754:26)
at DebugAppView.create (file:///Users/myapp/build/app.js:27954:49)
at ComponentFactory.create (file:///Users/myapp/build/app.js:24393:41)
at ViewContainerRef_.createComponent (file:///Users/myapp/build/app.js:23441:50)
at RouterOutlet.activate (file:///Users/myapp/build/app.js:72709:45)
at ActivateRoutes.placeComponentIntoOutlet (file:///Users/myapp/build/app.js:72207:21)
Error: Uncaught (in promise): Error: Error in ./ServerBrowserComponent class ServerBrowserComponent_Host - inline template:0:0 caused by: Cannot read property 'connect' of undefined(…)
The bulk of that seems to be struggling because : Cannot read property 'connect' of undefined -- yet I am following the example documentation. Can somebody please help my understand why this is not working - and how I can fix it?
I tried to pull the code out of my project and into its own file which looks like:
const Client = require('ssh2').Client;
console.log("Connecting now...");
var conn = new Client();
conn.on('ready', function() {
console.log('Client :: ready');
conn.exec('uptime', function(err, stream) {
if (err) throw err;
stream.on('close', function(code, signal) {
console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
conn.end();
}).on('data', function(data) {
console.log('STDOUT: ' + data);
}).stderr.on('data', function(data) {
console.log('STDERR: ' + data);
});
});
}).connect({
host: 'my.little.host',
port: 22,
username: 'uname',
password: 'pwd'
});
console.log("SSH Client created and demo has run");
But I get the same error:
var conn = new Client();
^
ReferenceError: Client is not defined
at Object.<anonymous> (/Users/myapp/attempt.js:2:21)
at Module._compile (module.js:541:32)
at Object.Module._extensions..js (module.js:550:10)
at Module.load (module.js:458:32)
at tryModuleLoad (module.js:417:12)
at Function.Module._load (module.js:409:3)
at Module.runMain (module.js:575:10)
at run (node.js:348:7)
at startup (node.js:140:9)
at node.js:463:3
So something simple is going wrong here, what could it be!?
the ssh2-package is for node.js, not frontend/web.
The browser can't use network like that (electron uses two processes, the browser/renderer -process does not have access to the network features you need)
does your electron app have a main.js file?
that's where you need to implement the ssh functionality.
i.e. in the main-process, not in the renderer-process.
http://electron.atom.io/docs/tutorial/quick-start/#main-process
In my wrapper of ssh2 (ssh2shell) I have this.connection = new require('ssh2')(); within the constructor of the class or it could be put in the init function. Creating it within the instance might help.
"use strict";
class SSHClient {
constructor() {}
init(username, password, host, port) {
console.log("initiating SSH connection to:" + host + "on port:" + port);
var ssh = require('ssh2').Client
this._conn = new ssh();
console.log("Connecting");
console.log('Client :: ready');
var self = this
this._conn.on('ready', function() {
self._conn.exec('uptime', function(err, stream) {
if (err) throw err;
stream.on('data', function(data) {
console.log('STDOUT: ' + data);
}).stderr.on('data', function(data) {
console.log('STDERR: ' + data);
}).on('close', function(code, signal) {
console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
self._conn.end();
});
});
}).connect({
host: host,
port: port,
username: username,
password: password
});
console.log("SSH Client created and demo has run");
}
}
module.exports = SSHClient
Or using my package ssh2shell the ssh connection instance is within the sope of ssh2shell instance so you don't have to worry about it.
"use strict";
class SSHClient {
constructor() {}
init(username, password, host, port) {
console.log("initiating SSH connection to:" + host + "on port:" + port);
var host = {
server: {
host: host,
port: port,
userName: username,
password: password
},
commands: [ "uptime" ]
}
var SSH2Shell = require ('ssh2shell'),
//Use a callback function to handle the response text
callback = function(sessionText){
console.log("SSH Client created and demo has run");
console.log("Response:\n" + sessionText)
}
//Create a new instance passing in the host object
this._conn = new SSH2Shell(host)
//Start the process
this._conn.connect(callback);
}
}
module.exports = SSHClient

Resources