I have written code to establish a SFTP connection and transfer files to the SFTP server using Node.js sftp.put command. I'm getting the following error while transferring the file. I can establish the connection successfully. But I cannot read/write files to the server. I have attached the code below
Code
let sftp = new client();
let filename = "sound.mp3";
const filePath = path.join(__dirname, '../audio', filename)
const putConfig = {
flags: 'w', // w - write and a - append
encoding: null, // use null for binary files
mode: 0o666, // mode to use for created file (rwx)
autoClose: true // automatically close the write stream when finished
};
sftp.connect({
host: 'host',
port: '22',
username: 'xxxx',
password: 'xxx'
}).then(() => {
return sftp.put(filePath, '/', putConfig)
}).then(data => {
console.log(data, 'the data info');
}).catch(err => {
console.log(err, 'catch error');
});
Error
Error: put->put: Failure /data
at fmtError (D:\project\node_modules\ssh2-sftp-client\src\utils.js:53:18)
at SftpClient.put (D:\project\node_modules\ssh2-sftp-client\src\index.js:684:13)
at processTicksAndRejections (internal/process/task_queues.js:93:5) {
code: 4,
custom: true
}
D:\project\node_modules\ssh2\lib\protocol\crypto\poly1305.js:20
function J(a){if(b.onAbort)b.onAbort(a);L(a);O=!0;a=new WebAssembly.RuntimeError("abort("+a+"). Build with -s ASSERTIONS=1 for more info.");r(a);throw a;}var V="data:application/octet-stream;base64,",W="data:application/octet-stream;base64,AGFzbQEAAAABIAZgAX8Bf2ADf39/AGABfwBgAABgAAF/YAZ/f39/f38AAgcBAWEBYQAAAwsKAAEDAQAAAgQFAgQFAXABAQEFBwEBgAKAgAIGCQF/AUGAjMACCwclCQFiAgABYwADAWQACQFlAAgBZgAHAWcABgFoAAUBaQAKAWoBAAqGTQpPAQJ/QYAIKAIAIgEgAEEDakF8cSICaiEAAkAgAkEAIAAgAU0bDQAgAD8AQRB0SwRAIAAQAEUNAQtBgAggADYCACABDwtBhAhBMDYCAEF/C4wFAg5+Cn8gACgCJCEUIAAoAiAhFSAAKAIcIREgACgCGCESIAAoAhQhEyACQRBPBEAgAC0ATEVBGHQhFyAAKAIEIhZBBWytIQ8gACgCCCIYQQVsrSENIAAoAgwiGUEFbK0hCyAAKAIQIhpBBWytIQkgADUCACEIIBqtIRAgGa0hDiAYrSEMIBatIQoDQCASIAEtAAMiEiABLQAEQQh0ciABLQAFQRB0ciABLQAGIhZBGHRyQQJ2Qf///x9xaq0iAyAOfiABLwAAIAEtAAJBEHRyIBNqIBJBGHRBgICAGHFqrSIEIBB+fCARIAEtAAdBCHQgFnIgAS0ACEEQdHIgAS0ACSIRQRh0ckEEdkH///8fcWqtIgUgDH58IAEtAApBCHQgEXIgAS0AC0EQdHIgAS0ADEEYdHJBBnY
RuntimeError: abort(Error: put->put: Failure /data). Build with -s ASSERTIONS=1 for more info.
at process.J (D:\project\node_modules\ssh2\lib\protocol\crypto\poly1305.js:20:53)
at process.emit (events.js:210:5)
at process.EventEmitter.emit (domain.js:475:20)
at processPromiseRejections (internal/process/promises.js:201:33)
at processTicksAndRejections (internal/process/task_queues.js:94:32)
The second argument of SftpClient.put is a path to the target remote file, not only path to the target remote folder.
So it should be like:
return sftp.put(filePath, '/' + filename, putConfig)
Related
I have a problem with the connection into a hpux server that we host locally in our local network. I get the following error:
Hello world
Connected to Nemesis
true
rejected: Error: read ECONNRESET
at TCP.onStreamRead (node:internal/stream_base_commons:217:20) {
errno: -4077,
code: 'ECONNRESET',
syscall: 'read',
level: 'client-socket'
}
node:internal/process/promises:279
triggerUncaughtException(err, true /* fromPromise */);
^
Error: read ECONNRESET
at TCP.onStreamRead (node:internal/stream_base_commons:217:20) {
errno: -4077,
code: 'ECONNRESET',
syscall: 'read',
level: 'client-socket'
}
Here is my code:
console.log('Hello world');
const { NodeSSH } = require('node-ssh');
const ssh = new NodeSSH();
ssh.connect({
host: "server",
username: "admin account",
password: "password"
}).then(console.log("Connected to Nemesis"))
console.log(ssh.isConnected());
ssh.exec('hh_client', ['--json'], { cwd: '/', stream: 'stdout', options: { pty: true } }).then(fulfilled => {
console.log("fulfilled:", fulfilled)
}).catch(rejected => {
console.log("rejected:", rejected)
})
I believe it is connecting to the server OK, tested by changing the IP, where I get a message to say that it cannot find the server. That said, the username and password does not seem to be being used, as I can type the user and password wrong, and I get the same error message.
the exec code is just lifted from the npm website for the module.
for a little more context, I am fairly new to hpux and linux in general, as most of this is inherited. I have seen a lot of information about using RSA and public/private keys, but there are already some on the server and I don't want to overwrite anything in the .ssh folder if I can help it.
In terms of connecting via other methods, I can use the username and password using ssh user#server and connect in fine, and do anything I want on the server with full permissions.
Any help appreciated.
Thank you,
Craig
Seing the exact same problem.
It's seems from the logs on the target server that the library is still trying to use key auth, maybe because we are not using it correctly or because it's simply considered insecure by the developers, or maybe they just negleted that option since most people won't use it for security reasons.
Here is the relevant server log:
Jan 23 20:43:55 debian sshd[6152]: error: kex_exchange_identification: banner line contains invalid characters
Jan 23 20:43:55 debian sshd[6152]: banner exchange: Connection from <source_ip_edited_for_privacy> port 42544: invalid format
Here is the code:
const readline = require("readline");
const { NodeSSH } = require("node-ssh");
// function to get input from user
const getInput = () => {
// required to take input from user
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
// required to connect
const ssh = new NodeSSH();
rl.question("What is the host? ", (host) => {
console.log(host);
rl.question("What is the user? ", (user) => {
console.log(user);
rl.question("What is the password?", (password) => {
console.log(password);
rl.question("What is the command?", (command) => {
console.log(command);
// Connect
ssh.connect({
host: host,
username: user,
password: password,
//privateKeyPath: '/home/steel/.ssh/id_rsa'
});
// Excute Command
ssh
.execCommand(`${command}`, { cwd: `/home/${user}` })
.then((result) => {
// rl.write(result.stdout);
console.log("STDOUT: " + result.stdout);
console.log("STDERR: " + result.stderr);
})
.catch((err) => {
console.log(err);
})
.finally(() => {
ssh.dispose();
rl.close();
});
});
});
});
});
};
getInput();
I am using node -v v14.17.0 and "ssh2-sftp-client": "^7.0.0" and method fastPut https://github.com/theophilusx/ssh2-sftp-client#sec-5-2-9
Checking the remote files is okay, so connection works.
My environment is wsl2 Ubuntu-20.04
Problem I face is error
RuntimeError: abort(Error: fastPut: No response from server Local: /home/draganddrop/testi.txt Remote: Downloads/testi.txt). Build with -s ASSERTIONS=1 for more info.
at process.J (/home/draganddrop/node_modules/ssh2/lib/protocol/crypto/poly1305.js:20:53)
at process.emit (events.js:376:20)
at processPromiseRejections (internal/process/promises.js:245:33)
at processTicksAndRejections (internal/process/task_queues.js:96:32)
I have tried also with sftp> put /home/draganddrop/testi.txt Downloads/testi.txt from console, which works.
Code I am using:
let Client = require('ssh2-sftp-client');
let sftp = new Client();
let remotePath = 'Downloads/testi.txt';
let localPath = '/home/draganddrop/testi.txt'
const config = {
host: 'XX.XX.XXX.XXX',
port: '22',
username: 'XXXXX',
password: 'XXXXXX'
};
sftp.connect(config)
.then(() => {
sftp.fastPut(localPath, remotePath);
//return sftp.exists(remotePath);
})
//.then(data => {
// console.log(data); // will be false or d, -, l (dir, file or link)
//})
.then(() => {
sftp.end();
})
.catch(err => {
console.error(err.message);
});
I have no idea what causes this error, I've tried with different paths and get either bad path error or this. What could be the cause?
The reason for the problem is that the connection is closing before the finish of executing fastPut.
You are running connect, after that in the first .then, the method fastPut runs asynchronously, it doesn't wait for the finish execution and return undefined to the next method .then of the chain.
To solve the problem you just need to return a promise received from fastPut
sftp.connect(config)
.then(() => sftp.fastPut(localPath, remotePath))
.then((data) => {/* do something*/}
.finally(() => sftp.end())
Rule:
Node.js Server will pull data from another FTP server retrieving a .csv file.
I keep getting this error:
Error: unable to verify the first certificate
at TLSSocket.onConnectSecure (_tls_wrap.js:1497:34)
at TLSSocket.emit (events.js:315:20)
at TLSSocket._finishInit (_tls_wrap.js:932:8)
at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:706:12) {
code: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'
The code is as follows:
const ftp = require("basic-ftp");
(async function () {
const client = new ftp.Client();
client.ftp.verbose = true;
try {
await client.access({
host: "host",
user: "user",
password: "pass",
secure: true,
strictSSL: false,
});
console.log(await client.list());
await client.uploadFrom("VEHICLES.csv");
await client.downloadTo("VEHICLES.csv");
} catch (err) {
console.log(err);
}
client.close();
})();
A beer to whoever can help me out..
UPDATE
add in .access options:
secureOptions: {
rejectUnauthorized: false
}
I am trying to publish messages to Amazon MQ from Node JS and none of the libraries I have tried so far seem to be working.
Library 1:
stomp-client
Code:
var Stomp = require('stomp-client');
var destination = '/topic/{new_topic}';
var client = new Stomp('{prefix}.amazonaws.com',
61614,
'{user}',
'{password}');
client.connect(function(sessionId) {
client.publish(destination, 'Oh herrow');
});
Error with first library:
Emitted 'error' event at:
at StompFrameEmitter.<anonymous> (project_path\node_modules\stomp-client\lib\client.js:236:10)
at StompFrameEmitter.emit (events.js:182:13)
[... lines matching original stack trace ...]
at Socket.Readable.push (_stream_readable.js:219:10)
Library 2:
stompit
Code:
const stompit = require('stompit');
var connectOptions = {
'host': '{prefix}.amazonaws.com',
'port': 61614,
'connectHeaders':{
'host': '/',
'login': '{user}',
'passcode': '{password}',
'heart-beat': '5000,5000'
}
};
stompit.connect(connectOptions, function(error, client) {
if (error) {
console.log('connect error ' + error.message);
return;
}
var sendHeaders = {
'destination': '/topic/{new_topic}',
'content-type': 'text/plain'
};
var frame = client.send(sendHeaders);
frame.write('hello');
frame.end();
});
Error with second library: connect error unexpected end of stream
I am not sure what else I can try but I seem to be stuck here as the error messages are not even verbose plus there isnt a lot of information on this issue online.
Only relevant article I found has no answer on Amazon forum:
https://forums.aws.amazon.com/thread.jspa?messageID=831730&tstart=0
What worked for me to solve this issue was to set ssl connection to true as follows:
const server_options = {
host,
port,
ssl: true,
connectHeaders: {
host: '/',
'accept-version': '1.1',
'heart-beat': '0,0', // no heart beat
login: user,
passcode: pass,
},
};
Port must be set to 61614 for stomp+ssl connection.
I am trying to write to a mapped network drive in Node using the windows-network-drive module and the fs module.
networkDrive.mount('\\\\server', 'Z', 'username', 'password')
.then(driveLetter => {
let filePath;
filePath = path.join(driveLetter + ":\\path\\to\\directory", "message.txt");
fs.writeFile(filePath, "text", (err) => {
if (err) throw err;
console.log('The file has been saved!');
});
})
.catch(err => {
console.log(err)
});
How can I get the connection and path to write to a remote location?
Do I need to pass in the drive letter? If so, how do I locate it?
(node:4796) UnhandledPromiseRejectionWarning:
ChildProcessError: Command failed: net use Z: "\server" /P:Yes /user:username password
System error 67 has occurred.
The network name cannot be found.
net use Z: "\server" /P:Yes /user:username password (exited with error code 2)
at callback (C:\app\location\node_modules\child-process-promise\lib\index.js:33:27)
at ChildProcess.exithandler (child_process.js:279:5)
at ChildProcess.emit (events.js:159:13)
at maybeClose (internal/child_process.js:943:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:220:5)
name: 'ChildProcessError',
code: 2,
childProcess:
{ ChildProcess: { [Function: ChildProcess] super_: [Function] },
fork: [Function],
_forkChild: [Function],
exec: [Function],
execFile: [Function],
spawn: [Function],
spawnSync: [Function: spawnSync],
execFileSync: [Function: execFileSync],
execSync: [Function: execSync] },
stdout: '',
stderr: 'System error 67 has occurred.\r\n\r\nThe network name cannot be found.\r\n\r\n' }
P.S. this code logs Z
networkDrive.mount('\\\\server\\path\\to\\directory', 'Z', 'mdadmin', 'Password1!')
.then(function (driveLetter) {
console.log(driveLetter);
fs.writeFile('L_test.txt', 'list', (err) => {
if (err) throw err
})
});
To write from a REST Service hosted in IIS, you will need to properly set the permissions on the server.
You will need to set the identity of the Application Pool of your site.
You will need to grant write permissions to match that account or account group to the folder that you are trying to write to.
Note: If you map a folder to a network drive letter through the OS, it is only defined at the user account level.
So, if you have mapped the folder location to a drive letter (in this case 'X:'), instead of writing to
fs.writeFile('X:/test.txt', 'text', (err) => {
if (err) throw err
})
You must write to to full path
fs.writeFile('\\\\servername\\path\\to\\director\\test.txt', 'text', (err) => {
if (err) throw err
})
Note: Backslashes need to be escaped, so the Windows file system will show something like \\servername\path\to\directory.
P.S. This answer includes recommendations from users l-bahr and Ctznkane525.
I am not sure what error you got, so here are a couple tips for when you are using windows-network-drive.
Escape Special Characters
Windows uses \ to separate directories. \ is a special character in a JavaScript string and must be escaped like this \\. e.g. C:\file.txt would be C:\\file.txt in a string.
Use POSIX Separation Character When You Can
Because of the added difficulty in reading a path with the escaped \, I would recommend using / instead. windows-network-drive should handle both just fine. e.g. C:\file.txt would be C:/file.txt in a string.
Example
I tried to make this match your example, but made a few changes so that it will work on any windows machine.
let networkDrive = require("windows-network-drive");
/**
* https://github.com/larrybahr/windows-network-drive
* Mount the local C: as Z:
*/
networkDrive.mount("\\\\localhost\\c$", "Z", undefined, undefined)
.then(function (driveLetter)
{
const fs = require("fs");
const path = require("path");
let filePath;
/**
* This will create a file at "Z:\message.txt" with the contents of "text"
* NOTE: Make sure to escape '\' (e.g. "\\" will translate to "\")
*/
filePath = path.join(driveLetter + ":\\", "message.txt");
fs.writeFile(filePath, "text", (err) =>
{
if (err) throw err;
console.log('The file has been saved!');
});
});