Skip to content

Commit

Permalink
Merge branch 'branch/v16' into bot/backport-49975-branch/v16
Browse files Browse the repository at this point in the history
  • Loading branch information
zmb3 authored Dec 17, 2024
2 parents 959f5b4 + f1628e7 commit e09e40b
Show file tree
Hide file tree
Showing 34 changed files with 685 additions and 309 deletions.
454 changes: 238 additions & 216 deletions api/gen/proto/go/teleport/integration/v1/awsoidc_service.pb.go

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions api/proto/teleport/integration/v1/awsoidc_service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,8 @@ message EnrollEKSClustersRequest {
// AgentVersion is version of agent Helm chart to install on the EKS cluster.
// Required.
string agent_version = 5;
// ExtraLabels added to the enrolled clusters.
map<string, string> extra_labels = 6;
}

// EnrollEKSClusterResult contains result for a single cluster enrollment.
Expand Down
20 changes: 12 additions & 8 deletions api/types/usertasks/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@ func WithExpiration(t time.Time) func(ut *usertasksv1.UserTask) {
// NewDiscoverEC2UserTask creates a new DiscoverEC2 User Task Type.
func NewDiscoverEC2UserTask(spec *usertasksv1.UserTaskSpec, opts ...UserTaskOption) (*usertasksv1.UserTask, error) {
taskName := TaskNameForDiscoverEC2(TaskNameForDiscoverEC2Parts{
Integration: spec.GetIntegration(),
IssueType: spec.GetIssueType(),
AccountID: spec.GetDiscoverEc2().GetAccountId(),
Region: spec.GetDiscoverEc2().GetRegion(),
Integration: spec.GetIntegration(),
IssueType: spec.GetIssueType(),
AccountID: spec.GetDiscoverEc2().GetAccountId(),
Region: spec.GetDiscoverEc2().GetRegion(),
SSMDocument: spec.GetDiscoverEc2().GetSsmDocument(),
InstallerScript: spec.GetDiscoverEc2().GetInstallerScript(),
})

ut := &usertasksv1.UserTask{
Expand Down Expand Up @@ -172,10 +174,12 @@ func validateDiscoverEC2TaskType(ut *usertasksv1.UserTask) error {
}

expectedTaskName := TaskNameForDiscoverEC2(TaskNameForDiscoverEC2Parts{
Integration: ut.Spec.Integration,
IssueType: ut.Spec.IssueType,
AccountID: ut.Spec.DiscoverEc2.AccountId,
Region: ut.Spec.DiscoverEc2.Region,
Integration: ut.Spec.Integration,
IssueType: ut.Spec.IssueType,
AccountID: ut.Spec.DiscoverEc2.AccountId,
Region: ut.Spec.DiscoverEc2.Region,
SSMDocument: ut.Spec.DiscoverEc2.SsmDocument,
InstallerScript: ut.Spec.DiscoverEc2.InstallerScript,
})
if ut.Metadata.GetName() != expectedTaskName {
return trace.BadParameter("task name is pre-defined for discover-ec2 types, expected %q, got %q",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ Terraform provider. The daemon stores its identity on the disk and refresh the t

- A Linux host that you wish to run the Teleport Terraform provider onto.

- A Linux user on that host that you wish Terraform and `tbot` to run as. In the guide,
we will use <Var name="teleport" /> for this.
- A Linux user on that host that you wish Terraform and `tbot` to run as.

## Step 1/4. Install `tbot` on your server

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ interactively and select the Teleport certificate that you exported when prompte
- Disables Network Level Authentication (NLA) for remote desktop services.
- Enables RemoteFX compression, if using Teleport version 15 or newer.

Note: in order for the Windows Local Security Authority (LSA) to load the Teleport DLL,
[LSA protection](https://learn.microsoft.com/en-us/windows-server/security/credentials-protection-and-management/configuring-additional-lsa-protection)
must be disabled.

{/*lint ignore ordered-list-marker-value*/}
5. Restart the computer.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,26 @@ available to be used when configuring rules for `tbot`'s Workload API service:

| Field | Description |
|-------------------|------------------------------------------------------------------------------|
| `unix.attested` | Indicates that the workload has been attested by the Unix Workload Attestor. |
| `unix.attested` | Indicates that the workload has been attested by the Unix Workload Attestor. |
| `unix.pid` | The process ID of the attested workload. |
| `unix.uid` | The effective user ID of the attested workload. |
| `unix.gid` | The effective primary group ID of the attested workload. |

### Support for non-standard procfs mounting

To resolve information about a process from the PID, the Unix Workload Attestor
reads information from the procfs filesystem. By default, it expects procfs to
be mounted at `/proc`.

If procfs is mounted at a different location, you must configure the Unix
Workload Attestor to read from that alternative location by setting the
`HOST_PROC` environment variable.

This is a sensitive configuration option, and you should ensure that it is
set correctly or not set at all. If misconfigured, an attacker could provide
falsified information about processes, and this could lead to the issuance of
SVIDs to unauthorized workloads.

## Kubernetes

The Kubernetes Workload Attestor allows you to restrict the issuance of SVIDs
Expand Down
2 changes: 1 addition & 1 deletion e
Submodule e updated from 1ac4aa to 4dc78b
28 changes: 28 additions & 0 deletions lib/auth/autoupdate/autoupdatev1/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
apievents "github.com/gravitational/teleport/api/types/events"
"github.com/gravitational/teleport/lib/authz"
"github.com/gravitational/teleport/lib/events"
"github.com/gravitational/teleport/lib/modules"
"github.com/gravitational/teleport/lib/services"
)

Expand Down Expand Up @@ -289,6 +290,10 @@ func (s *Service) CreateAutoUpdateVersion(ctx context.Context, req *autoupdate.C
return nil, trace.Wrap(err)
}

if err := checkAdminCloudAccess(authCtx); err != nil {
return nil, trace.Wrap(err)
}

if err := authCtx.CheckAccessToKind(types.KindAutoUpdateVersion, types.VerbCreate); err != nil {
return nil, trace.Wrap(err)
}
Expand Down Expand Up @@ -330,6 +335,10 @@ func (s *Service) UpdateAutoUpdateVersion(ctx context.Context, req *autoupdate.U
return nil, trace.Wrap(err)
}

if err := checkAdminCloudAccess(authCtx); err != nil {
return nil, trace.Wrap(err)
}

if err := authCtx.CheckAccessToKind(types.KindAutoUpdateVersion, types.VerbUpdate); err != nil {
return nil, trace.Wrap(err)
}
Expand Down Expand Up @@ -371,6 +380,10 @@ func (s *Service) UpsertAutoUpdateVersion(ctx context.Context, req *autoupdate.U
return nil, trace.Wrap(err)
}

if err := checkAdminCloudAccess(authCtx); err != nil {
return nil, trace.Wrap(err)
}

if err := authCtx.CheckAccessToKind(types.KindAutoUpdateVersion, types.VerbCreate, types.VerbUpdate); err != nil {
return nil, trace.Wrap(err)
}
Expand Down Expand Up @@ -412,6 +425,10 @@ func (s *Service) DeleteAutoUpdateVersion(ctx context.Context, req *autoupdate.D
return nil, trace.Wrap(err)
}

if err := checkAdminCloudAccess(authCtx); err != nil {
return nil, trace.Wrap(err)
}

if err := authCtx.CheckAccessToKind(types.KindAutoUpdateVersion, types.VerbDelete); err != nil {
return nil, trace.Wrap(err)
}
Expand Down Expand Up @@ -453,3 +470,14 @@ func (s *Service) emitEvent(ctx context.Context, e apievents.AuditEvent) {
)
}
}

// checkAdminCloudAccess validates if the given context has the builtin admin role if cloud feature is enabled.
func checkAdminCloudAccess(authCtx *authz.Context) error {
if modules.GetModules().Features().Cloud && !authz.HasBuiltinRole(*authCtx, string(types.RoleAdmin)) {
return trace.AccessDenied("This Teleport instance is running on Teleport Cloud. "+
"The %q resource is managed by the Teleport Cloud team. You can use the %q resource to opt-in, "+
"opt-out or configure update schedules.",
types.KindAutoUpdateVersion, types.KindAutoUpdateConfig)
}
return nil
}
1 change: 1 addition & 0 deletions lib/auth/integration/integrationv1/awsoidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ func (s *AWSOIDCService) EnrollEKSClusters(ctx context.Context, req *integration
AgentVersion: req.AgentVersion,
TeleportClusterName: clusterName.GetClusterName(),
IntegrationName: req.Integration,
ExtraLabels: req.ExtraLabels,
})
if err != nil {
return nil, trace.Wrap(err)
Expand Down
59 changes: 49 additions & 10 deletions lib/cloud/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,9 @@ type awsOptions struct {

// maxRetries is the maximum number of retries to use for the session.
maxRetries *int

// withoutSessionCache disables the session cache for the AWS session.
withoutSessionCache bool
}

func (a *awsOptions) checkAndSetDefaults() error {
Expand Down Expand Up @@ -429,6 +432,13 @@ func WithAssumeRole(roleARN, externalID string) AWSOptionsFn {
}
}

// WithoutSessionCache disables the session cache for the AWS session.
func WithoutSessionCache() AWSOptionsFn {
return func(options *awsOptions) {
options.withoutSessionCache = true
}
}

// WithAssumeRoleFromAWSMeta extracts options needed from AWS metadata for
// assuming an AWS role.
func WithAssumeRoleFromAWSMeta(meta types.AWS) AWSOptionsFn {
Expand Down Expand Up @@ -495,7 +505,7 @@ func (c *cloudClients) GetAWSSession(ctx context.Context, region string, opts ..
}
var err error
if options.baseSession == nil {
options.baseSession, err = c.getAWSSessionForRegion(region, options)
options.baseSession, err = c.getAWSSessionForRegion(ctx, region, options)
if err != nil {
return nil, trace.Wrap(err)
}
Expand Down Expand Up @@ -793,17 +803,12 @@ func awsAmbientSessionProvider(ctx context.Context, region string) (*awssession.
}

// getAWSSessionForRegion returns AWS session for the specified region.
func (c *cloudClients) getAWSSessionForRegion(region string, opts awsOptions) (*awssession.Session, error) {
func (c *cloudClients) getAWSSessionForRegion(ctx context.Context, region string, opts awsOptions) (*awssession.Session, error) {
if err := opts.checkAndSetDefaults(); err != nil {
return nil, trace.Wrap(err)
}

cacheKey := awsSessionCacheKey{
region: region,
integration: opts.integration,
}

sess, err := utils.FnCacheGet(context.Background(), c.awsSessionsCache, cacheKey, func(ctx context.Context) (*awssession.Session, error) {
createSession := func(ctx context.Context) (*awssession.Session, error) {
if opts.credentialsSource == credentialsSourceIntegration {
if c.awsIntegrationSessionProviderFn == nil {
return nil, trace.BadParameter("missing aws integration session provider")
Expand All @@ -817,6 +822,30 @@ func (c *cloudClients) getAWSSessionForRegion(region string, opts awsOptions) (*
logrus.Debugf("Initializing AWS session for region %v using environment credentials.", region)
session, err := awsAmbientSessionProvider(ctx, region)
return session, trace.Wrap(err)
}

if opts.withoutSessionCache {
sess, err := createSession(ctx)
if err != nil {
return nil, trace.Wrap(err)
}
if opts.customRetryer != nil || opts.maxRetries != nil {
return sess.Copy(&aws.Config{
Retryer: opts.customRetryer,
MaxRetries: opts.maxRetries,
}), nil
}
return sess, trace.Wrap(err)
}

cacheKey := awsSessionCacheKey{
region: region,
integration: opts.integration,
}

sess, err := utils.FnCacheGet(ctx, c.awsSessionsCache, cacheKey, func(ctx context.Context) (*awssession.Session, error) {
session, err := createSession(ctx)
return session, trace.Wrap(err)
})
if err != nil {
return nil, trace.Wrap(err)
Expand All @@ -836,15 +865,25 @@ func (c *cloudClients) getAWSSessionForRole(ctx context.Context, region string,
return nil, trace.Wrap(err)
}

createSession := func(ctx context.Context) (*awssession.Session, error) {
stsClient := sts.New(options.baseSession)
return newSessionWithRole(ctx, stsClient, region, options.assumeRoleARN, options.assumeRoleExternalID)
}

if options.withoutSessionCache {
session, err := createSession(ctx)
return session, trace.Wrap(err)
}

cacheKey := awsSessionCacheKey{
region: region,
integration: options.integration,
roleARN: options.assumeRoleARN,
externalID: options.assumeRoleExternalID,
}
return utils.FnCacheGet(ctx, c.awsSessionsCache, cacheKey, func(ctx context.Context) (*awssession.Session, error) {
stsClient := sts.New(options.baseSession)
return newSessionWithRole(ctx, stsClient, region, options.assumeRoleARN, options.assumeRoleExternalID)
session, err := createSession(ctx)
return session, trace.Wrap(err)
})
}

Expand Down
17 changes: 14 additions & 3 deletions lib/integrations/awsoidc/eks_enroll_clusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"encoding/base64"
"fmt"
"log/slog"
"maps"
"net/http"
"net/url"
"slices"
Expand Down Expand Up @@ -245,6 +246,9 @@ type EnrollEKSClustersRequest struct {

// AgentVersion specifies version of the Helm chart that will be installed during enrollment.
AgentVersion string

// ExtraLabels added to the enrolled clusters.
ExtraLabels map[string]string
}

// CheckAndSetDefaults checks if the required fields are present.
Expand Down Expand Up @@ -674,13 +678,20 @@ func installKubeAgent(ctx context.Context, cfg installKubeAgentParams) error {
common.ApplyEKSNameSuffix(kubeCluster)
vals["kubeClusterName"] = kubeCluster.GetName()

labels := kubeCluster.GetStaticLabels()
labels[types.InternalResourceIDLabel] = cfg.resourceID
vals["labels"] = labels
vals["labels"] = kubeAgentLabels(kubeCluster, cfg.resourceID, cfg.req.ExtraLabels)

if _, err := installCmd.RunWithContext(ctx, agentChart, vals); err != nil {
return trace.Wrap(err, "could not install Helm chart.")
}

return nil
}

func kubeAgentLabels(kubeCluster types.KubeCluster, resourceID string, extraLabels map[string]string) map[string]string {
labels := make(map[string]string)
maps.Copy(labels, extraLabels)
maps.Copy(labels, kubeCluster.GetStaticLabels())
labels[types.InternalResourceIDLabel] = resourceID

return labels
}
27 changes: 27 additions & 0 deletions lib/integrations/awsoidc/eks_enroll_clusters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
eksTypes "github.com/aws/aws-sdk-go-v2/service/eks/types"
"github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/aws/smithy-go/middleware"
"github.com/google/uuid"
"github.com/gravitational/trace"
"github.com/jonboulle/clockwork"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -631,3 +632,29 @@ func (m *mockEnrollEKSClusterClient) CreateToken(ctx context.Context, token type
}

var _ EnrollEKSCLusterClient = &mockEnrollEKSClusterClient{}

func TestKubeAgentLabels(t *testing.T) {
kubeClusterLabels := map[string]string{
"priority": "yes",
"region": "us-east-1",
}
resourceID := uuid.NewString()
extraLabels := map[string]string{
"priority": "no",
"custom": "yes",
}

got := kubeAgentLabels(
&types.KubernetesClusterV3{Metadata: types.Metadata{Labels: kubeClusterLabels}},
resourceID,
extraLabels,
)

expectedLabels := map[string]string{
"priority": "yes",
"region": "us-east-1",
"custom": "yes",
"teleport.internal/resource-id": resourceID,
}
require.Equal(t, expectedLabels, got)
}
Loading

0 comments on commit e09e40b

Please sign in to comment.