diff --git a/integration/ec2_test.go b/integration/ec2_test.go index df505e5b67223..ee86076932835 100644 --- a/integration/ec2_test.go +++ b/integration/ec2_test.go @@ -26,6 +26,7 @@ import ( "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/sts" "github.com/gravitational/trace" @@ -141,6 +142,9 @@ func getIID(ctx context.Context, t *testing.T) imds.InstanceIdentityDocument { func getCallerIdentity(t *testing.T) *sts.GetCallerIdentityOutput { sess, err := session.NewSessionWithOptions(session.Options{ SharedConfigState: session.SharedConfigEnable, + Config: aws.Config{ + EC2MetadataEnableFallback: aws.Bool(false), + }, }) require.NoError(t, err) stsService := sts.New(sess) diff --git a/lib/auth/join_iam.go b/lib/auth/join_iam.go index 54367306c1512..88609ae1f5c4a 100644 --- a/lib/auth/join_iam.go +++ b/lib/auth/join_iam.go @@ -472,11 +472,11 @@ func newSTSClient(ctx context.Context, cfg *stsIdentityRequestConfig) (*sts.STS, if cfg.fipsEndpointOption == endpoints.FIPSEndpointStateEnabled && !slices.Contains(validSTSEndpoints, strings.TrimPrefix(stsClient.Endpoint, "https://")) { // The AWS SDK will generate invalid endpoints when attempting to - // resolve the FIPS endpoint for a region which does not have one. + // resolve the FIPS endpoint for a region that does not have one. // In this case, try to use the FIPS endpoint in us-east-1. This should - // work for all regions in the standard partition. In GovCloud we should + // work for all regions in the standard partition. In GovCloud, we should // not hit this because all regional endpoints support FIPS. In China or - // other partitions this will fail and FIPS mode will not be supported. + // other partitions, this will fail, and FIPS mode will not be supported. log.Infof("AWS SDK resolved FIPS STS endpoint %s, which does not appear to be valid. "+ "Attempting to use the FIPS STS endpoint for us-east-1.", stsClient.Endpoint) diff --git a/lib/backend/dynamo/dynamodbbk.go b/lib/backend/dynamo/dynamodbbk.go index 9c2e5cac71cf6..8e1e6147aafc9 100644 --- a/lib/backend/dynamo/dynamodbbk.go +++ b/lib/backend/dynamo/dynamodbbk.go @@ -236,32 +236,30 @@ func New(ctx context.Context, params backend.Params) (*Backend, error) { clock: clockwork.NewRealClock(), buf: buf, } + // determine if the FIPS endpoints should be used useFIPSEndpoint := endpoints.FIPSEndpointStateUnset if modules.GetModules().IsBoringBinary() { useFIPSEndpoint = endpoints.FIPSEndpointStateEnabled } - // create an AWS session using default SDK behavior, i.e. it will interpret - // the environment and ~/.aws directory just like an AWS CLI tool would: + + awsConfig := aws.Config{ + EC2MetadataEnableFallback: aws.Bool(false), + } + if cfg.Region != "" { + awsConfig.Region = aws.String(cfg.Region) + } + if cfg.AccessKey != "" || cfg.SecretKey != "" { + awsConfig.Credentials = credentials.NewStaticCredentials(cfg.AccessKey, cfg.SecretKey, "") + } + b.session, err = session.NewSessionWithOptions(session.Options{ SharedConfigState: session.SharedConfigEnable, - Config: aws.Config{ - EC2MetadataEnableFallback: aws.Bool(false), - UseFIPSEndpoint: useFIPSEndpoint, - }, + Config: awsConfig, }) if err != nil { return nil, trace.Wrap(err) } - // override the default environment (region + credentials) with the values - // from the YAML file: - if cfg.Region != "" { - b.session.Config.Region = aws.String(cfg.Region) - } - if cfg.AccessKey != "" || cfg.SecretKey != "" { - creds := credentials.NewStaticCredentials(cfg.AccessKey, cfg.SecretKey, "") - b.session.Config.Credentials = creds - } // Increase the size of the connection pool. This substantially improves the // performance of Teleport under load as it reduces the number of TLS @@ -276,7 +274,14 @@ func New(ctx context.Context, params backend.Params) (*Backend, error) { b.session.Config.HTTPClient = httpClient // create DynamoDB service: - svc, err := dynamometrics.NewAPIMetrics(dynamometrics.Backend, dynamodb.New(b.session)) + svc, err := dynamometrics.NewAPIMetrics(dynamometrics.Backend, dynamodb.New(b.session, &aws.Config{ + // Setting this on the individual service instead of the session, as DynamoDB Streams + // and Application Auto Scaling do not yet have FIPS endpoints in non-GovCloud. + // See also: https://aws.amazon.com/compliance/fips/#FIPS_Endpoints_by_Service + // TODO(reed): This can be simplified once https://github.com/aws/aws-sdk-go/pull/5078 + // is available (or whenever AWS adds the missing FIPS endpoints). + UseFIPSEndpoint: useFIPSEndpoint, + })) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/events/dynamoevents/dynamoevents.go b/lib/events/dynamoevents/dynamoevents.go index 4434a9c1475b5..01ef141653de2 100644 --- a/lib/events/dynamoevents/dynamoevents.go +++ b/lib/events/dynamoevents/dynamoevents.go @@ -261,34 +261,39 @@ func New(ctx context.Context, cfg Config) (*Log, error) { Entry: l, Config: cfg, } - // create an AWS session using default SDK behavior, i.e. it will interpret - // the environment and ~/.aws directory just like an AWS CLI tool would: - b.session, err = awssession.NewSessionWithOptions(awssession.Options{ - SharedConfigState: awssession.SharedConfigEnable, - }) - if err != nil { - return nil, trace.Wrap(err) + + awsConfig := aws.Config{ + EC2MetadataEnableFallback: aws.Bool(false), } - // override the default environment (region + credentials) with the values - // from the YAML file: + + // Override the default environment's region if value set in YAML file: if cfg.Region != "" { - b.session.Config.Region = aws.String(cfg.Region) + awsConfig.Region = aws.String(cfg.Region) } // Override the service endpoint using the "endpoint" query parameter from // "audit_events_uri". This is for non-AWS DynamoDB-compatible backends. if cfg.Endpoint != "" { - b.session.Config.Endpoint = aws.String(cfg.Endpoint) + awsConfig.Endpoint = aws.String(cfg.Endpoint) } - // Explicitly enable or disable FIPS endpoints for DynamoDB - b.session.Config.UseFIPSEndpoint = events.FIPSProtoStateToAWSState(cfg.UseFIPSEndpoint) - - // Explicitly disable IMDSv1 fallback - b.session.Config.EC2MetadataEnableFallback = aws.Bool(false) + b.session, err = awssession.NewSessionWithOptions(awssession.Options{ + SharedConfigState: awssession.SharedConfigEnable, + Config: awsConfig, + }) + if err != nil { + return nil, trace.Wrap(err) + } // create DynamoDB service: - svc, err := dynamometrics.NewAPIMetrics(dynamometrics.Events, dynamodb.New(b.session)) + svc, err := dynamometrics.NewAPIMetrics(dynamometrics.Events, dynamodb.New(b.session, &aws.Config{ + // Setting this on the individual service instead of the session, as DynamoDB Streams + // and Application Auto Scaling do not yet have FIPS endpoints in non-GovCloud. + // See also: https://aws.amazon.com/compliance/fips/#FIPS_Endpoints_by_Service + // TODO(reed): This can be simplified once https://github.com/aws/aws-sdk-go/pull/5078 + // is available (or whenever AWS adds the missing FIPS endpoints). + UseFIPSEndpoint: events.FIPSProtoStateToAWSState(cfg.UseFIPSEndpoint), + })) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/events/s3sessions/s3handler.go b/lib/events/s3sessions/s3handler.go index 58e98dafdc83d..adc2912a29cd1 100644 --- a/lib/events/s3sessions/s3handler.go +++ b/lib/events/s3sessions/s3handler.go @@ -154,33 +154,31 @@ func (s *Config) CheckAndSetDefaults() error { return trace.BadParameter("missing parameter Bucket") } if s.Session == nil { - // create an AWS session using default SDK behavior, i.e. it will interpret - // the environment and ~/.aws directory just like an AWS CLI tool would: - sess, err := awssession.NewSessionWithOptions(awssession.Options{ - SharedConfigState: awssession.SharedConfigEnable, - }) - if err != nil { - return trace.Wrap(err) + awsConfig := aws.Config{ + EC2MetadataEnableFallback: aws.Bool(false), + UseFIPSEndpoint: events.FIPSProtoStateToAWSState(s.UseFIPSEndpoint), } - // override the default environment (region + Host + credentials) with the values - // from the YAML file: if s.Region != "" { - sess.Config.Region = aws.String(s.Region) + awsConfig.Region = aws.String(s.Region) } if s.Endpoint != "" { - sess.Config.Endpoint = aws.String(s.Endpoint) - sess.Config.S3ForcePathStyle = aws.Bool(true) + awsConfig.Endpoint = aws.String(s.Endpoint) + awsConfig.S3ForcePathStyle = aws.Bool(true) } if s.Insecure { - sess.Config.DisableSSL = aws.Bool(s.Insecure) + awsConfig.DisableSSL = aws.Bool(s.Insecure) } if s.Credentials != nil { - sess.Config.Credentials = s.Credentials + awsConfig.Credentials = s.Credentials } - sess.Config.EC2MetadataEnableFallback = aws.Bool(false) - - sess.Config.UseFIPSEndpoint = events.FIPSProtoStateToAWSState(s.UseFIPSEndpoint) + sess, err := awssession.NewSessionWithOptions(awssession.Options{ + SharedConfigState: awssession.SharedConfigEnable, + Config: awsConfig, + }) + if err != nil { + return trace.Wrap(err) + } s.Session = sess } diff --git a/lib/integrations/awsoidc/clientsv1.go b/lib/integrations/awsoidc/clientsv1.go index 1dd4e8b31f685..54aaae1a9ae92 100644 --- a/lib/integrations/awsoidc/clientsv1.go +++ b/lib/integrations/awsoidc/clientsv1.go @@ -22,11 +22,13 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/credentials/stscreds" + "github.com/aws/aws-sdk-go/aws/endpoints" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/sts" "github.com/gravitational/trace" "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/modules" "github.com/gravitational/teleport/lib/utils/oidc" ) @@ -60,8 +62,17 @@ func NewSessionV1(ctx context.Context, client IntegrationTokenGenerator, region return nil, trace.BadParameter("invalid integration subkind, expected awsoidc, got %s", integration.GetSubKind()) } + useFIPSEndpoint := endpoints.FIPSEndpointStateUnset + if modules.GetModules().IsBoringBinary() { + useFIPSEndpoint = endpoints.FIPSEndpointStateEnabled + } + sess, err := session.NewSessionWithOptions(session.Options{ SharedConfigState: session.SharedConfigDisable, + Config: aws.Config{ + EC2MetadataEnableFallback: aws.Bool(false), + UseFIPSEndpoint: useFIPSEndpoint, + }, }) if err != nil { return nil, trace.Wrap(err) @@ -88,13 +99,14 @@ func NewSessionV1(ctx context.Context, client IntegrationTokenGenerator, region ) awsCredentials := credentials.NewCredentials(roleProvider) - awsConfig := aws.NewConfig(). - WithRegion(region). - WithCredentials(awsCredentials) - session, err := session.NewSessionWithOptions(session.Options{ - Config: *awsConfig, SharedConfigState: session.SharedConfigDisable, + Config: aws.Config{ + Region: aws.String(region), + Credentials: awsCredentials, + EC2MetadataEnableFallback: aws.Bool(false), + UseFIPSEndpoint: useFIPSEndpoint, + }, }) if err != nil { return nil, trace.Wrap(err)