Skip to content

Commit

Permalink
Add a database TLS option to trust system CAs (#43286)
Browse files Browse the repository at this point in the history
* Add a database TLS option to trust system CAs

* add doc

* review comments

* make derive
  • Loading branch information
greedy52 authored Jun 24, 2024
1 parent e89434a commit 3d8fb11
Show file tree
Hide file tree
Showing 13 changed files with 1,762 additions and 1,638 deletions.
7 changes: 7 additions & 0 deletions api/proto/teleport/legacy/types/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,13 @@ message DatabaseTLS {
// ServerName allows to provide custom hostname. This value will override the
// servername/hostname on a certificate during validation.
string ServerName = 3 [(gogoproto.jsontag) = "server_name,omitempty"];
// TrustSystemCertPool allows Teleport to trust certificate authorities
// available on the host system. If not set (by default), Teleport only
// trusts self-signed databases with TLS certificates signed by Teleport's
// Database Server CA or the ca_cert specified in this TLS setting. For
// cloud-hosted databases, Teleport downloads the corresponding required CAs
// for validation.
bool TrustSystemCertPool = 4 [(gogoproto.jsontag) = "trust_system_cert_pool,omitempty"];
}

// MySQLOptions are additional MySQL database options.
Expand Down
3 changes: 2 additions & 1 deletion api/types/derived.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3,302 changes: 1,672 additions & 1,630 deletions api/types/types.pb.go

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions docs/pages/database-access/reference/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,13 @@ spec:
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
# Optional configuration that allows Teleport to trust certificate
# authorities available on the host system. If not set (by default),
# Teleport only trusts self-signed databases with TLS certificates signed
# by Teleport's Database Server CA or the ca_cert specified in this TLS
# setting. For cloud-hosted databases, Teleport downloads the corresponding
# required CAs for validation.
trust_system_cert_pool: false

# Database admin user for automatic user provisioning.
admin_user:
Expand Down
7 changes: 7 additions & 0 deletions docs/pages/includes/config-reference/database-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ db_service:
server_name: db.example.com
# Optional path to the CA used to validate the database certificate.
ca_cert_file: /path/to/pem
# Optional configuration that allows Teleport to trust certificate
# authorities available on the host system. If not set (by default),
# Teleport only trusts self-signed databases with TLS certificates signed
# by Teleport's Database Server CA or the ca_cert_file specified in this
# TLS setting. For cloud-hosted databases, Teleport downloads the
# corresponding required CAs for validation.
trust_system_cert_pool: false

# MySQL only options.
mysql:
Expand Down
16 changes: 16 additions & 0 deletions docs/pages/includes/database-access/self-hosted-config-start.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,20 @@ To configure the Teleport Database Service to trust a custom CA:
--labels=env=dev
```


If your database servers use certificates that are signed by a public CA such
as ComodoCA or DigiCert, you can use the `trust_system_cert_pool` option
without exporting the CA:
```code
$ sudo teleport db configure create \
-o file \
--token=/tmp/token \
--proxy=<Var name="example.teleport.sh:443" /> \
--name={{ dbName }} \
--protocol={{ dbProtocol }} \
--uri={{ databaseAddress }} \
--trust_system_cert_pool \
--labels=env=dev
```

(!docs/pages/includes/start-teleport.mdx service="the Teleport Database Service"!)
7 changes: 4 additions & 3 deletions lib/config/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -1825,9 +1825,10 @@ func applyDatabasesConfig(fc *FileConfig, cfg *servicecfg.Config) error {
ServerVersion: database.MySQL.ServerVersion,
},
TLS: servicecfg.DatabaseTLS{
CACert: caBytes,
ServerName: database.TLS.ServerName,
Mode: servicecfg.TLSMode(database.TLS.Mode),
CACert: caBytes,
ServerName: database.TLS.ServerName,
Mode: servicecfg.TLSMode(database.TLS.Mode),
TrustSystemCertPool: database.TLS.TrustSystemCertPool,
},
AdminUser: servicecfg.DatabaseAdminUser{
Name: database.AdminUser.Name,
Expand Down
10 changes: 9 additions & 1 deletion lib/config/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,9 +364,14 @@ db_service:
{{- if .StaticDatabaseURI }}
uri: "{{ .StaticDatabaseURI }}"
{{- end}}
{{- if .DatabaseCACertFile }}
{{- if or .DatabaseCACertFile .DatabaseTrustSystemCertPool}}
tls:
{{- if .DatabaseCACertFile }}
ca_cert_file: "{{ .DatabaseCACertFile }}"
{{- end }}
{{- if .DatabaseTrustSystemCertPool }}
trust_system_cert_pool: {{ .DatabaseTrustSystemCertPool }}
{{- end }}
{{- end }}
{{- if or .DatabaseAWSRegion .DatabaseAWSAccountID .DatabaseAWSAssumeRoleARN .DatabaseAWSExternalID .DatabaseAWSRedshiftClusterID .DatabaseAWSRDSInstanceID .DatabaseAWSRDSClusterID .DatabaseAWSElastiCacheGroupID .DatabaseAWSMemoryDBClusterName }}
aws:
Expand Down Expand Up @@ -658,6 +663,9 @@ type DatabaseSampleFlags struct {
DatabaseGCPInstanceID string
// DatabaseCACertFile is the database CA cert path.
DatabaseCACertFile string
// DatabaseTrustSystemCertPool allows Teleport to trust certificate
// authorities available on the host system.
DatabaseTrustSystemCertPool bool
}

// CheckAndSetDefaults checks and sets default values for the flags.
Expand Down
3 changes: 3 additions & 0 deletions lib/config/fileconf.go
Original file line number Diff line number Diff line change
Expand Up @@ -1843,6 +1843,9 @@ type DatabaseTLS struct {
ServerName string `yaml:"server_name,omitempty"`
// CACertFile is an optional path to the database CA certificate.
CACertFile string `yaml:"ca_cert_file,omitempty"`
// TrustSystemCertPool allows Teleport to trust certificate authorities
// available on the host system.
TrustSystemCertPool bool `yaml:"trust_system_cert_pool,omitempty"`
}

// DatabaseMySQL are an additional MySQL database options.
Expand Down
10 changes: 7 additions & 3 deletions lib/service/servicecfg/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,10 @@ func (d *Database) ToDatabase() (types.Database, error) {
URI: d.URI,
CACert: string(d.TLS.CACert),
TLS: types.DatabaseTLS{
CACert: string(d.TLS.CACert),
ServerName: d.TLS.ServerName,
Mode: d.TLS.Mode.ToProto(),
CACert: string(d.TLS.CACert),
ServerName: d.TLS.ServerName,
Mode: d.TLS.Mode.ToProto(),
TrustSystemCertPool: d.TLS.TrustSystemCertPool,
},
MySQL: types.MySQLOptions{
ServerVersion: d.MySQL.ServerVersion,
Expand Down Expand Up @@ -204,6 +205,9 @@ type DatabaseTLS struct {
ServerName string
// CACert is an optional database CA certificate.
CACert []byte
// TrustSystemCertPool allows Teleport to trust certificate authorities
// available on the host system.
TrustSystemCertPool bool
}

// DatabaseAWS contains AWS specific settings for RDS/Aurora databases.
Expand Down
4 changes: 4 additions & 0 deletions lib/srv/db/common/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,10 @@ func setupTLSConfigRootCAs(tlsConfig *tls.Config, sessionCtx *Session) error {
// certificates signed by publicly trusted CAs so a system cert pool can be
// used.
func shouldUseSystemCertPool(sessionCtx *Session) bool {
if sessionCtx.Database.GetTLS().TrustSystemCertPool {
return true
}

switch sessionCtx.Database.GetType() {
// Azure databases either use Baltimore Root CA or DigiCert Global Root G2.
//
Expand Down
23 changes: 23 additions & 0 deletions lib/srv/db/common/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,13 @@ func TestAuthGetTLSConfig(t *testing.T) {
expectRootCAs: defaultCertPool,
expectClientCertificates: true,
},
{
name: "self-hosted with trust_system_cert_pool",
sessionDatabase: newSelfHostedDatabaseWithTrustSytemCertPool(t, "postgres.dev.example.com:8888"),
expectServerName: "postgres.dev.example.com",
expectRootCAs: systemCertPoolWithCA,
expectClientCertificates: true,
},
{
name: "AWS ElastiCache Redis",
sessionDatabase: newElastiCacheRedisDatabase(t, withCA(fixtures.SAMLOktaCertPEM)),
Expand Down Expand Up @@ -715,6 +722,22 @@ func newAzureRedisDatabase(t *testing.T, resourceID string) types.Database {
return database
}

func newSelfHostedDatabaseWithTrustSytemCertPool(t *testing.T, uri string) types.Database {
t.Helper()

database, err := types.NewDatabaseV3(types.Metadata{
Name: "test-database",
}, types.DatabaseSpecV3{
Protocol: defaults.ProtocolMySQL,
URI: uri,
TLS: types.DatabaseTLS{
TrustSystemCertPool: true,
},
})
require.NoError(t, err)
return database
}

func newSelfHostedDatabase(t *testing.T, uri string) types.Database {
t.Helper()

Expand Down
1 change: 1 addition & 0 deletions tool/teleport/common/teleport.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ func Run(options Options) (app *kingpin.Application, executedCommand string, con
"Write to stdout with -o=stdout, default config file with -o=file or custom path with -o=file:///path").Short('o').Default(
teleport.SchemeStdout).StringVar(&dbConfigCreateFlags.output)
dbConfigureCreate.Flag("dynamic-resources-labels", "Comma-separated list(s) of labels to match dynamic resources, for example env=dev,dept=it. Required to enable dynamic resources matching.").StringsVar(&dbConfigCreateFlags.DynamicResourcesRawLabels)
dbConfigureCreate.Flag("trust-system-cert-pool", "Allows Teleport to trust certificate authorities available on the host system for self-hosted databases.").BoolVar(&dbConfigCreateFlags.DatabaseTrustSystemCertPool)
dbConfigureCreate.Alias(dbCreateConfigExamples) // We're using "alias" section to display usage examples.

dbConfigureBootstrap := dbConfigure.Command("bootstrap", "Bootstrap the necessary configuration for the database agent. It reads the provided agent configuration to determine what will be bootstrapped.")
Expand Down

0 comments on commit 3d8fb11

Please sign in to comment.