6

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
M. Haenzi
  • 61
  • 1
  • 3

1 Answers1

0

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() 
Sandeep Patel
  • 4,815
  • 3
  • 21
  • 37
  • read more here :https://stackoverflow.com/questions/20082893/unable-to-verify-leaf-signature – Sandeep Patel Dec 04 '19 at 14:40
  • Doesn't seem to work. I've also tried manually including the intermediate certificate as explained in the [API](https://git.coolaj86.com/coolaj86/ssl-root-cas.js#unable-to-verify-the-first-certificate). `.addFile(__dirname + '/ssl/01-cheap-ssl-intermediary-a.pem')` – M. Haenzi Dec 05 '19 at 12:19
  • In my case the user individually configures multiple ftp connections via userinterface. So uploading and providing each and every certificate separately isn't really what I had in mind. Am I missing the point and should it be handled that way? – M. Haenzi Dec 06 '19 at 10:54
  • If I am not wrong, what we are passing here is a server certificate with a full chain of certificates. so the same certificate should work for all users and I think this is how it should be. – Sandeep Patel Dec 06 '19 at 11:17
  • What do you mean by "a server certificate with a full chain of certificates"? Users create various ftp connections, so for every connection I'll have to manually add a server certificate with it's chain certificates? – M. Haenzi Dec 09 '19 at 08:13