Skip to content

Database Automatic User Provisioning support for self-hosted MongoDB#33717

Merged
greedy52 merged 11 commits intomasterfrom
STeve/27323_self_hosted_mongo
Dec 3, 2023
Merged

Database Automatic User Provisioning support for self-hosted MongoDB#33717
greedy52 merged 11 commits intomasterfrom
STeve/27323_self_hosted_mongo

Conversation

@greedy52
Copy link
Copy Markdown
Contributor

@greedy52 greedy52 commented Oct 19, 2023

Part of #27323

changelog: Database Automatic User Provisioning support for self-hosted MongoDB

Implemented as RFD: #33750

Testing:

  • Modes
    • keep
    • drop
  • Single self-hosted MongoDB
    • Mongo 7.0
    • Mongo 6.0
    • Mongo 5.0
    • Mongo 4.4
    • Mongo 4.2
    • Mongo 4.0
Manual testing example

1. Configure self-hosted MongoDB

Setup a self-hosted MongoDB. Sample docker setup
https://github.com/greedy52/teleport-database-test-setup/tree/main/mongo

Log into the database as the default admin, for ex:

docker exec -it mongo mongosh -u mongoadmin -p secret

Create the role for teleport-admin:

db.getSiblingDB("admin").runCommand({
    createRole: "teleport-admin-role",
    privileges: [
        { resource: { cluster: true }, actions: [ "inprog" ] },
        { resource: { db: "", collection: "" }, actions: [ "grantRole", "revokeRole" ] },
        { resource: { db: "$external", "collection": "" }, actions: [ "createUser", "updateUser", "dropUser", "viewUser", "setAuthenticationRestriction", "changeCustomData"] },
    ],
    roles: [],
})

Create teleport-admin user:

db.getSiblingDB("$external").runCommand({
  createUser: "CN=teleport-admin",
  roles: [ { role: 'teleport-admin-role', db: 'admin' } ],
})

Create a custom role for testing:

db.getSiblingDB("test").createRole({role: "my-custom-role", privileges:[], roles:[]});

2. Configure Teleport

Create a Teleport role for auto-user and assign it to your Teleport user, ex:

kind: role
version: v6
metadata:
  name: mongo-auto-user
spec:
  options:
    create_db_user_mode: keep
  allow:
    db_labels:
      automongo: "true"
    db_names:
    - "*"
    db_roles:
    - read@test2
    - readWrite@test
    - my-custom-role@test

Assign the role to your User.

Create a database:

  - name: "self-hosted-mongo-auto"
    protocol: "mongodb"
    uri: "localhost:27017"
    static_labels:
      automongo: "true"
    admin_user:
      name: "teleport-admin"

3. Connect

  • tsh login
  • tsh db connect --db-user <teleport-user> --db-name test self-hosted-mongo-auto
test> db.users.insertOne({name:"steve", age: 99})
{
  acknowledged: true,
  insertedId: ObjectId("...")
}
test> use $external
$external> db.getUser("CN=<teleport-user>",{showCustomData:1})
{
  _id: '$external.CN=<teleport-user>',
  userId: new UUID("..."),
  user: 'CN=STeve',
  db: '$external',
  customData: { 'teleport-auto-user': true },
  roles: [
    { role: 'readWrite', db: 'test' },
    { role: 'read', db: 'test2' },
    { role: 'my-custom-role', db: 'test' }
  ],
  mechanisms: [ 'external' ]
}

The change is ready but waiting for #34132 to merge before open for review.
Also need #34271 to show proper error messages when setup is bad.

@greedy52 greedy52 added database-access Database access related issues and PRs db/mongo MongoDB related database access issues do-not-merge changelog labels Oct 19, 2023
@greedy52 greedy52 self-assigned this Oct 19, 2023
@greedy52 greedy52 force-pushed the STeve/27323_self_hosted_mongo branch 2 times, most recently from 4d1c9c8 to 914369e Compare October 24, 2023 18:38
@greedy52 greedy52 force-pushed the STeve/27323_self_hosted_mongo branch from 399a50e to 95217ed Compare October 30, 2023 15:28
@greedy52 greedy52 changed the base branch from master to STeve/27323_refactor_role November 4, 2023 01:44
@greedy52 greedy52 force-pushed the STeve/27323_self_hosted_mongo branch 2 times, most recently from cc48523 to 398a930 Compare November 4, 2023 02:14
Base automatically changed from STeve/27323_refactor_role to master November 9, 2023 15:12
@greedy52 greedy52 force-pushed the STeve/27323_self_hosted_mongo branch from 8b83049 to 672aed7 Compare November 9, 2023 16:22
@greedy52 greedy52 marked this pull request as ready for review November 9, 2023 16:50
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Nov 9, 2023

