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

Allow users to request database certificates in Machine ID #11904

Merged
merged 6 commits into from
Apr 19, 2022

Conversation

timothyb89
Copy link
Contributor

@timothyb89 timothyb89 commented Apr 12, 2022

This adds a new destination-level config option to tbot.yaml that allows users to request database access for a particular destination certificate. Behind the scenes, this triggers generates two impersonated certs: the first identity is generated to request the specified roles and resolve the database config, then is replaced with a new identity using those roles plus a fully-formed RouteToDatabase request. We don't match tsh's behavior here as the additional certs generated conceptually similar enough to Machine ID's multiple destinations - if users don't want a cert with RouteToDatabase they can just add another destination with the same roles.

Database requests are made by adding a destination entry like the following to tbot.yaml:

destinations:
  - directory: ./tbot-user

    database:
      service: <teleport database name>
      username: <database username>
      database: <database name>

    # The certs won't be very useful without TLS
    kinds: [tls]

We currently don't support proxying or generating db-specific config files. See #11596 for an identityfile implementation that can help. Additionally, we don't currently have a tsh proxy equivalent so the legacy MySQL handlers need to be enabled, which is not the case by default in Teleport 9. However, that same PR can export a tsh-compatible identity file for the datbase identity which can be passed along to tsh -i ... and presumably used with its proxy commands. We plan to follow-up with another PR to improve this UX.

If using MySQL/MariaDB with the legacy proxy handler exposed, this command should connect to the database:

mariadb -vvvv --ssl-key ./tbot-user/key --ssl-ca tbot-user/tlscacerts-test --ssl-cert ./tbot-user/tlscert  -h <teleport proxy host> --port=3036 --protocol TCP -u <database username> --ssl-verify-server-cert

Somewhat unrelatedly, this PR also moves most cert renewal-related code into a new file. It makes for an unpleasant diff, but it needed to happen eventually.

This adds a new destination-level config option to `tbot.yaml` that
allows users to request database access for a particular destination
certificate. Behind the scenes, this triggers generates two
impersonated certs: the first identity is generated to request the
specified roles and resolve the database config, then is replaced
with a new identity using those roles plus a fully-formed
`RouteToDatabase` request.

Database requests are made by adding a destination entry like the
following to `tbot.yaml`:
```yaml
destinations:
  - directory: /foo/bar

    database:
      service: <teleport database name>
      username: <database username>
      database: <database name>

    # The certs won't be very useful without TLS
    kinds: [tls]
```

We currently don't support proxying or generating db-specific config
files. See #11596 for an `identityfile` implementation that can help.
Additionally, we don't currently have a `tsh proxy` equivalent so the
legacy MySQL handlers need to be enabled, which is not the case by
default in Teleport 9. However, that same PR can export a
tsh-compatible identity file for the datbase identity which can be
passed along to `tsh -i ...` and presumably used with its proxy
commands. We plan to follow-up with another PR to improve this UX.
@timothyb89
Copy link
Contributor Author

While writing the PR description I realized I did still have a manual hack in place for the TLS CA certs. We still use $ as a separator character since we internally need both Teleport's user and host certs, but obviously literally nothing supports this "format". I'm gonna think on the best way around this - we might just not want to write these weird cert types to destination dirs since the bot doesn't even use them, and separately write sensible CA certs.

Comment on lines 26 to 27
// Service is the service name of the
Service string `yaml:"service,omitempty"`
Copy link
Collaborator

Choose a reason for hiding this comment

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

The godoc is incomplete here. What is service supposed to be?

tool/tbot/renew.go Outdated Show resolved Hide resolved
tool/tbot/testhelpers/srv.go Outdated Show resolved Hide resolved
@timothyb89
Copy link
Contributor Author

After thinking on it I think I'd like to resolve the missing TLS CAs as part of #11596 where we'll be making significant changes to artifact saving/loading anyway. Any changes here are just going to create conflicts and I don't think it's too awful to borrow the cluster's CA cert from tsh or cut and paste it from our tlscacerts for testing purposes.

@timothyb89 timothyb89 marked this pull request as ready for review April 14, 2022 00:14
@github-actions github-actions bot requested review from jakule and r0mant April 14, 2022 00:14
tool/tbot/renew.go Outdated Show resolved Hide resolved
timothyb89 and others added 2 commits April 15, 2022 11:57
Co-authored-by: Roman Tkachenko <roman@goteleport.com>
@timothyb89 timothyb89 enabled auto-merge (squash) April 19, 2022 23:11
@timothyb89 timothyb89 merged commit 27f96a4 into master Apr 19, 2022
@timothyb89 timothyb89 deleted the timothyb89/machineid-database-certs branch April 19, 2022 23:34
timothyb89 added a commit that referenced this pull request Apr 23, 2022
* Allow users to request database certificates in Machine ID

This adds a new destination-level config option to `tbot.yaml` that
allows users to request database access for a particular destination
certificate. Behind the scenes, this triggers generates two
impersonated certs: the first identity is generated to request the
specified roles and resolve the database config, then is replaced
with a new identity using those roles plus a fully-formed
`RouteToDatabase` request.

Database requests are made by adding a destination entry like the
following to `tbot.yaml`:
```yaml
destinations:
  - directory: /foo/bar

    database:
      service: <teleport database name>
      username: <database username>
      database: <database name>

    # The certs won't be very useful without TLS
    kinds: [tls]
```

We currently don't support proxying or generating db-specific config
files. See #11596 for an `identityfile` implementation that can help.
Additionally, we don't currently have a `tsh proxy` equivalent so the
legacy MySQL handlers need to be enabled, which is not the case by
default in Teleport 9. However, that same PR can export a
tsh-compatible identity file for the datbase identity which can be
passed along to `tsh -i ...` and presumably used with its proxy
commands. We plan to follow-up with another PR to improve this UX.

* Try to fix flaky test

* Address review feedback

* Update tool/tbot/renew.go

Co-authored-by: Roman Tkachenko <roman@goteleport.com>

* Add special username checks for MongoDB and Redis

Co-authored-by: Roman Tkachenko <roman@goteleport.com>
timothyb89 added a commit that referenced this pull request May 4, 2022
…12195)

* Allow users to request database certificates in Machine ID

This adds a new destination-level config option to `tbot.yaml` that
allows users to request database access for a particular destination
certificate. Behind the scenes, this triggers generates two
impersonated certs: the first identity is generated to request the
specified roles and resolve the database config, then is replaced
with a new identity using those roles plus a fully-formed
`RouteToDatabase` request.

Database requests are made by adding a destination entry like the
following to `tbot.yaml`:
```yaml
destinations:
  - directory: /foo/bar

    database:
      service: <teleport database name>
      username: <database username>
      database: <database name>

    # The certs won't be very useful without TLS
    kinds: [tls]
```

We currently don't support proxying or generating db-specific config
files. See #11596 for an `identityfile` implementation that can help.
Additionally, we don't currently have a `tsh proxy` equivalent so the
legacy MySQL handlers need to be enabled, which is not the case by
default in Teleport 9. However, that same PR can export a
tsh-compatible identity file for the datbase identity which can be
passed along to `tsh -i ...` and presumably used with its proxy
commands. We plan to follow-up with another PR to improve this UX.

* Try to fix flaky test

* Address review feedback

* Update tool/tbot/renew.go

Co-authored-by: Roman Tkachenko <roman@goteleport.com>

* Add special username checks for MongoDB and Redis

Co-authored-by: Roman Tkachenko <roman@goteleport.com>

Co-authored-by: Roman Tkachenko <roman@goteleport.com>
@webvictim webvictim mentioned this pull request Jun 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants