How to connect to FTPS server in node using basic-ftp module - node.js

I am using https://www.npmjs.com/package/basic-ftp basic ftp package to connect to ftps server. I have tried my other extension but failed to connect to ftps server
below is my code
const ftp = require("basic-ftp")
example();
async function example() {
const client = new ftp.Client()
client.ftp.verbose = true
try {
await client.access({
host: "ftp.xxxx.xxxxx",
user: "xxxx#xxxx.xx",
password: "xxxxxxx",
secure :true
})
await client.ensureDir("/my/remote/directory")
console.log(await client.list())
await client.uploadFrom("temp/readme.txt", "readme.txt")
// await client.downloadTo("README_COPY.md", "README_FTP.md")
}
catch(err) {
console.log(err)
}
client.close()
}
but giving me a error
Connected to xxx.xxx.xx.xxx:21
< 220 Service ready for new user.
Login security: No encryption
> USER xx#xxx.xx
< 331 User name okay, need password for xxxx#xxx.xx.
> PASS ###
< 530 Box: Smartest Energy does not allow regular FTP; use FTPS instead. (Both "
explicit" and "implicit" FTPS are supported.)
{ FTPError: 530 Box: Smartest Energy does not allow regular FTP; use FTPS instea
d. (Both "explicit" and "implicit" FTPS are supported.)
at FTPContext._onControlSocketData (D:\node\basicftp\node_modules\basic-ftp\
dist\FtpContext.js:276:39)
at Socket.socket.on.data (D:\node\basicftp\node_modules\basic-ftp\dist\FtpCo
ntext.js:121:44)
at Socket.emit (events.js:198:13)
at addChunk (_stream_readable.js:288:12)
at readableAddChunk (_stream_readable.js:265:13)
at Socket.Readable.push (_stream_readable.js:224:10)
at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17) name
: 'FTPError', code: 530 }
Please help
Thanks in advance

You will require to connect Explicit FTPS over TLS.
to connect to ftps over tls you will need to pass the following options:
const fs = require('fs');
async function example() {
const client = new ftp.Client()
client.ftp.verbose = true
try {
const secureOptions = {
// Necessary only if the server requires client certificate authentication.
key: fs.readFileSync('client-key.pem'),
cert: fs.readFileSync('client-cert.pem'),
// Necessary only if the server uses a self-signed certificate.
ca: [ fs.readFileSync('server-cert.pem') ],
// Necessary only if the server's cert isn't for "localhost".
checkServerIdentity: () => { return null; },
};
await client.access({
host: "ftp.xxxx.xxxxx",
user: "xxxx#xxxx.xx",
password: "xxxxxxx",
secure :true,
secureOptions : secureOptions
})
await client.ensureDir("/my/remote/directory")
console.log(await client.list())
await client.uploadFrom("temp/readme.txt", "readme.txt")
// await client.downloadTo("README_COPY.md", "README_FTP.md")
}
catch(err) {
console.log(err)
}
client.close()
}

After trying to get this working with basic-ftp, i just tried https://www.npmjs.com/package/ssh2-sftp-clientand it worked immediately.

Related

Error:read ECONNRESET - I cannot successfully authenticate with the hp-ux server in node.js

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 trying to setup a Node.js FTP Server that can pull data from another FTP server

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
}

Is it possible to connect to mssql with windows auth mode from a nodejs app running on linux?

I'm trying to connect to a mssql with Windows authentication mode (can't change that) from nodejs running on a linux machine.
I tried many things, all of them resulted in nearly the same error, here is an attempt using tedious with this simple code running on a linux machine with nodejs:
let tedious = require('tedious');
let Connection = tedious.Connection;
const config = {
userName: 'myUserName',
password: 'myPassword',
server: 'MyServ',
options: {
database: 'MyDbName'
}
}
function handleConnection(err: any) {
if (err) console.error("error connecting :-(", err);
else console.log("successfully connected!!")
}
let connection = new Connection(config);
connection.on('connect', handleConnection);
I get this error
error connecting :-( { ConnectionError: Login failed for user ''.
at ConnectionError (./node_modules/tedious/lib/errors.js:13:12)
at Parser.tokenStreamParser.on.token (./node_modules/tedious/lib/connection.js:848:51)
at Parser.emit (events.js:198:13)
at Parser.parser.on.token (./node_modules/tedious/lib/token/token-stream-parser.js:37:14)
at Parser.emit (events.js:198:13)
at addChunk (./node_modules/readable-stream/lib/_stream_readable.js:298:12)
at readableAddChunk (./node_modules/readable-stream/lib/_stream_readable.js:280:11)
at Parser.Readable.push (./node_modules/readable-stream/lib/_stream_readable.js:241:10)
at Parser.Transform.push (./node_modules/readable-stream/lib/_stream_transform.js:139:32)
at doneParsing (./node_modules/tedious/lib/token/stream-parser.js:122:14) message: 'Login failed for user \'\'.', code: 'ELOGIN' }
The credentials I used do have SQL rights (tested with ODBC on windows machine).
Am I doing something wrong or is it just impossible ?
#ADyson thank you a lot for your informations, you managed to pinpoint the solution to my poorly formulated problem caused by my total lack of knowledge on the subject, really thank you again. the solution was to use domain login this snippet worked :
const config = {
user: MyUserName,
password: MyPassword,
server: 'MyServAdress',
database: 'MyDbName,
domain: 'MyDomain'
}
const sql = require('mssql');
sql.connect(config).then((pool: any) => {
console.log('connected!');
}).catch((err: any) => {
console.log(err);
});
Yes indeed, it's possible to receive data form a linux client using windows authentication only enabled. MS SQL Server and NodeJS Linux Server are in the same network. The linux Server isn't domain-joined:
I used this to run execute my query:
const sql = require('mssql')
const config = {
server: 'SERVER',
database: 'DATABASE',
user: 'USER',
password: 'PASSWORD',
domain: 'DOMAIN',
options: {
enableArithAbort: true // required, otherwise deprecation warning
}
}
sql.connect(config)
.then((conn) => {
console.log('MSSQL: connected');
conn.query(`SELECT ..`)
.then(data => console.log(data))
.then(() => conn.close())
}).catch(err => { console.log(err) });

Unable to verify the first certificate - Nodejs TLS

I'm using the node-module basic-ftp to try to establish a secure connection via TLS/ SSL.
The server uses a wildcard CA-signed certificate as it's hostname. I can't seem to find an answer for the followig error code.
Connected to 1.1.1.1:21
< 220 Welcome to ftp.foo.com
> AUTH TLS
< 234 Using authentication type TLS
{ Error: unable to verify the first certificate
at TLSSocket.onConnectSecure (_tls_wrap.js:1051:34)
at TLSSocket.emit (events.js:189:13)
at TLSSocket._finishInit (_tls_wrap.js:633:8) code: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'
}
Below you find the sample code:
const ftp = require("basic-ftp");
async establishFtpsConnection() {
const client = new ftp.Client();
client.ftp.verbose = true;
try {
await client.access({
host: "ftp.foo.com",
user: "bar",
password: "1234",
port: 21,
secure: true
});
const list = await client.list();
console.log(list);
} catch (err) {
console.log(err);
}
client.close();
}
NOTE: I'm trying to get it to work for my production environment. So disabling or rejecting unauthorization is NO option for me.
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
OR
rejectUnauthorized: false
Try this :
const ftp = require("basic-ftp");
async establishFtpsConnection() {
const client = new ftp.Client();
client.ftp.verbose = true;
const tlsOptions = {
cert: fs.readFileSync('fullchain.pem', 'ascii')
// a PEM containing the SERVER and ALL INTERMEDIATES
}
try {
await client.access({
host: "ftp.foo.com",
user: "bar",
password: "1234",
port: 21,
secure: true,
secureOptions:tlsOptions
});
const list = await client.list();
console.log(list);
} catch (err) {
console.log(err);
}
client.close();
}
If you are still getting an error then try to inject root SSL certificates
var sslRootCAs = require('ssl-root-cas/latest')
sslRootCAs.inject()

Getting "bad username or password" error while attempting to connect to broker

I have followed the tutorial presented here, but I couldn't connect a client to the server. I always get the following error message (full stacktrace):
Error: Connection refused: Bad username or password
at MqttClient._handleConnack (${project_dir}/node_modules/mqtt/lib/client.js:760:24)
at MqttClient._handlePacket (${project_dir}/node_modules/mqtt/lib/client.js:300:12)
at process (${project_dir}/node_modules/mqtt/lib/client.js:242:12)
at Writable.writable._write (${project_dir}/node_modules/mqtt/lib/client.js:252:5)
at doWrite (${project_dir}/node_modules/mqtt/node_modules/readable-stream/lib/_stream_writable.js:345:64)
at writeOrBuffer (${project_dir}/node_modules/mqtt/node_modules/readable-stream/lib/_stream_writable.js:334:5)
at Writable.write (${project_dir}/node_modules/mqtt/node_modules/readable-stream/lib/_stream_writable.js:271:11)
at Socket.ondata (_stream_readable.js:528:20)
at emitOne (events.js:77:13)
at Socket.emit (events.js:169:7)
I have double-checked my environment variables, whose values came from my Auth0 account, (particularly CLIENT_ID, DOMAIN, CLIENT_SECRET and CONNECTION) but they seem fine.
I've changed the client's code a bit to match the current version of MQTT.js. Here is the code:
const mqtt = require('mqtt');
const settings = {
port: 1883,
keepalive: 1000,
protocolId: 'MQIsdp', // already tried 'MQTT' with protocol version 4
protocolVersion: 3,
clientId: 'a random id',
username: 'an account at Auth0',
password: 'the password of the account'
}
var client = mqtt.connect('mqtt://localhost', settings);
client.on("connect", function () {
client.subscribe("topic");
console.log("connected");
});
client.on("message", function (topic, message) {
// message is Buffer
console.log(message.toString());
client.end();
});
The broker code is very similar to the presented in the tutorial. I want to solve this error before changing it.
const mosca = require('mosca')
const Auth0Mosca = require('auth0mosca');
require('dotenv').config();
const settings = {
port: 1883
};
if (!process.env.AUTH0_DOMAIN || !process.env.AUTH0_CLIENT_ID ||
!process.env.AUTH0_CLIENT_SECRET || !process.env.AUTH0_CONNECTION) {
throw 'Make sure you have AUTH0_DOMAIN, AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET and AUTH0_CONNECTION in your .env file';
}
const auth0 = new Auth0Mosca('https://' + process.env.AUTH0_DOMAIN, process.env.AUTH0_CLIENT_ID, process.env.AUTH0_CLIENT_SECRET, process.env.AUTH0_CONNECTION);
// mosca server
const server = new mosca.Server(settings);
server.authenticate = auth0.authenticateWithCredentials();
server.authorizePublish = auth0.authorizePublish();
server.authorizeSubscribe = auth0.authorizeSubscribe();
server.on('ready', setup);
// MQTT server is ready
function setup() {
console.log('Mosca server is up and running');
}
server.on('clientConnected', function(client) {
console.log('New connection: ', client.id);
});
I know that it is probably a stupid mistake or a library update that is causing this. For the latter case, here are the versions:
"auth0mosca": "^0.1.0",
"mosca": "^2.3.0",
"mqtt": "^2.5.0"
Finally, I have checked that the request reaches the broker.
I have forked the repository with the code of the tutorial and updated its dependencies to the latest versions. Also, added the possibility to verify JWTs signed with, for example, RS256 algorithm.
This solved my problem and I hope it helps everyone facing the same issue.

Resources