The PR changelog entry failed validation: Changelog entry not found in the PR body. Please add a "no-changelog" label to the PR, or changelog lines starting with changelog: followed by the changelog entries for the PR.

@github-actions github-actions Bot requested a review from AntonAM November 9, 2023 16:51
Copy link
Copy Markdown
Contributor

@smallinsky smallinsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job. Tested on my local setup without any issue. LGTM

Comment thread lib/srv/db/mongodb/autousers.go Outdated
Comment thread lib/srv/db/mongodb/autousers.go Outdated
Comment thread lib/srv/db/mongodb/autousers.go Outdated
Comment thread lib/srv/db/mongodb/autousers.go Outdated
Comment thread lib/srv/db/mongodb/autousers.go Outdated
Comment thread lib/srv/db/mongodb/autousers_admin.go
Comment on lines +62 to +64
databaseName string
databaseURI string
adminUser string
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably there is a corner case during CA rotation where a shared client should be reused but a connection needs to be recreated but this should be really narrow case.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. During a rotation, the server should be restarted with a new configuration so the connection will be dead. The connection could be killed for other reasons as well.

Let me try to add a check on whether the shared client is dead after getting it from the cache. If so, just make a non-shared client.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems the mongo client connection pool has the ability to reconnect even if i restarted mongo docker. So I will not handle that case.

As for the CA rotation case, users should understand that the connection may have issues during rotation. And it should self-heal after cache expires (one minute). I will leave a comment in the code for this case but not worth it to fix properly.

Comment thread lib/srv/db/mongodb/autousers.go
Comment thread lib/srv/db/mongodb/autousers.go
Comment thread lib/srv/db/mongodb/autousers_admin.go Outdated
Copy link
Copy Markdown
Contributor

@gabrielcorado gabrielcorado left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've also tested with my local setup and everything worked as expected. Nice work.

@greedy52 greedy52 enabled auto-merge December 3, 2023 01:31
@greedy52 greedy52 disabled auto-merge December 3, 2023 01:42
@greedy52 greedy52 enabled auto-merge December 3, 2023 02:16
@greedy52 greedy52 force-pushed the STeve/27323_self_hosted_mongo branch from eca68d2 to 492b307 Compare December 3, 2023 02:17
@greedy52 greedy52 added this pull request to the merge queue Dec 3, 2023
Merged via the queue into master with commit d9e2492 Dec 3, 2023
@greedy52 greedy52 deleted the STeve/27323_self_hosted_mongo branch December 3, 2023 02:57
greedy52 added a commit that referenced this pull request Dec 4, 2023
…33717)

* Database Automatic User Provisioning support for self-hosted MongoDB

* Use user's customData instead of teleport-auto-user role

* cache admin connections

* add UT in db/mongodb

* add UT in db/autousers_test

* check version for showCustomData

* remove command comment to compat with older versions

* address comments round 1

* update new license

* ensure shared client is diabled during CI
github-merge-queue Bot pushed a commit that referenced this pull request Dec 4, 2023
…ngoDB (#35317)

* Database Automatic User Provisioning support for self-hosted MongoDB (#33717)

* Database Automatic User Provisioning support for self-hosted MongoDB

* Use user's customData instead of teleport-auto-user role

* cache admin connections

* add UT in db/mongodb

* add UT in db/autousers_test

* check version for showCustomData

* remove command comment to compat with older versions

* address comments round 1

* update new license

* ensure shared client is diabled during CI

* replace license

* fix ut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

database-access Database access related issues and PRs db/mongo MongoDB related database access issues size/lg

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants