Unable to verify the first certificate - Nodejs TLS - node.js

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()

Related

proxy setting in adal-node package

I am trying to generate token to authenticate to Azure AD in my node server using adal-node package().Its working on my local machines but when trying to run on virtual machines its giving below error:
{
Error: getaddrinfo EAI_AGAIN login.microsoftonline.com login.microsoftonline.com:443
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:57:26)
errno: 'EAI_AGAIN',
code: 'EAI_AGAIN',
syscall: 'getaddrinfo',
hostname: 'login.microsoftonline.com',
host: 'login.microsoftonline.com',
port: 443` }
sample code snippet
var authorityUrl = 'https://login.microsoftonline.com/53d652a4-6f71-416f-971f-*****'
var applicationId = '26915ab6-22fc-4017-8741-***************'; // Application Id of app registered under AAD.
var clientSecret = '2NZtB5mIX1xZaXZ_I6I~-*********'; // Secret generated for app. Read this environment variable.
var resource = 'https://**************.com'; // URI that identifies the resource for which the token is valid.
var context = new AuthenticationContext(authorityUrl);
context.acquireTokenWithClientCredentials(resource, applicationId, clientSecret, function(err, tokenResponse) {
if (err) {
console.log('well that didn\'t work: ' + err.stack);
console.log(err);
res.json(err.stack);
} else {
console.log(tokenResponse.accessToken);
}
Analysis:It looks like proxy issue but unable to figure out how to set proxy url using adal-node package.Kindly suggest the way forward.
If you want to use the proxy server in your application, please refer to the following code
const { AuthenticationContext, Logging } = require("adal-node");
const proxy = require("node-global-proxy").default;
proxy.setConfig({
http: "",
https: ""
});
proxy.start();
const context = new AuthenticationContext(
"https://login.microsoftonline.com/const { AuthenticationContext, Logging } = require("adal-node");
const proxy = require("node-global-proxy").default;
proxy.setConfig({
http: "http://149.28.43.184:8080",
});
proxy.start();
const context = new AuthenticationContext(
"https://login.microsoftonline.com/e4c9ab4e-bd27-40d5-8459-230ba2a757fb"
);
Logging.setLoggingOptions({
log: function (level, message, error) {
console.log(message);
if (error) {
console.log(error);
}
},
loggingWithPII: false,
level: Logging.LOGGING_LEVEL.VERBOSE,
});
var applicationId = ""; // Application Id of app registered under AAD.
var clientSecret = ""; // Secret generated for app. Read this environment variable.
var resource = "";
context.acquireTokenWithClientCredentials(
resource,
applicationId,
clientSecret,
function (err, tokenResponse) {
if (err) {
console.log("well that didn't work: " + err.stack);
} else {
console.log(tokenResponse);
}
}
);
proxy.stop()

Can I connect to ssh2 without the privateKey?

I can connect to ssh2 without the privateKey
I am trying to enter a server with SFTP but when I get the following error ...
Timed out while waiting for handshake
I'm looking for an example and almost everyone uses the privateKey, is it mandatory? and how is one generated?
My code is the following ...
var Client = require ('ssh2'). Client;
var conn = new Client ();
conn.on ('error', function (err) {
console.log ('SSH - Connection Error:' + err);
});
conn.on ('end', function () {
console.log ('SSH - Connection Closed');
});
conn.on ('ready', function () {
console.log ("------ enter ------");
// code to work with SSH
});
conn.connect ({
host: 'host',
username: 'user',
port: 22
password: 'password',
});

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
}

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

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.

Node-Redis: ready check failed - NOAUTH Authentication required

I have a strange redis behavior:
const redis = require('redis');
const { REDIS_URL: redisUrl, REDIS_PASSWORD: redisPassword } = process.env;
const client = redis.createClient(redisUrl, {
no_ready_check: true,
auth_pass: redisPassword
});
client.on('connect', () => {
redisPassword && client.auth(redisPassword);
});
client.on('error', err => {
global.console.log(err.message)
});
But all the time I receive following error:
throw er; // Unhandled 'error' event
ReplyError: Ready check failed: NOAUTH Authentication required.
Why unhandled ? I set onerror handler
Why Ready check failed ? I disabled it in options
I'm not sure why your code will throw this error. But I try this code in my local machine, it works well.
const redis = require('redis');
const redisPassword = "password" ;
const client = redis.createClient({
host : '127.0.0.1',
no_ready_check: true,
auth_pass: redisPassword,
});
client.on('connect', () => {
global.console.log("connected");
});
client.on('error', err => {
global.console.log(err.message)
});
client.set("foo", 'bar');
client.get("foo", function (err, reply) {
global.console.log(reply.toString())
})
And run node client.js will output :
connected
bar
NOAUTH Authentication required is caused by when redis process command , it found the client is not authenticated so it complained with it.
I guess maybe the redisUrl you give to createClient has some problem, try to debug it or change to my code's way to try. Hopefully you can fix it.
And one more thing: the client.auth(redisPassword) is not necessary because if you set an auth_pass or password option, the redis client will auto send auth command to server before any command.
If you have redis uri saved as string. You need decompose it to object. For ioredis you can use function
export function decomposeRedisUrl(url) {
const [[, , password, host, port]] = [...(url.matchAll(/redis:\/\/(([^#]*)#)?(.*?):(\d*)/g))];
return { password, host, port };
}
There are tests for this function:
it("redis url should be decomposed correctly with password", () => {
expect(decomposeRedisUrl("redis://pass#host.com:9183")).to.eql({
password: "pass",
host: "host.com",
port: "9183",
});
});
it("redis url should be decomposed correctly without password", () => {
expect(decomposeRedisUrl("redis://localhost:6379")).to.eql({
password: undefined,
host: "localhost",
port: "6379",
});
});
and usage
import Redis from "ioredis";
async function getKeysFromRedisUrl(url) {
const rc = new Redis(decomposeRedisUrl(url));
const keys = await rc.keys("*");
rc.disconnect();
return keys;
}
describe("Redis can connect", () => {
it("with cloud", async () => {
expect(await getKeysFromRedisUrl("redis://pass#host.com:9183")).to.be.an("array");
});
it("with local redis instance", async () => {
expect(await getKeysFromRedisUrl("redis://localhost:6379")).to.be.an("array");
});
});
user name is not handled in this function
if you're using docker to run Redis, check if your docker-compose has the command: redis-server --requirepass redis
Then check your .env file to make sure you're using it.
It was the problem here and I was able to fix it by adding the password at .env file.

Resources