Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENAMETOOLONG sslCA breaking change #10705

Closed
SamFarrington opened this issue Sep 10, 2021 · 12 comments
Closed

ENAMETOOLONG sslCA breaking change #10705

SamFarrington opened this issue Sep 10, 2021 · 12 comments
Assignees
Labels
docs This issue is due to a mistake or omission in the mongoosejs.com documentation
Milestone

Comments

@SamFarrington
Copy link

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

There appears to be an undocumented breaking change from Mongoose 5 to 6.

Since upgrading to Mongoose 6, when setting up an SSL connection to the db, we have started getting an ENAMETOOLONG error:

Error: ENAMETOOLONG: name too long, open '-----BEGIN CERTIFICATE-----
--
<--redacted--certificate-->
-----END CERTIFICATE-----'
at Object.openSync (fs.js:462:3)
at Object.readFileSync (fs.js:364:35)
at transform (/opt/<redacted-project-name>/node_modules/mongodb/lib/connection_string.js:806:23)
at setOption (/opt/<redacted-project-name>/node_modules/mongodb/lib/connection_string.js:394:36)
at Object.parseOptions (/opt/<redacted-project-name>/node_modules/mongodb/lib/connection_string.js:287:9)
at new MongoClient (/opt/<redacted-project-name>/node_modules/mongodb/lib/mongo_client.js:62:46)
at /opt/<redacted-project-name>/node_modules/mongoose/lib/connection.js:785:16
at new Promise (<anonymous>)
at NativeConnection.Connection.openUri (/opt/<redacted-project-name>/node_modules/mongoose/lib/connection.js:782:19)
at /opt/<redacted-project-name>/node_modules/mongoose/lib/index.js:330:10
at /opt/<redacted-project-name>/node_modules/mongoose/lib/helpers/promiseOrCallback.js:32:5
at new Promise (<anonymous>)
at promiseOrCallback (/opt/<redacted-project-name>/node_modules/mongoose/lib/helpers/promiseOrCallback.js:31:10)
at Mongoose._promiseOrCallback (/opt/<redacted-project-name>/node_modules/mongoose/lib/index.js:1151:10)
at Mongoose.connect (/opt/<redacted-project-name>/node_modules/mongoose/lib/index.js:329:20)
at Server.databaseConnection (/opt/<redacted-project-name>/server.js:103:20)
at Server.databaseConnectAWS (/opt/<redacted-project-name>/server.js:95:16)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async Server.runAwsInstance (/opt/<redacted-project-name>/server.js:43:5)
at async Server.run (/opt/<redacted-project-name>/server.js:21:9) {
errno: -36,
syscall: 'open',
code: 'ENAMETOOLONG',
path: '<redacted-certificate-content',
level: 'error',

Our options are as follows:

const options = {
      autoIndex: true,
      ssl: true,
      sslCA,,
      sslValidate: true,
      sslKey,
      sslCert,
};

await mongoose.connect(url, options);

Where sslCA, sslKey and sslCert are the string values of the relevant certificates and keys.

The error message is implying that the code under the hood is trying to read a file with the name of the supplied value, which isn't how things previously worked in version 5.

Indeed, on the Mongoose documentation itself says to supply the contents of the file:

https://mongoosejs.com/docs/tutorials/ssl.html#ssl-validation

await mongoose.connect('mongodb://localhost:27017/test', {
  ssl: true,
  sslValidate: true,
  // For example, see https://medium.com/@rajanmaharjan/secure-your-mongodb-connections-ssl-tls-92e2addb3c89
  // for where the `rootCA.pem` file comes from
  sslCA: require('fs').readFileSync(`${__dirname}/rootCA.pem`)
});

We have currently worked around the issue by writing the contents of those values to a file and passing the file path, which is working.

It does seem like a bug however as I can't find any mention of this in the release notes and the documentation example will no longer work.

There was a bug raised here which seemed to also hit the issue:

#10488

It was closed but there was no explanation as to when this behaviour changed, whether it was intentional and why the documentation didn't match the implementation.

What is the expected behavior?

For the options object to accept ssl details as strings, as they did prior to version 6.

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.

Node: 12.22.6
Mongoose: 6.0.5
MongoDB: 4.0.10

@vkarpov15 vkarpov15 added this to the 6.0.8 milestone Sep 13, 2021
@darkmavis1980
Copy link

darkmavis1980 commented Sep 14, 2021

I have the same exact problem, I need to include the sslCA to connect to AWS DocumentDB and as output I get this ENAMETOOLONG: name too long, open '-----BEGIN CERTIFICATE----- and then the certificate repeated multiple times and it can't connect to the database.
This is what I'm adding as connection options:

const connectionOptions = {
      ssl: true,
      sslValidate: true,
      sslCA: await fs.readFile('./rds-combined-ca-bundle.pem'),
    };

Node: 14.17.6
Mongoose: 6.0.5
MongoDB: 4.4.8

@SamFarrington
Copy link
Author

This is how we have temporarily worked around the issue if it is of any use to you.

const writeSslDetailsToFiles = (sslCa, sslKey, sslCert) => {
  const sslCALocation = './certificates/sslCA.pem';
  const sslKeyLocation = './certificates/sslKey.pem';
  const sslCertLocation = './certificates/sslCert.pem';

  fs.writeFileSync(sslCALocation, sslCa);
  fs.writeFileSync(sslKeyLocation, sslKey);
  fs.writeFileSync(sslCertLocation, sslCert);

  return {
    sslCALocation,
    sslKeyLocation,
    sslCertLocation,
  };
};

const createDbOptions = async (sslCa, sslKey, sslCert) => {
  const {
    sslCALocation,
    sslKeyLocation,
    sslCertLocation,
  } = writeSslDetailsToFiles(sslCa, sslKey, sslCert);

  return {
    autoIndex: true,
    ssl: true,
    sslCA: sslCALocation,
    sslValidate: true,
    sslKey: sslKeyLocation,
    sslCert: sslCertLocation,
  };
};

@SamFarrington
Copy link
Author

I have the same exact problem, I need to include the sslCA to connect to AWS DocumentDB and as output I get this ENAMETOOLONG: name too long, open '-----BEGIN CERTIFICATE----- and then the certificate repeated multiple times and it can't connect to the database.
This is what I'm adding as connection options:

const connectionOptions = {
      ssl: true,
      sslValidate: true,
      sslCA: await fs.readFile('./rds-combined-ca-bundle.pem'),
    };

Node: 14.17.6
Mongoose: 6.0.5
MongoDB: 4.4.8

I suspect if you do the following it'll start working for you:

> const connectionOptions = {
>       ssl: true,
>       sslValidate: true,
>       sslCA: './rds-combined-ca-bundle.pem',
>     };

However it is a workaround...

@darkmavis1980
Copy link

Uhm, so essentially you are just passing the path to the sslCA correct?
I see, with the previous version of Mongoose you had to pass the actual binary data of the certificate, I'll give it a try, thanks!

@SamFarrington
Copy link
Author

Yea that seems to be the new behaviour, yet to find out if it is staying or going.

@darkmavis1980
Copy link

yeah that worked for me, thanks @SamFarrington!
Kinda odd as it's not documented anywhere on the migration document from version 5 to 6, I'm fine with changes as long they tell you about it somewhere eheh

@mil7
Copy link

mil7 commented Sep 16, 2021

For us the insight to forward as sslCA the path instead of the content is a step forward.

But connecting to DocDB is still not possible. I could narrow it down to a trouble with the node-mongodb-native version: 3.7.1 is working just fine, everything of v4 (I tested 4.0.0 and 4.1.2) leads to ENAMETOOLONG. How did you come around that issue, @darkmavis1980?

@darkmavis1980
Copy link

@mil7 I can connect just fine, using engine v4 for AWS DocumentDB, the only thing I do is to fetch the AWS RDS certificate and save it in the docker container where I run the application, then I just set the sslCA path to that file, that's pretty much it

@ubinatus
Copy link

Thank you @SamFarrington !

@vkarpov15 vkarpov15 added the docs This issue is due to a mistake or omission in the mongoosejs.com documentation label Sep 25, 2021
vkarpov15 referenced this issue in mongodb/node-mongodb-native Sep 25, 2021
We now prefer the `tls` variants of SSL/TLS options. For now, we
detect these and translate them internally to the old option names.
Documentation has been updated to prefer these types, and mention
that the `sslVariants` are deprecated

NODE-2359
@Guy-Bilitski
Copy link

Hi all, when injecting the path instead of its content I get the following error:
Error [ERR_INTERNAL_ASSERTION]: This is caused by either a bug in Node.js or incorrect usage of Node.js internals.

any idea?

@simoncpu
Copy link

simoncpu commented Sep 16, 2022

I'm experiencing this too. My use case is that I want to pass the certificate to serverless functions via an environment variable. Writing the cert to a temporary file is inefficient because I'd have to do this each time a function is invoked.

@xzyfer
Copy link

xzyfer commented Apr 20, 2023

The behaviour of sslCA is changed, you can use ca instead.

@Automattic Automattic locked as resolved and limited conversation to collaborators Apr 24, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
docs This issue is due to a mistake or omission in the mongoosejs.com documentation
Projects
None yet
Development

No branches or pull requests

8 participants