Uploaded image for project: 'Node.js Driver'
  1. Node.js Driver
  2. NODE-4209

Investigate NODE-4208 - Ineffective timeout in MONGODB-AWS credential loading

    • Type: Icon: Task Task
    • Resolution: Done
    • Priority: Icon: Unknown Unknown
    • None
    • Affects Version/s: None
    • Component/s: None
    • 2
    • Not Needed

      NODE-4208 Description

      What problem are you facing?

      When the MONGODB-AWS auth mechanism is selected, and credentials are not provided upfront, the auth mechanism will try loading credentials from the EC2 metadata service.

      The problem is that the intended 10-second timeout is not programmed properly, so the auth mechanism will hang for more than a minute if attempted outside of EC2.

      On my machine I'm seeing a delay of 75 seconds before the connection attempt fails.

      Additionally, a timeout as low as 3 seconds may be more desirable to improve user experience.

      This issue seems to also impact "mongosh".

      What driver and relevant dependency versions are you using?

      node v17.8.0

      mongodb@4.5.0

      mongosh 1.3.1

      Steps to reproduce?

      Within nodejs:

      import { MongoClient } from "mongodb";
      
      MongoClient.connect("mongodb+srv://some-stuff-here.mongodb.net", {
        authSource: "$external",
        authMechanism: "MONGODB-AWS",
      });
      

       With mongosh:

      $ mongosh "mongodb+srv://some-stuff-here.mongodb.net?authSource=%24external&authMechanism=MONGODB-AWS" --apiVersion 1Connecting to:          mongodb+srv://......etc.......

      Note that the issue only occurs when you do not have credentials in the environment and are not on EC2.
      In both cases, this error is given after 75 seconds:

      Error: connect ETIMEDOUT 169.254.169.254:80

      Comparison with AWS SDK

      I'd like to point out that the official AWS SDK JS only waits 3 seconds before giving up on a credential fetch. It issues up to 3 requests with a 1-second timeout on each request. Source: https://github.com/aws/aws-sdk-js/blob/8d6429f810abb24895a248b486746ffae92eedfb/lib/credentials/ec2_metadata_credentials.js#L12-L13

      Logic fault details

      This StackOverflow entry shows how HTTP timeouts work in NodeJS: https://stackoverflow.com/questions/6214902/how-to-set-a-timeout-on-a-http-request-in-node

      Effectively, the timeout registered here does not have any effect on its own: https://github.com/mongodb/node-mongodb-native/blob/067fa077b6e3be266844b6f1c7ba1f34fd882917/src/cmap/auth/mongodb_aws.ts#L258

      To enforce the timeout, this line of code can be added later in the function:

      req.on('timeout', () => req.destroy());

       

            Assignee:
            daria.pardue@mongodb.com Daria Pardue
            Reporter:
            dbeng-pm-bot PM Bot
            Daria Pardue
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: