From 17f50fb07a2c6df95bf19190a3597b4ba998361c Mon Sep 17 00:00:00 2001 From: Jakub Nyckowski Date: Sun, 13 Feb 2022 00:02:19 -0500 Subject: [PATCH 1/8] Add MariaDB AWS auto discovery --- lib/services/database.go | 8 +++++--- lib/srv/db/cloud/watchers/rds.go | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/services/database.go b/lib/services/database.go index 12faa8aa21613..75f25063c341b 100644 --- a/lib/services/database.go +++ b/lib/services/database.go @@ -290,7 +290,7 @@ func engineToProtocol(engine string) string { switch engine { case RDSEnginePostgres, RDSEngineAuroraPostgres: return defaults.ProtocolPostgres - case RDSEngineMySQL, RDSEngineAurora, RDSEngineAuroraMySQL: + case RDSEngineMySQL, RDSEngineAurora, RDSEngineAuroraMySQL, RDSEngineMariaDB: return defaults.ProtocolMySQL } return "" @@ -536,6 +536,8 @@ const ( RDSEngineMySQL = "mysql" // RDSEnginePostgres is RDS engine name for Postgres instances. RDSEnginePostgres = "postgres" + // RDSEngineMariaDB is RDS engine name for MariaDB instances. + RDSEngineMariaDB = "mariadb" // RDSEngineAurora is RDS engine name for Aurora MySQL 5.6 compatible clusters. RDSEngineAurora = "aurora" // RDSEngineAuroraMySQL is RDS engine name for Aurora MySQL 5.7 compatible clusters. @@ -553,9 +555,9 @@ const ( // RDSEndpointTypeReader is the endpoint that load-balances connections across the Aurora Replicas that are // available in a RDS cluster. RDSEndpointTypeReader RDSEndpointType = "reader" - // RDSEndpointTypeCustom is the endpoint that specifieds one of the custom endpoints associated with the RDS cluster. + // RDSEndpointTypeCustom is the endpoint that specified one of the custom endpoints associated with the RDS cluster. RDSEndpointTypeCustom RDSEndpointType = "custom" - // RDSEndpointTypeInstance is the endpoint of a RDS DB instance. + // RDSEndpointTypeInstance is the endpoint of an RDS DB instance. RDSEndpointTypeInstance RDSEndpointType = "instance" ) diff --git a/lib/srv/db/cloud/watchers/rds.go b/lib/srv/db/cloud/watchers/rds.go index 3f697b9cbeda7..a2ffd2611b298 100644 --- a/lib/srv/db/cloud/watchers/rds.go +++ b/lib/srv/db/cloud/watchers/rds.go @@ -275,7 +275,8 @@ func rdsFilters() []*rds.Filter { Name: aws.String("engine"), Values: aws.StringSlice([]string{ services.RDSEnginePostgres, - services.RDSEngineMySQL}), + services.RDSEngineMySQL, + services.RDSEngineMariaDB}), }} } From bd54ae55267fd7f61f75178c0478d34518fb710c Mon Sep 17 00:00:00 2001 From: Jakub Nyckowski Date: Thu, 3 Mar 2022 03:00:19 -0500 Subject: [PATCH 2/8] Add MariaDB AWS IAM version check --- lib/services/database.go | 24 +++++++++++++++- lib/services/database_test.go | 48 ++++++++++++++++++++++++++++++++ lib/srv/db/cloud/watchers/rds.go | 8 ++++++ 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/lib/services/database.go b/lib/services/database.go index 75f25063c341b..bfad8247bc42f 100644 --- a/lib/services/database.go +++ b/lib/services/database.go @@ -21,6 +21,7 @@ import ( "fmt" "strings" + "github.com/coreos/go-semver/semver" "github.com/gravitational/teleport/api/types" apiutils "github.com/gravitational/teleport/api/utils" "github.com/gravitational/teleport/lib/defaults" @@ -49,7 +50,7 @@ type Databases interface { DatabaseGetter // CreateDatabase creates a new database resource. CreateDatabase(context.Context, types.Database) error - // UpdateDatabse updates an existing database resource. + // UpdateDatabase updates an existing database resource. UpdateDatabase(context.Context, types.Database) error // DeleteDatabase removes the specified database resource. DeleteDatabase(ctx context.Context, name string) error @@ -369,6 +370,27 @@ func rdsTagsToLabels(tags []*rds.Tag) map[string]string { return labels } +// IsRDSInstanceSupported returns true if database supports IAM authentication. +// Currently, only MariaDB is being checked as all other RDS databases supports +// IAM authentication in all configurations. +func IsRDSInstanceSupported(instance *rds.DBInstance) bool { + if aws.StringValue(instance.Engine) != RDSEngineMariaDB { + return true + } + + // MariaDB follows semver schema: https://mariadb.org/about/ + ver, err := semver.NewVersion(aws.StringValue(instance.EngineVersion)) + if err != nil { + log.Errorf("Failed to parse RDS MariaDB version: %s", aws.StringValue(instance.EngineVersion)) + return false + } + + // Min supported MariaDB version that supports IAM is 10.6 + // https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html + minIAMSupportedVer := semver.New("10.6.0") + return ver.Compare(*minIAMSupportedVer) >= 0 +} + // IsRDSClusterSupported checks whether the aurora cluster is supported and logs // related info if not. func IsRDSClusterSupported(cluster *rds.DBCluster) bool { diff --git a/lib/services/database_test.go b/lib/services/database_test.go index c16862d506f3a..745ef79999dee 100644 --- a/lib/services/database_test.go +++ b/lib/services/database_test.go @@ -364,6 +364,54 @@ func TestIsRDSClusterSupported(t *testing.T) { } } +func TestIsRDSInstanceSupported(t *testing.T) { + tests := []struct { + name string + engine string + engineVersion string + isSupported bool + }{ + { + name: "non-MariaDB engine", + engine: RDSEnginePostgres, + engineVersion: "13.3", + isSupported: true, + }, + { + name: "unsupported MariaDB", + engine: RDSEngineMariaDB, + engineVersion: "10.3.28", + isSupported: false, + }, + { + name: "min supported version", + engine: RDSEngineMariaDB, + engineVersion: "10.6.2", + isSupported: true, + }, + { + name: "supported version", + engine: RDSEngineMariaDB, + engineVersion: "10.8.0", + isSupported: true, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + cluster := &rds.DBInstance{ + DBInstanceArn: aws.String("arn:aws:rds:us-east-1:1234567890:instance:test"), + DBClusterIdentifier: aws.String(test.name), + DbiResourceId: aws.String(uuid.New().String()), + Engine: aws.String(test.engine), + EngineVersion: aws.String(test.engineVersion), + } + + require.Equal(t, test.isSupported, IsRDSInstanceSupported(cluster)) + }) + } +} + func TestRDSTagsToLabels(t *testing.T) { rdsTags := []*rds.Tag{ &rds.Tag{ diff --git a/lib/srv/db/cloud/watchers/rds.go b/lib/srv/db/cloud/watchers/rds.go index a2ffd2611b298..17fa187f6787d 100644 --- a/lib/srv/db/cloud/watchers/rds.go +++ b/lib/srv/db/cloud/watchers/rds.go @@ -106,6 +106,14 @@ func (f *rdsDBInstancesFetcher) getRDSDatabases(ctx context.Context) (types.Data } databases := make(types.Databases, 0, len(instances)) for _, instance := range instances { + if !services.IsRDSInstanceSupported(instance) { + f.log.Debugf("RDS instance %q (engine mode %v, engine version %v) doesn't support IAM authentication. Skipping.", + aws.StringValue(instance.DBInstanceIdentifier), + aws.StringValue(instance.Engine), + aws.StringValue(instance.EngineVersion)) + continue + } + if !services.IsRDSInstanceAvailable(instance) { f.log.Debugf("The current status of RDS instance %q is %q. Skipping.", aws.StringValue(instance.DBInstanceIdentifier), From 01bdefeda6c3d4efcd729b0f09568235ad5728ee Mon Sep 17 00:00:00 2001 From: Jakub Nyckowski Date: Thu, 3 Mar 2022 11:52:42 -0500 Subject: [PATCH 3/8] Add MariaDB to RDS docs. --- docs/pages/database-access/guides/rds.mdx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/pages/database-access/guides/rds.mdx b/docs/pages/database-access/guides/rds.mdx index fba667601e2d2..50255d7c84978 100644 --- a/docs/pages/database-access/guides/rds.mdx +++ b/docs/pages/database-access/guides/rds.mdx @@ -1,6 +1,6 @@ --- -title: Database Access with AWS RDS and Aurora for PostgreSQL and MySQL -description: How to configure Teleport Database Access with AWS RDS and Aurora for PostgreSQL and MySQL. +title: Database Access with AWS RDS and Aurora for PostgreSQL, MySQL and MariaDB. +description: How to configure Teleport Database Access with AWS RDS and Aurora for PostgreSQL, MySQL and MariaDB. --- This guide will help you to: @@ -14,6 +14,11 @@ This guide will help you to: writing so it can't be used with Database Access. + + The minimum supported version of MariaDB is 10.6. Older versions don't support + IAM authentication and they can't be used with Database Access. + + ## Prerequisites - Teleport version `(=teleport.version=)`. @@ -318,8 +323,8 @@ Access for RDS. See below how to enable it for your database engine. GRANT rds_iam TO alice; ``` - - MySQL users must have RDS authentication plugin enabled: + + MySQL and MariaDB users must have RDS authentication plugin enabled: ```sql CREATE USER alice IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS'; From c0faaf78490ce5ba32a5d15c9a21319c0fa70bc8 Mon Sep 17 00:00:00 2001 From: Jakub Nyckowski Date: Fri, 4 Mar 2022 17:27:55 -0500 Subject: [PATCH 4/8] Apply suggestions from code review Co-authored-by: Paul Gottschling Co-authored-by: Alan Parra --- docs/pages/database-access/guides/rds.mdx | 4 ++-- lib/services/database.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/pages/database-access/guides/rds.mdx b/docs/pages/database-access/guides/rds.mdx index 50255d7c84978..ecc336012da78 100644 --- a/docs/pages/database-access/guides/rds.mdx +++ b/docs/pages/database-access/guides/rds.mdx @@ -1,5 +1,5 @@ --- -title: Database Access with AWS RDS and Aurora for PostgreSQL, MySQL and MariaDB. +title: Database Access with AWS RDS and Aurora for PostgreSQL, MySQL and MariaDB description: How to configure Teleport Database Access with AWS RDS and Aurora for PostgreSQL, MySQL and MariaDB. --- @@ -324,7 +324,7 @@ Access for RDS. See below how to enable it for your database engine. ``` - MySQL and MariaDB users must have RDS authentication plugin enabled: + MySQL and MariaDB users must have the RDS authentication plugin enabled: ```sql CREATE USER alice IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS'; diff --git a/lib/services/database.go b/lib/services/database.go index bfad8247bc42f..915cdbb4aad5d 100644 --- a/lib/services/database.go +++ b/lib/services/database.go @@ -577,7 +577,7 @@ const ( // RDSEndpointTypeReader is the endpoint that load-balances connections across the Aurora Replicas that are // available in a RDS cluster. RDSEndpointTypeReader RDSEndpointType = "reader" - // RDSEndpointTypeCustom is the endpoint that specified one of the custom endpoints associated with the RDS cluster. + // RDSEndpointTypeCustom is the endpoint that specifies one of the custom endpoints associated with the RDS cluster. RDSEndpointTypeCustom RDSEndpointType = "custom" // RDSEndpointTypeInstance is the endpoint of an RDS DB instance. RDSEndpointTypeInstance RDSEndpointType = "instance" From 426202d0bd8adc72fcd6c83efef88eea7e7a28e1 Mon Sep 17 00:00:00 2001 From: Jakub Nyckowski Date: Fri, 4 Mar 2022 17:47:35 -0500 Subject: [PATCH 5/8] Address code review comments. --- docs/pages/database-access/guides/rds.mdx | 12 ++++-------- lib/services/database.go | 8 ++++---- lib/services/database_test.go | 7 ++++--- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/docs/pages/database-access/guides/rds.mdx b/docs/pages/database-access/guides/rds.mdx index ecc336012da78..57bfd2c96010a 100644 --- a/docs/pages/database-access/guides/rds.mdx +++ b/docs/pages/database-access/guides/rds.mdx @@ -9,14 +9,10 @@ This guide will help you to: - Set up Teleport to access your RDS instances and Aurora clusters. - Connect to your databases through Teleport. - - Aurora Serverless does not support IAM authentication at the time of this - writing so it can't be used with Database Access. - - - - The minimum supported version of MariaDB is 10.6. Older versions don't support - IAM authentication and they can't be used with Database Access. + + The following products are not compatible with Database Access as they don't support IAM authentication: + * Aurora Serverless. + * RDS MariaDB in version lower than 10.6. ## Prerequisites diff --git a/lib/services/database.go b/lib/services/database.go index 915cdbb4aad5d..0d53cbe48cf8d 100644 --- a/lib/services/database.go +++ b/lib/services/database.go @@ -21,7 +21,6 @@ import ( "fmt" "strings" - "github.com/coreos/go-semver/semver" "github.com/gravitational/teleport/api/types" apiutils "github.com/gravitational/teleport/api/utils" "github.com/gravitational/teleport/lib/defaults" @@ -32,6 +31,7 @@ import ( "github.com/aws/aws-sdk-go/service/rds" "github.com/aws/aws-sdk-go/service/redshift" + "github.com/coreos/go-semver/semver" "github.com/gravitational/trace" log "github.com/sirupsen/logrus" ) @@ -371,9 +371,9 @@ func rdsTagsToLabels(tags []*rds.Tag) map[string]string { } // IsRDSInstanceSupported returns true if database supports IAM authentication. -// Currently, only MariaDB is being checked as all other RDS databases supports -// IAM authentication in all configurations. +// Currently, only MariaDB is being checked. func IsRDSInstanceSupported(instance *rds.DBInstance) bool { + // TODO(jakule): Check other engines. if aws.StringValue(instance.Engine) != RDSEngineMariaDB { return true } @@ -388,7 +388,7 @@ func IsRDSInstanceSupported(instance *rds.DBInstance) bool { // Min supported MariaDB version that supports IAM is 10.6 // https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html minIAMSupportedVer := semver.New("10.6.0") - return ver.Compare(*minIAMSupportedVer) >= 0 + return !ver.LessThan(*minIAMSupportedVer) } // IsRDSClusterSupported checks whether the aurora cluster is supported and logs diff --git a/lib/services/database_test.go b/lib/services/database_test.go index 745ef79999dee..0e50fc7243930 100644 --- a/lib/services/database_test.go +++ b/lib/services/database_test.go @@ -358,8 +358,8 @@ func TestIsRDSClusterSupported(t *testing.T) { EngineVersion: aws.String(test.engineVersion), } - require.Equal(t, test.isSupported, IsRDSClusterSupported(cluster)) - + got, want := IsRDSClusterSupported(cluster), test.isSupported + require.Equal(t, want, got, "IsRDSClusterSupported = %v, want = %v", got, want) }) } } @@ -407,7 +407,8 @@ func TestIsRDSInstanceSupported(t *testing.T) { EngineVersion: aws.String(test.engineVersion), } - require.Equal(t, test.isSupported, IsRDSInstanceSupported(cluster)) + got, want := IsRDSInstanceSupported(cluster), test.isSupported + require.Equal(t, want, got, "IsRDSInstanceSupported = %v, want = %v", got, want) }) } } From 48facd56b2d3f4d69ebde94e68b6b225b382a006 Mon Sep 17 00:00:00 2001 From: Jakub Nyckowski Date: Mon, 7 Mar 2022 22:28:47 -0500 Subject: [PATCH 6/8] Address code review comments. --- docs/pages/database-access/guides/rds.mdx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/pages/database-access/guides/rds.mdx b/docs/pages/database-access/guides/rds.mdx index 57bfd2c96010a..58eee96c656b5 100644 --- a/docs/pages/database-access/guides/rds.mdx +++ b/docs/pages/database-access/guides/rds.mdx @@ -1,5 +1,6 @@ --- -title: Database Access with AWS RDS and Aurora for PostgreSQL, MySQL and MariaDB +title: Database Access with AWS RDS and Aurora +h1: Database Access with AWS RDS and Aurora for PostgreSQL, MySQL and MariaDB description: How to configure Teleport Database Access with AWS RDS and Aurora for PostgreSQL, MySQL and MariaDB. --- @@ -12,7 +13,7 @@ This guide will help you to: The following products are not compatible with Database Access as they don't support IAM authentication: * Aurora Serverless. - * RDS MariaDB in version lower than 10.6. + * RDS MariaDB in versions lower than 10.6. ## Prerequisites From 8a397826dac7fb371f1f4d21c67d286fe41bf7da Mon Sep 17 00:00:00 2001 From: Jakub Nyckowski Date: Mon, 7 Mar 2022 23:00:30 -0500 Subject: [PATCH 7/8] Fix linter issue. --- docs/pages/database-access/guides/rds.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/pages/database-access/guides/rds.mdx b/docs/pages/database-access/guides/rds.mdx index 58eee96c656b5..b126947522c8a 100644 --- a/docs/pages/database-access/guides/rds.mdx +++ b/docs/pages/database-access/guides/rds.mdx @@ -12,8 +12,8 @@ This guide will help you to: The following products are not compatible with Database Access as they don't support IAM authentication: - * Aurora Serverless. - * RDS MariaDB in versions lower than 10.6. + - Aurora Serverless. + - RDS MariaDB in versions lower than 10.6. ## Prerequisites From 9f40a3dff35d1324f142d4a519e5ce09a3ee2bd3 Mon Sep 17 00:00:00 2001 From: Jakub Nyckowski Date: Wed, 9 Mar 2022 11:09:33 -0500 Subject: [PATCH 8/8] Update docs/pages/database-access/guides/rds.mdx Co-authored-by: Roman Tkachenko --- docs/pages/database-access/guides/rds.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/database-access/guides/rds.mdx b/docs/pages/database-access/guides/rds.mdx index b126947522c8a..88e3c1979eb57 100644 --- a/docs/pages/database-access/guides/rds.mdx +++ b/docs/pages/database-access/guides/rds.mdx @@ -13,7 +13,7 @@ This guide will help you to: The following products are not compatible with Database Access as they don't support IAM authentication: - Aurora Serverless. - - RDS MariaDB in versions lower than 10.6. + - RDS MariaDB versions lower than 10.6. ## Prerequisites