Connect to MongoDB Atlas using AWS IAM role

Hello,

I would like to understand whether the connection method is supported by Pritunl?
Basically username and password will not be provided as part of the connection string.

Thank you!

It may work the MongoDB documentation says that when authMechanism=MONGODB-AWS is set it will automatically read from the environmental variables. I’ve never tested this configuration. If client DNS mapping is enabled that is golang code so any configuration would need to work with both the PyMongo and mongo-go-driver.

Actually I have tried to use what is described in the MongoDB Atlas documentation like:

pritunl set-mongodb "mongodb://<endpoint>/<db-name>?ssl=true&replicaSet=atlas-shard-0&authSource=%24external&authMechanism=MONGODB-AWS&retryWrites=true&w=majority&appName=<app-name>"

but pritunl throws very huge exception:

[ERROR] Pritunl setup failed
Traceback (most recent call last):
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/auth_aws.py", line 33, in _authenticate_aws
    import pymongo_auth_aws  # type:ignore[import]
ModuleNotFoundError: No module named 'pymongo_auth_aws'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pritunl/setup/__init__.py", line 82, in setup_db
    setup_mongo()
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pritunl/setup/mongo.py", line 351, in setup_mongo
    app_settings = settings_col.find_one({'_id': 'app'})
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/collection.py", line 1495, in find_one
    for result in cursor.limit(-1):
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/cursor.py", line 1243, in next
    if len(self.__data) or self._refresh():
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/cursor.py", line 1160, in _refresh
    self.__send_message(q)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/cursor.py", line 1039, in __send_message
    response = client._run_operation(
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/_csot.py", line 108, in csot_wrapper
    return func(self, *args, **kwargs)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/mongo_client.py", line 1431, in _run_operation
    return self._retryable_read(
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/mongo_client.py", line 1540, in _retryable_read
    return self._retry_internal(
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/_csot.py", line 108, in csot_wrapper
    return func(self, *args, **kwargs)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/mongo_client.py", line 1496, in _retry_internal
    return _ClientConnectionRetryable(
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/mongo_client.py", line 2353, in run
    return self._read() if self._is_read else self._write()
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/mongo_client.py", line 2485, in _read
    with self._client._conn_from_server(self._read_pref, self._server, self._session) as (
  File "/usr/lib/pritunl/usr/lib/python3.9/contextlib.py", line 119, in __enter__
    return next(self.gen)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/mongo_client.py", line 1357, in _conn_from_server
    with self._checkout(server, session) as conn:
  File "/usr/lib/pritunl/usr/lib/python3.9/contextlib.py", line 119, in __enter__
    return next(self.gen)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/mongo_client.py", line 1266, in _checkout
    with server.checkout(handler=err_handler) as conn:
  File "/usr/lib/pritunl/usr/lib/python3.9/contextlib.py", line 119, in __enter__
    return next(self.gen)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/pool.py", line 1767, in checkout
    conn = self._get_conn(checkout_started_time, handler=handler)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/pool.py", line 1926, in _get_conn
    conn = self.connect(handler=handler)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/pool.py", line 1729, in connect
    conn.authenticate()
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/pool.py", line 1099, in authenticate
    auth.authenticate(creds, self, reauthenticate=reauthenticate)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/auth.py", line 656, in authenticate
    auth_func(credentials, conn)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/auth_aws.py", line 35, in _authenticate_aws
    raise ConfigurationError(
pymongo.errors.ConfigurationError: MONGODB-AWS authentication requires pymongo-auth-aws: install with: python -m pip install 'pymongo[aws]'
Traceback (most recent call last):
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/auth_aws.py", line 33, in _authenticate_aws
    import pymongo_auth_aws  # type:ignore[import]
ModuleNotFoundError: No module named 'pymongo_auth_aws'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/bin/pritunl", line 33, in <module>
    sys.exit(load_entry_point('pritunl==1.32.4181.41', 'console_scripts', 'pritunl')())
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pritunl/__main__.py", line 480, in main
    setup.setup_db()
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pritunl/setup/__init__.py", line 82, in setup_db
    setup_mongo()
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pritunl/setup/mongo.py", line 351, in setup_mongo
    app_settings = settings_col.find_one({'_id': 'app'})
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/collection.py", line 1495, in find_one
    for result in cursor.limit(-1):
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/cursor.py", line 1243, in next
    if len(self.__data) or self._refresh():
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/cursor.py", line 1160, in _refresh
    self.__send_message(q)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/cursor.py", line 1039, in __send_message
    response = client._run_operation(
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/_csot.py", line 108, in csot_wrapper
    return func(self, *args, **kwargs)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/mongo_client.py", line 1431, in _run_operation
    return self._retryable_read(
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/mongo_client.py", line 1540, in _retryable_read
    return self._retry_internal(
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/_csot.py", line 108, in csot_wrapper
    return func(self, *args, **kwargs)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/mongo_client.py", line 1496, in _retry_internal
    return _ClientConnectionRetryable(
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/mongo_client.py", line 2353, in run
    return self._read() if self._is_read else self._write()
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/mongo_client.py", line 2485, in _read
    with self._client._conn_from_server(self._read_pref, self._server, self._session) as (
  File "/usr/lib/pritunl/usr/lib/python3.9/contextlib.py", line 119, in __enter__
    return next(self.gen)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/mongo_client.py", line 1357, in _conn_from_server
    with self._checkout(server, session) as conn:
  File "/usr/lib/pritunl/usr/lib/python3.9/contextlib.py", line 119, in __enter__
    return next(self.gen)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/mongo_client.py", line 1266, in _checkout
    with server.checkout(handler=err_handler) as conn:
  File "/usr/lib/pritunl/usr/lib/python3.9/contextlib.py", line 119, in __enter__
    return next(self.gen)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/pool.py", line 1767, in checkout
    conn = self._get_conn(checkout_started_time, handler=handler)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/pool.py", line 1926, in _get_conn
    conn = self.connect(handler=handler)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/pool.py", line 1729, in connect
    conn.authenticate()
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/pool.py", line 1099, in authenticate
    auth.authenticate(creds, self, reauthenticate=reauthenticate)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/auth.py", line 656, in authenticate
    auth_func(credentials, conn)
  File "/usr/lib/pritunl/usr/lib/python3.9/site-packages/pymongo/auth_aws.py", line 35, in _authenticate_aws
    raise ConfigurationError(
pymongo.errors.ConfigurationError: MONGODB-AWS authentication requires pymongo-auth-aws: install with: python -m pip install 'pymongo[aws]'

It may work after running sudo /usr/lib/pritunl/usr/bin/pip3.9 install pymongo-auth-aws but this would need to be run after every update. The client DNS mapping may still not work as that code uses the golang driver.

@zach , I’m not completely sure what are you referring to when you are mentioning “client DNS mapping”, could you collaborate a bit more?
Also isn’t it possible to have pymongo-auth-aws installed by default?
Thank you.

The Enable VPN Client DNS Mapping option in the server settings runs the pritunl-dns service which is written in Go and uses the mongo-go-driver. This may also have compability issues not resolved by installing the Python package.

It may be included by default in a future release but currently it isn’t.

Where can I read more about this feature?
Also what client DNS mapping has common with the database connection?

This create DNS mappings for each user at user_name.org_name.vpn.

I’m not clear on how these two features are related—likely due to my limited understanding of the application workflow. Specifically, I don’t see how the database connection could affect the VPN feature. Are you referring to → Internal DNS or VPC DNS Server ? Alternatively, could you provide a link to documentation so I can learn more about this? It seems that, because of Pritunl’s limitations, I might not be able to fully leverage MongoDB Atlas cluster security features.
Thank you.

The DNS doesn’t have any effect. The feature utilizes Go code that utilizes a different MongoDB driver, the mongo-go-driver. This driver may have compatibility issues with the IAM authentication that the PyMongo driver does not.

OK,

Based on what we have discussed so far to me it looks like achieving a seamless, fully supported configuration for AWS IAM authentication in MongoDB Atlas with Pritunl is problematic at the moment.
Can you confirm this @zach ?

Yes the server does not have support for it by default.

1 Like