From e69d5ba4ceee2a13b4d4daa6be06476f0ce15d85 Mon Sep 17 00:00:00 2001 From: Andrew Burke <31974658+atburke@users.noreply.github.com> Date: Tue, 31 May 2022 16:19:16 -0700 Subject: [PATCH] Automatically import EC2 tags (#12593) This change allows Teleport to automatically import EC2 tags when running in an EC2 instance. --- api/types/appserver.go | 10 + api/types/constants.go | 3 + api/types/databaseserver.go | 10 + api/types/desktop.go | 20 ++ api/types/resource.go | 4 + api/types/server.go | 14 ++ docs/img/aws/allow-tags.png | Bin 0 -> 28669 bytes docs/img/aws/instance-settings.png | Bin 0 -> 103190 bytes .../aws/launch-instance-advanced-options.png | Bin 0 -> 38332 bytes docs/pages/setup/guides/ec2-tags.mdx | 160 ++++++---------- integration/ec2_test.go | 180 ++++++++++++++++++ integration/helpers.go | 20 +- integration/utmp_integration_test.go | 2 +- lib/cloud/aws/errors.go | 10 + lib/cloud/aws/imds.go | 30 +++ lib/kube/proxy/forwarder.go | 19 +- lib/labels/ec2/ec2.go | 154 +++++++++++++++ lib/labels/ec2/ec2_test.go | 107 +++++++++++ lib/labels/labels.go | 13 ++ lib/labels/labels_test.go | 42 ++-- lib/service/db.go | 1 + lib/service/kubernetes.go | 1 + lib/service/service.go | 87 +++++++-- lib/services/server.go | 2 +- lib/services/watcher.go | 2 - lib/srv/app/server.go | 8 +- lib/srv/db/server.go | 6 + lib/srv/regular/sshserver.go | 27 ++- lib/srv/regular/sshserver_test.go | 2 +- .../apiserver/handler/handler_servers.go | 2 +- lib/utils/ec2.go | 60 ++++++ lib/web/ui/server.go | 2 +- 32 files changed, 840 insertions(+), 158 deletions(-) create mode 100644 docs/img/aws/allow-tags.png create mode 100644 docs/img/aws/instance-settings.png create mode 100644 docs/img/aws/launch-instance-advanced-options.png create mode 100644 lib/cloud/aws/imds.go create mode 100644 lib/labels/ec2/ec2.go create mode 100644 lib/labels/ec2/ec2_test.go diff --git a/api/types/appserver.go b/api/types/appserver.go index aa5a96b43d2d4..0921dc12470f7 100644 --- a/api/types/appserver.go +++ b/api/types/appserver.go @@ -285,6 +285,16 @@ func (s *AppServerV3) GetAllLabels() map[string]string { return CombineLabels(staticLabels, dynamicLabels) } +// GetStaticLabels returns the app server static labels. +func (s *AppServerV3) GetStaticLabels() map[string]string { + return s.Metadata.Labels +} + +// SetStaticLabels sets the app server static labels. +func (s *AppServerV3) SetStaticLabels(sl map[string]string) { + s.Metadata.Labels = sl +} + // Copy returns a copy of this app server object. func (s *AppServerV3) Copy() AppServer { return proto.Clone(s).(*AppServerV3) diff --git a/api/types/constants.go b/api/types/constants.go index 9520655db540c..ab54ab1d2b35f 100644 --- a/api/types/constants.go +++ b/api/types/constants.go @@ -326,6 +326,9 @@ const ( OriginCloud = "cloud" ) +// EC2HostnameTag is the name of the EC2 tag used to override a node's hostname. +const EC2HostnameTag = "TeleportHostname" + // OriginValues lists all possible origin values. var OriginValues = []string{OriginDefaults, OriginConfigFile, OriginDynamic, OriginCloud} diff --git a/api/types/databaseserver.go b/api/types/databaseserver.go index db2637513a3cc..2313b9ce4bc56 100644 --- a/api/types/databaseserver.go +++ b/api/types/databaseserver.go @@ -272,6 +272,16 @@ func (s *DatabaseServerV3) GetAllLabels() map[string]string { return CombineLabels(staticLabels, s.Spec.DynamicLabels) } +// GetStaticLabels returns the database server static labels. +func (s *DatabaseServerV3) GetStaticLabels() map[string]string { + return s.Metadata.Labels +} + +// SetStaticLabels sets the database server static labels. +func (s *DatabaseServerV3) SetStaticLabels(sl map[string]string) { + s.Metadata.Labels = sl +} + // Copy returns a copy of this database server object. func (s *DatabaseServerV3) Copy() DatabaseServer { return proto.Clone(s).(*DatabaseServerV3) diff --git a/api/types/desktop.go b/api/types/desktop.go index 6fdda0b05fa75..8bc7d23cf15f2 100644 --- a/api/types/desktop.go +++ b/api/types/desktop.go @@ -99,6 +99,16 @@ func (s *WindowsDesktopServiceV3) GetAllLabels() map[string]string { return s.Metadata.Labels } +// GetStaticLabels returns the windows desktop static labels. +func (s *WindowsDesktopServiceV3) GetStaticLabels() map[string]string { + return s.Metadata.Labels +} + +// SetStaticLabels sets the windows desktop static labels. +func (s *WindowsDesktopServiceV3) SetStaticLabels(sl map[string]string) { + s.Metadata.Labels = sl +} + // GetHostname returns the windows hostname of this service. func (s *WindowsDesktopServiceV3) GetHostname() string { return s.Spec.Hostname @@ -177,6 +187,16 @@ func (d *WindowsDesktopV3) GetAllLabels() map[string]string { return CombineLabels(d.Metadata.Labels, nil) } +// GetStaticLabels returns the windows desktop static labels. +func (d *WindowsDesktopV3) GetStaticLabels() map[string]string { + return d.Metadata.Labels +} + +// SetStaticLabels sets the windows desktop static labels. +func (d *WindowsDesktopV3) SetStaticLabels(sl map[string]string) { + d.Metadata.Labels = sl +} + // LabelsString returns all desktop labels as a string. func (d *WindowsDesktopV3) LabelsString() string { return LabelsAsString(d.Metadata.Labels, nil) diff --git a/api/types/resource.go b/api/types/resource.go index 86740fb17ab4b..7f9be4eb9511a 100644 --- a/api/types/resource.go +++ b/api/types/resource.go @@ -82,6 +82,10 @@ type ResourceWithLabels interface { ResourceWithOrigin // GetAllLabels returns all resource's labels. GetAllLabels() map[string]string + // GetStaticLabels returns the resource's static labels. + GetStaticLabels() map[string]string + // SetStaticLabels sets the resource's static labels. + SetStaticLabels(sl map[string]string) // MatchSearch goes through select field values of a resource // and tries to match against the list of search values. MatchSearch(searchValues []string) bool diff --git a/api/types/server.go b/api/types/server.go index e6cd77e5dfa54..866ea49e73bb7 100644 --- a/api/types/server.go +++ b/api/types/server.go @@ -221,11 +221,25 @@ func (s *ServerV2) GetHostname() string { return s.Spec.Hostname } +// GetLabels and GetStaticLabels are the same, and that is intentional. GetLabels +// exists to preserve backwards compatibility, while GetStaticLabels exists to +// implement ResourcesWithLabels. + // GetLabels returns server's static label key pairs func (s *ServerV2) GetLabels() map[string]string { return s.Metadata.Labels } +// GetStaticLabels returns the server static labels. +func (s *ServerV2) GetStaticLabels() map[string]string { + return s.Metadata.Labels +} + +// SetStaticLabels sets the server static labels. +func (s *ServerV2) SetStaticLabels(sl map[string]string) { + s.Metadata.Labels = sl +} + // GetCmdLabels returns command labels func (s *ServerV2) GetCmdLabels() map[string]CommandLabel { if s.Spec.CmdLabels == nil { diff --git a/docs/img/aws/allow-tags.png b/docs/img/aws/allow-tags.png new file mode 100644 index 0000000000000000000000000000000000000000..43cbbca289c1463aff1d6b7752f6cee04a2e8004 GIT binary patch literal 28669 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�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 literal 0 HcmV?d00001 diff --git a/docs/pages/setup/guides/ec2-tags.mdx b/docs/pages/setup/guides/ec2-tags.mdx index c5085065d5ef7..7508ddfe31779 100644 --- a/docs/pages/setup/guides/ec2-tags.mdx +++ b/docs/pages/setup/guides/ec2-tags.mdx @@ -4,131 +4,81 @@ description: How to set up Teleport Node labels based on EC2 tags h1: Sync EC2 Tags and Teleport Node Labels --- -This guide will explain how to set up Teleport Node labels based on Amazon EC2 tags. +When running on an AWS EC2 instance, Teleport will automatically detect and import EC2 tags as +Teleport labels for SSH nodes, Applications, Databases, and Kubernetes clusters. Labels created +this way will have the `aws/` prefix. + +If the tag `TeleportHostname` (case-sensitive) is present, its value will override the node's hostname. + +```bash +$ tsh ls +Node Name Address Labels +-------------------- -------------- ----------------------------------------------------------------------------------------------------------------------- +fakehost.example.com 127.0.0.1:3022 env=example,hostname=ip-172-31-53-70,aws/Name=atburke-dev,aws/TagKey=TagValue,aws/TeleportHostname=fakehost.example.com +``` + + + For services that manage multiple resources (such as the database service), each resource will receive the + same labels from EC2. + ## Prerequisites (!docs/pages/includes/edition-prereqs-tabs.mdx!) - - One Teleport Node running on an Amazon EC2 instance. See [Adding Nodes](../admin/adding-nodes.mdx) for how to set up a Teleport Node. -- The following software installed on your Teleport Node: `curl`, `python`, and - the `aws` CLI, which comes from the `awscli` Python package. -## Step 1/3. Deploy the script +## Enable tags in instance metadata -You’ll need a script on your EC2 instance that can query the AWS API and get the -values of your instance's tags for you. The Teleport Node will then use these -values to execute RBAC rules. +To allow Teleport to import EC2 tags, tags must be enabled in the instance metadata. This can be done +via the AWS console or the AWS CLI. See the [AWS documentation](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html#allow-access-to-tags-in-IMDS) +for more details. -Here’s one script you can use: + + Only instances that are running on the [Nitro system](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html#ec2-nitro-instances) + will update their tags while running. All other instance types [must be restarted](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html#work-with-tags-in-IMDS) + to update tags. + -```code -#!/bin/bash -if [[ "$1" == "" ]]; then - echo "Usage: $(basename $0) " - exit 1 -fi -TAG_NAME=$1 - -IMDS_TOKEN=$(curl -sS -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 300") -IMDS_TOKEN_HEADER="-H \"X-aws-ec2-metadata-token: ${IMDS_TOKEN}\"" -INSTANCE_ID=$(curl -sS "${IMDS_TOKEN_HEADER}" http://169.254.169.254/latest/meta-data/instance-id) -REGION=$(curl -sS "${IMDS_TOKEN_HEADER}" http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e "s:\([0-9][0-9]*\)[a-z]*\$:\\1:") -TAG_VALUE="$(aws ec2 describe-tags --filters "Name=resource-id,Values=$INSTANCE_ID" "Name=key,Values=$TAG_NAME" --region $REGION --output=text | cut -f5)" - -if [[ "${TAG_VALUE}" == "" ]]; then - echo "" -else - echo $TAG_VALUE -fi -``` +### AWS EC2 Console -Save this script to `/usr/local/bin/get-tag.sh` on your EC2 instance. -Run the command below to make it executable: +To launch a new instance with instance metadata tags enabled: +1. Open `Advanced Options` at the bottom of the page. +2. Ensure that `Metadata accessible` is not disabled. +3. Enable `Allow tags in metadata`. -```code -$ chmod +x /usr/local/bin/get-tag.sh -``` +

+ ![Advanced Options](../../../img/aws/launch-instance-advanced-options.png) +
-## Step 2/3. Set up an IAM role +To modify an existing instance to enable instance metadata tags: +1. From the instance summary, go to `Actions > Instance Settings > Allow tags in instance metadata`. +2. Enable `Allow`. -Grant your EC2 instance an IAM role that will allow it to query tag values for EC2 instances. +
+ ![Instance Settings](../../../img/aws/instance-settings.png) +
-Here’s an example policy which you can add to an IAM role: +
+ ![Allow Tags](../../../img/aws/allow-tags.png) +
+### AWS CLI -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "ec2:DescribeTags", - "Resource": "*" - } - ] -} -``` - -Once this is done, query the value of the test tag on your EC2 instance by running the following command: +To modify the instance at launch: ```code -$ /usr/local/bin/get-tag.sh test -tagValue +$ aws ec2 run-instances \ + --image-id \ + --instance-type \ + --metadata-options "InstanceMetadataTags=enabled" + ... ``` -## Step 3/3. Modify the Teleport Node config file +To modify a running instance: -Modify the Teleport config file on your node (`/etc/teleport.yaml`) as follows: - -```yaml -teleport: - ssh_service: - enabled: yes - listen_addr: 0.0.0.0:3022 - commands: - - name: aws_tag_test - command: ['/usr/local/bin/get-tag.sh', 'test'] - period: 1h -``` - -This config will add a label with the key `aws_tag_test` to your instance. Its value will be set to whatever the `test` tag is set to and it will be updated once every hour. - -Restart Teleport on the node and you should see the new label appear: - -```txt -Node Name Address Labels ------------------------------ ----------------------------------------------------------------------- ------------------------------------------------------------------------------------------- -example 172.31.26.55:3022 aws_tag_test=tagValue -``` - -Now you have a label on the instance which you can use inside a Teleport role. Here’s an example role: - -```yaml -kind: role -version: v5 -metadata: - name: test-tag-role -spec: - allow: - logins: - - ec2-user - node_labels: - 'aws_tag_test': 'tagValue' - deny: {} - options: - cert_format: standard - forward_agent: true - max_session_ttl: 2h0m0s - port_forwarding: true +```code +$ aws ec2 modify-instance-metadata-options \ + --instance-id i-123456789example \ + --instance-metadata-tags enabled ``` - -When assigned to Teleport users, this role will only allow them to log in to -Teleport Nodes which have the `aws_tag_test` label with the value of `tagValue`, -effectively gating access to infrastructure based on the value of the EC2 `test` -tag. - -By adding multiple commands to a Teleport Node, setting the values of different -tags, then adding Teleport roles that reference these tags, you can build -fine-grained RBAC systems based on your EC2 tagging structure. diff --git a/integration/ec2_test.go b/integration/ec2_test.go index 2a56ac22a208c..1810f75867202 100644 --- a/integration/ec2_test.go +++ b/integration/ec2_test.go @@ -18,6 +18,7 @@ package integration import ( "context" + "fmt" "io" "net" "os" @@ -30,9 +31,11 @@ import ( "github.com/gravitational/teleport/lib/backend" "github.com/gravitational/teleport/lib/backend/lite" "github.com/gravitational/teleport/lib/defaults" + "github.com/gravitational/teleport/lib/labels/ec2" "github.com/gravitational/teleport/lib/service" "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/utils" + "github.com/gravitational/trace" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" @@ -282,3 +285,180 @@ func TestIAMNodeJoin(t *testing.T) { return len(nodes) > 0 }, time.Minute, time.Second, "waiting for node to join cluster") } + +type mockIMDSClient struct { + tags map[string]string +} + +func (m *mockIMDSClient) IsAvailable(ctx context.Context) bool { + return true +} + +func (m *mockIMDSClient) GetTagKeys(ctx context.Context) ([]string, error) { + keys := make([]string, 0, len(m.tags)) + for k := range m.tags { + keys = append(keys, k) + } + return keys, nil +} + +func (m *mockIMDSClient) GetTagValue(ctx context.Context, key string) (string, error) { + if value, ok := m.tags[key]; ok { + return value, nil + } + return "", trace.NotFound("Tag %q not found", key) +} + +// TestEC2Labels is an integration test which asserts that Teleport correctly picks up +// EC2 tags when running on an EC2 instance. +func TestEC2Labels(t *testing.T) { + storageConfig := backend.Config{ + Type: lite.GetName(), + Params: backend.Params{ + "path": t.TempDir(), + "poll_stream_period": 50 * time.Millisecond, + }, + } + tconf := service.MakeDefaultConfig() + tconf.Log = newSilentLogger() + tconf.DataDir = t.TempDir() + tconf.Auth.Enabled = true + tconf.Proxy.Enabled = true + tconf.Proxy.DisableWebInterface = true + tconf.Auth.StorageConfig = storageConfig + tconf.Auth.SSHAddr.Addr = net.JoinHostPort(Host, ports.Pop()) + tconf.AuthServers = append(tconf.AuthServers, tconf.Auth.SSHAddr) + + tconf.SSH.Enabled = true + tconf.SSH.Addr.Addr = net.JoinHostPort(Host, ports.Pop()) + + appConf := service.App{ + Name: "test-app", + URI: "app.example.com", + } + + tconf.Apps.Enabled = true + tconf.Apps.Apps = []service.App{appConf} + + dbConfig := service.Database{ + Name: "test-db", + Protocol: "postgres", + URI: "postgres://somewhere.example.com", + } + tconf.Databases.Enabled = true + tconf.Databases.Databases = []service.Database{dbConfig} + + enableKubernetesService(t, tconf) + + imClient := &mockIMDSClient{ + tags: map[string]string{ + "Name": "my-instance", + }, + } + + proc, err := service.NewTeleport(tconf, service.WithIMDSClient(imClient)) + require.NoError(t, err) + require.NoError(t, proc.Start()) + t.Cleanup(func() { require.NoError(t, proc.Close()) }) + + ctx := context.Background() + authServer := proc.GetAuthServer() + + var nodes []types.Server + var apps []types.AppServer + var databases []types.DatabaseServer + var kubes []types.Server + + // Wait for everything to come online. + require.Eventually(t, func() bool { + var err error + nodes, err = authServer.GetNodes(ctx, tconf.SSH.Namespace) + require.NoError(t, err) + apps, err = authServer.GetApplicationServers(ctx, tconf.SSH.Namespace) + require.NoError(t, err) + databases, err = authServer.GetDatabaseServers(ctx, tconf.SSH.Namespace) + require.NoError(t, err) + kubes, err = authServer.GetKubeServices(ctx) + require.NoError(t, err) + return len(nodes) == 1 && len(apps) == 1 && len(databases) == 1 && len(kubes) == 1 + }, 10*time.Second, time.Second) + + tagName := fmt.Sprintf("%s/Name", ec2.AWSNamespace) + + // Check that EC2 labels were applied. + require.Eventually(t, func() bool { + node, err := authServer.GetNode(ctx, tconf.SSH.Namespace, nodes[0].GetName()) + require.NoError(t, err) + _, nodeHasLabel := node.GetAllLabels()[tagName] + apps, err := authServer.GetApplicationServers(ctx, tconf.SSH.Namespace) + require.NoError(t, err) + require.Len(t, apps, 1) + app := apps[0].GetApp() + _, appHasLabel := app.GetAllLabels()[tagName] + + databases, err := authServer.GetDatabaseServers(ctx, tconf.SSH.Namespace) + require.NoError(t, err) + require.Len(t, databases, 1) + database := databases[0].GetDatabase() + _, dbHasLabel := database.GetAllLabels()[tagName] + + kubeClusters := getKubeClusters(t, authServer) + require.Len(t, kubeClusters, 1) + kube := kubeClusters[0] + _, kubeHasLabel := kube.StaticLabels[tagName] + return nodeHasLabel && appHasLabel && dbHasLabel && kubeHasLabel + }, 10*time.Second, time.Second) +} + +// TestEC2Hostname is an integration test which asserts that Teleport sets its +// hostname if the EC2 tag `TeleportHostname` is available. This test must be +// run on an instance with tag `TeleportHostname=fakehost.example.com`. +func TestEC2Hostname(t *testing.T) { + teleportHostname := "fakehost.example.com" + + storageConfig := backend.Config{ + Type: lite.GetName(), + Params: backend.Params{ + "path": t.TempDir(), + "poll_stream_period": 50 * time.Millisecond, + }, + } + tconf := service.MakeDefaultConfig() + tconf.Log = newSilentLogger() + tconf.DataDir = t.TempDir() + tconf.Auth.Enabled = true + tconf.Proxy.Enabled = true + tconf.Proxy.DisableWebInterface = true + tconf.Auth.StorageConfig = storageConfig + tconf.Auth.SSHAddr.Addr = net.JoinHostPort(Host, ports.Pop()) + tconf.AuthServers = append(tconf.AuthServers, tconf.Auth.SSHAddr) + + tconf.SSH.Enabled = true + tconf.SSH.Addr.Addr = net.JoinHostPort(Host, ports.Pop()) + + imClient := &mockIMDSClient{ + tags: map[string]string{ + types.EC2HostnameTag: teleportHostname, + }, + } + + proc, err := service.NewTeleport(tconf, service.WithIMDSClient(imClient)) + require.NoError(t, err) + require.NoError(t, proc.Start()) + t.Cleanup(func() { require.NoError(t, proc.Close()) }) + + ctx := context.Background() + authServer := proc.GetAuthServer() + var node types.Server + require.Eventually(t, func() bool { + nodes, err := authServer.GetNodes(ctx, tconf.SSH.Namespace) + require.NoError(t, err) + if len(nodes) == 1 { + node = nodes[0] + return true + } + return false + }, 10*time.Second, time.Second) + + require.Equal(t, teleportHostname, node.GetHostname()) +} diff --git a/integration/helpers.go b/integration/helpers.go index cb0ef4590d7b8..2f9dcb91f74a6 100644 --- a/integration/helpers.go +++ b/integration/helpers.go @@ -42,6 +42,7 @@ import ( "github.com/stretchr/testify/require" + apiclient "github.com/gravitational/teleport/api/client" "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/constants" apidefaults "github.com/gravitational/teleport/api/defaults" @@ -1773,7 +1774,7 @@ func enableKubernetesService(t *testing.T, config *service.Config) { err = kubeconfig.Update(kubeConfigPath, kubeconfig.Values{ TeleportClusterName: "teleport-cluster", - ClusterAddr: net.JoinHostPort(Host, ports.Pop()), + ClusterAddr: "https://" + net.JoinHostPort(Host, ports.Pop()), Credentials: key, }) require.NoError(t, err) @@ -1783,6 +1784,23 @@ func enableKubernetesService(t *testing.T, config *service.Config) { config.Kube.ListenAddr = utils.MustParseAddr(net.JoinHostPort(Host, ports.Pop())) } +// getKubeClusters gets all kubernetes clusters accessible from a given auth server. +func getKubeClusters(t *testing.T, as *auth.Server) []*types.KubernetesCluster { + ctx := context.Background() + resources, err := apiclient.GetResourcesWithFilters(ctx, as, proto.ListResourcesRequest{ + ResourceType: types.KindKubeService, + }) + require.NoError(t, err) + kss, err := types.ResourcesWithLabels(resources).AsServers() + require.NoError(t, err) + + clusters := make([]*types.KubernetesCluster, 0) + for _, ks := range kss { + clusters = append(clusters, ks.GetKubernetesClusters()...) + } + return clusters +} + func genUserKey() (*client.Key, error) { caKey, caCert, err := tlsca.GenerateSelfSignedCA(pkix.Name{ CommonName: "localhost", diff --git a/integration/utmp_integration_test.go b/integration/utmp_integration_test.go index 33c123e190adb..47007899959d3 100644 --- a/integration/utmp_integration_test.go +++ b/integration/utmp_integration_test.go @@ -276,7 +276,7 @@ func newSrvCtx(ctx context.Context, t *testing.T) *SrvCtx { Period: types.NewDuration(time.Millisecond), Command: []string{"expr", "1", "+", "3"}, }, - }, + }, nil, ), regular.SetBPF(&bpf.NOP{}), regular.SetRestrictedSessionManager(&restricted.NOP{}), diff --git a/lib/cloud/aws/errors.go b/lib/cloud/aws/errors.go index 25bb84877eae6..6a26d3d478eec 100644 --- a/lib/cloud/aws/errors.go +++ b/lib/cloud/aws/errors.go @@ -17,6 +17,7 @@ limitations under the License. package aws import ( + "errors" "net/http" "github.com/aws/aws-sdk-go/aws/awserr" @@ -43,3 +44,12 @@ func ConvertRequestFailureError(err error) error { return err // Return unmodified. } + +// ParseMetadataClientError converts a failed instance metadata service call to a trace error. +func ParseMetadataClientError(err error) error { + var httpError interface{ HTTPStatusCode() int } + if errors.As(err, &httpError) { + return trace.ReadError(httpError.HTTPStatusCode(), nil) + } + return trace.Wrap(err) +} diff --git a/lib/cloud/aws/imds.go b/lib/cloud/aws/imds.go new file mode 100644 index 0000000000000..442003aec8ce9 --- /dev/null +++ b/lib/cloud/aws/imds.go @@ -0,0 +1,30 @@ +/* +Copyright 2022 Gravitational, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package aws + +import "context" + +// InstanceMetadata is an interface for fetching information from EC2 instance +// metadata. +type InstanceMetadata interface { + // IsAvailable checks if instance metadata is available. + IsAvailable(ctx context.Context) bool + // GetTagKeys gets all of the EC2 tag keys. + GetTagKeys(ctx context.Context) ([]string, error) + // GetTagValue gets the value for a specified tag key. + GetTagValue(ctx context.Context, key string) (string, error) +} diff --git a/lib/kube/proxy/forwarder.go b/lib/kube/proxy/forwarder.go index 101db320f4e77..dc465737093b6 100644 --- a/lib/kube/proxy/forwarder.go +++ b/lib/kube/proxy/forwarder.go @@ -136,6 +136,9 @@ type ForwarderConfig struct { // DynamicLabels is map of dynamic labels associated with this cluster. // Used for RBAC. DynamicLabels *labels.Dynamic + // CloudLabels is a map of labels imported from a cloud provider associated with this + // cluster. Used for RBAC. + CloudLabels labels.Importer // LockWatcher is a lock watcher. LockWatcher *services.LockWatcher // CheckImpersonationPermissions is an optional override of the default @@ -1830,6 +1833,20 @@ func (f *Forwarder) requestCertificate(ctx authContext) (*tls.Config, error) { return tlsConfig, nil } +// getStaticLabels gets the labels that the forwarder should present as static, +// which includes EC2 labels if available. +func (f *Forwarder) getStaticLabels() map[string]string { + if f.cfg.CloudLabels == nil { + return f.cfg.StaticLabels + } + labels := f.cfg.CloudLabels.Get() + // Let static labels override ec2 labels. + for k, v := range f.cfg.StaticLabels { + labels[k] = v + } + return labels +} + func (f *Forwarder) kubeClusters() []*types.KubernetesCluster { var dynLabels map[string]types.CommandLabelV2 if f.cfg.DynamicLabels != nil { @@ -1840,7 +1857,7 @@ func (f *Forwarder) kubeClusters() []*types.KubernetesCluster { for n := range f.creds { res = append(res, &types.KubernetesCluster{ Name: n, - StaticLabels: f.cfg.StaticLabels, + StaticLabels: f.getStaticLabels(), DynamicLabels: dynLabels, }) } diff --git a/lib/labels/ec2/ec2.go b/lib/labels/ec2/ec2.go new file mode 100644 index 0000000000000..f0ecf9df0c51e --- /dev/null +++ b/lib/labels/ec2/ec2.go @@ -0,0 +1,154 @@ +/* +Copyright 2022 Gravitational, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package ec2 + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/cloud/aws" + "github.com/gravitational/teleport/lib/utils" + "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" + "github.com/sirupsen/logrus" +) + +const ( + // AWSNamespace is used as the namespace prefix for any labels + // imported from AWS. + AWSNamespace = "aws" + // ec2LabelUpdatePeriod is the period for updating EC2 labels. + ec2LabelUpdatePeriod = time.Hour +) + +// Config is the configuration for the EC2 label service. +type Config struct { + Client aws.InstanceMetadata + Clock clockwork.Clock + Log logrus.FieldLogger +} + +func (conf *Config) checkAndSetDefaults(ctx context.Context) error { + if conf.Client == nil { + client, err := utils.NewInstanceMetadataClient(ctx) + if err != nil { + return trace.Wrap(err) + } + conf.Client = client + } + if conf.Clock == nil { + conf.Clock = clockwork.NewRealClock() + } + if conf.Log == nil { + conf.Log = logrus.WithField(trace.Component, "ec2labels") + } + return nil +} + +// EC2 is a service that periodically imports tags from EC2 via instance +// metadata. +type EC2 struct { + c *Config + mu sync.RWMutex + labels map[string]string + + closeCh chan struct{} +} + +func New(ctx context.Context, c *Config) (*EC2, error) { + if err := c.checkAndSetDefaults(ctx); err != nil { + return nil, trace.Wrap(err) + } + return &EC2{ + c: c, + labels: make(map[string]string), + closeCh: make(chan struct{}), + }, nil +} + +// Get returns the list of updated EC2 labels. +func (l *EC2) Get() map[string]string { + l.mu.RLock() + defer l.mu.RUnlock() + return l.labels +} + +// Apply adds EC2 labels to the provided resource. +func (l *EC2) Apply(r types.ResourceWithLabels) { + labels := l.Get() + for k, v := range r.GetStaticLabels() { + labels[k] = v + } + r.SetStaticLabels(labels) +} + +// Sync will block and synchronously update EC2 labels. +func (l *EC2) Sync(ctx context.Context) error { + m := make(map[string]string) + + tags, err := l.c.Client.GetTagKeys(ctx) + if err != nil { + return trace.Wrap(err) + } + + for _, t := range tags { + value, err := l.c.Client.GetTagValue(ctx, t) + if err != nil { + return trace.Wrap(err) + } + m[t] = value + } + + l.mu.Lock() + defer l.mu.Unlock() + l.labels = toAWSLabels(m) + + return nil +} + +// Start will start a loop that continually keeps EC2 labels updated. +func (l *EC2) Start(ctx context.Context) { + go l.periodicUpdateLabels(ctx) +} + +func (l *EC2) periodicUpdateLabels(ctx context.Context) { + ticker := l.c.Clock.NewTicker(ec2LabelUpdatePeriod) + defer ticker.Stop() + + for { + if err := l.Sync(ctx); err != nil { + l.c.Log.Errorf("Error fetching EC2 tags: %v", err) + } + select { + case <-ticker.Chan(): + case <-ctx.Done(): + return + } + } +} + +// toAWSLabels formats labels coming from EC2. +func toAWSLabels(labels map[string]string) map[string]string { + m := make(map[string]string, len(labels)) + for k, v := range labels { + m[fmt.Sprintf("%s/%s", AWSNamespace, k)] = v + } + return m +} diff --git a/lib/labels/ec2/ec2_test.go b/lib/labels/ec2/ec2_test.go new file mode 100644 index 0000000000000..a86a302b11bd6 --- /dev/null +++ b/lib/labels/ec2/ec2_test.go @@ -0,0 +1,107 @@ +/* +Copyright 2022 Gravitational, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package ec2 + +import ( + "context" + "testing" + "time" + + "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" + "github.com/stretchr/testify/require" +) + +type mockIMDSClient struct { + tags map[string]string +} + +func (m *mockIMDSClient) IsAvailable(ctx context.Context) bool { + return true +} + +func (m *mockIMDSClient) GetTagKeys(ctx context.Context) ([]string, error) { + keys := make([]string, 0, len(m.tags)) + for k := range m.tags { + keys = append(keys, k) + } + return keys, nil +} + +func (m *mockIMDSClient) GetTagValue(ctx context.Context, key string) (string, error) { + if value, ok := m.tags[key]; ok { + return value, nil + } + return "", trace.NotFound("Tag %q not found", key) +} + +func TestEC2LabelsSync(t *testing.T) { + ctx := context.Background() + tags := map[string]string{"a": "1", "b": "2"} + imdsClient := &mockIMDSClient{ + tags: tags, + } + ec2Labels, err := New(ctx, &Config{ + Client: imdsClient, + }) + require.NoError(t, err) + require.NoError(t, ec2Labels.Sync(ctx)) + require.Equal(t, toAWSLabels(tags), ec2Labels.Get()) +} + +func TestEC2LabelsAsync(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + imdsClient := &mockIMDSClient{} + clock := clockwork.NewFakeClock() + ec2Labels, err := New(ctx, &Config{ + Client: imdsClient, + Clock: clock, + }) + require.NoError(t, err) + + compareLabels := func(m map[string]string) func() bool { + return func() bool { + labels := ec2Labels.Get() + if len(labels) != len(m) { + return false + } + for k, v := range labels { + if m[k] != v { + return false + } + } + return true + } + } + + // Check that initial tags are read. + initialTags := map[string]string{"a": "1", "b": "2"} + imdsClient.tags = initialTags + ec2Labels.Start(ctx) + require.Eventually(t, compareLabels(toAWSLabels(initialTags)), time.Second, 100*time.Microsecond) + + // Check that tags are updated over time. + updatedTags := map[string]string{"a": "3", "c": "4"} + imdsClient.tags = updatedTags + clock.Advance(ec2LabelUpdatePeriod) + require.Eventually(t, compareLabels(toAWSLabels(updatedTags)), time.Second, 100*time.Millisecond) + + // Check that service stops updating when closed. + cancel() + imdsClient.tags = map[string]string{"x": "8", "y": "9", "z": "10"} + clock.Advance(ec2LabelUpdatePeriod) + require.Eventually(t, compareLabels(toAWSLabels(updatedTags)), time.Second, 100*time.Millisecond) +} diff --git a/lib/labels/labels.go b/lib/labels/labels.go index 3fce155e1e6cb..e93f3ac0560e7 100644 --- a/lib/labels/labels.go +++ b/lib/labels/labels.go @@ -166,3 +166,16 @@ func (l *Dynamic) setLabel(name string, value types.CommandLabel) { l.c.Labels[name] = value } + +// Importer is an interface for labels imported from an external source, +// such as a cloud provider. +type Importer interface { + // Get returns the current labels. + Get() map[string]string + // Apply adds the current labels to the provided resource's static labels. + Apply(r types.ResourceWithLabels) + // Sync blocks and synchronously updates the labels. + Sync(context.Context) error + // Start starts a loop that continually keeps the labels updated. + Start(context.Context) +} diff --git a/lib/labels/labels_test.go b/lib/labels/labels_test.go index 509c76cdb4418..e3097dd14629d 100644 --- a/lib/labels/labels_test.go +++ b/lib/labels/labels_test.go @@ -19,15 +19,14 @@ package labels import ( "context" "os" - "strings" "testing" "time" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/utils" + "github.com/stretchr/testify/require" "github.com/google/uuid" - "gopkg.in/check.v1" ) func TestMain(m *testing.M) { @@ -35,14 +34,7 @@ func TestMain(m *testing.M) { os.Exit(m.Run()) } -type LabelSuite struct { -} - -var _ = check.Suite(&LabelSuite{}) - -func TestLabels(t *testing.T) { check.TestingT(t) } - -func (s *LabelSuite) TestSync(c *check.C) { +func TestSync(t *testing.T) { // Create dynamic labels and sync right away. l, err := NewDynamic(context.Background(), &DynamicConfig{ Labels: map[string]types.CommandLabel{ @@ -52,14 +44,14 @@ func (s *LabelSuite) TestSync(c *check.C) { }, }, }) - c.Assert(err, check.IsNil) + require.NoError(t, err) l.Sync() // Check that the result contains the output of the command. - c.Assert(l.Get()["foo"].GetResult(), check.Equals, "4") + require.Equal(t, "4", l.Get()["foo"].GetResult()) } -func (s *LabelSuite) TestStart(c *check.C) { +func TestStart(t *testing.T) { // Create dynamic labels and setup async update. l, err := NewDynamic(context.Background(), &DynamicConfig{ Labels: map[string]types.CommandLabel{ @@ -69,24 +61,18 @@ func (s *LabelSuite) TestStart(c *check.C) { }, }, }) - c.Assert(err, check.IsNil) + require.NoError(t, err) l.Start() - // Wait a maximum of 5 seconds for dynamic labels to be updated. - select { - case <-time.Tick(50 * time.Millisecond): + require.Eventually(t, func() bool { val, ok := l.Get()["foo"] - c.Assert(ok, check.Equals, true) - if val.GetResult() == "4" { - break - } - case <-time.After(5 * time.Second): - c.Fatalf("Timed out waiting for label to be updated.") - } + require.True(t, ok) + return val.GetResult() == "4" + }, 5*time.Second, 50*time.Millisecond) } // TestInvalidCommand makes sure that invalid commands return a error message. -func (s *LabelSuite) TestInvalidCommand(c *check.C) { +func TestInvalidCommand(t *testing.T) { // Create invalid labels and sync right away. l, err := NewDynamic(context.Background(), &DynamicConfig{ Labels: map[string]types.CommandLabel{ @@ -95,11 +81,11 @@ func (s *LabelSuite) TestInvalidCommand(c *check.C) { Command: []string{uuid.New().String()}}, }, }) - c.Assert(err, check.IsNil) + require.NoError(t, err) l.Sync() // Check that the output contains that the command was not found. val, ok := l.Get()["foo"] - c.Assert(ok, check.Equals, true) - c.Assert(strings.Contains(val.GetResult(), "output:"), check.Equals, true) + require.True(t, ok) + require.Contains(t, val.GetResult(), "output:") } diff --git a/lib/service/db.go b/lib/service/db.go index 9c869a8cec41a..70bf8d20d4c7b 100644 --- a/lib/service/db.go +++ b/lib/service/db.go @@ -201,6 +201,7 @@ func (process *TeleportProcess) initDatabaseService() (retErr error) { Hostname: process.Config.Hostname, HostID: process.Config.HostUUID, Databases: databases, + CloudLabels: process.cloudLabels, ResourceMatchers: process.Config.Databases.ResourceMatchers, AWSMatchers: process.Config.Databases.AWSMatchers, OnHeartbeat: process.onHeartbeat(teleport.ComponentDatabase), diff --git a/lib/service/kubernetes.go b/lib/service/kubernetes.go index 314b4325c6050..9cd2e69c7faf5 100644 --- a/lib/service/kubernetes.go +++ b/lib/service/kubernetes.go @@ -250,6 +250,7 @@ func (process *TeleportProcess) initKubernetesService(log *logrus.Entry, conn *C Component: teleport.ComponentKube, StaticLabels: cfg.Kube.StaticLabels, DynamicLabels: dynLabels, + CloudLabels: process.cloudLabels, LockWatcher: lockWatcher, CheckImpersonationPermissions: cfg.Kube.CheckImpersonationPermissions, PublicAddr: publicAddr, diff --git a/lib/service/service.go b/lib/service/service.go index 855c833a21831..41143a057c50c 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -67,6 +67,7 @@ import ( "github.com/gravitational/teleport/lib/backend/postgres" "github.com/gravitational/teleport/lib/bpf" "github.com/gravitational/teleport/lib/cache" + "github.com/gravitational/teleport/lib/cloud/aws" "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/events/dynamoevents" @@ -76,6 +77,8 @@ import ( "github.com/gravitational/teleport/lib/events/s3sessions" "github.com/gravitational/teleport/lib/joinserver" kubeproxy "github.com/gravitational/teleport/lib/kube/proxy" + "github.com/gravitational/teleport/lib/labels" + "github.com/gravitational/teleport/lib/labels/ec2" "github.com/gravitational/teleport/lib/limiter" "github.com/gravitational/teleport/lib/modules" "github.com/gravitational/teleport/lib/multiplexer" @@ -330,6 +333,10 @@ type TeleportProcess struct { // clusterFeatures contain flags for supported and unsupported features. clusterFeatures proto.Features + + // cloudLabels is a set of labels imported from a cloud provider and shared between + // services. + cloudLabels labels.Importer } type keyPairKey struct { @@ -337,6 +344,20 @@ type keyPairKey struct { reason string } +// newTeleportConfig provides extra options to NewTeleport(). +type newTeleportConfig struct { + imdsClient aws.InstanceMetadata +} + +type NewTeleportOption func(*newTeleportConfig) + +// WithIMDSClient provides NewTeleport with a custom EC2 instance metadata client. +func WithIMDSClient(client aws.InstanceMetadata) NewTeleportOption { + return func(c *newTeleportConfig) { + c.imdsClient = client + } +} + // processIndex is an internal process index // to help differentiate between two different teleport processes // during in-process reload. @@ -609,7 +630,11 @@ func waitAndReload(ctx context.Context, cfg Config, srv Process, newTeleport New // NewTeleport takes the daemon configuration, instantiates all required services // and starts them under a supervisor, returning the supervisor object. -func NewTeleport(cfg *Config) (*TeleportProcess, error) { +func NewTeleport(cfg *Config, opts ...NewTeleportOption) (*TeleportProcess, error) { + newTeleportConf := &newTeleportConfig{} + for _, opt := range opts { + opt(newTeleportConf) + } var err error // Before we do anything reset the SIGINT handler back to the default. @@ -709,16 +734,6 @@ func NewTeleport(cfg *Config) (*TeleportProcess, error) { cfg.AuthServers = []utils.NetAddr{cfg.Auth.SSHAddr} } - // if user did not provide auth domain name, use this host's name - if cfg.Auth.Enabled && cfg.Auth.ClusterName == nil { - cfg.Auth.ClusterName, err = services.NewClusterNameWithRandomID(types.ClusterNameSpecV2{ - ClusterName: cfg.Hostname, - }) - if err != nil { - return nil, trace.Wrap(err) - } - } - processID := fmt.Sprintf("%v", nextProcessID()) supervisor := NewSupervisor(processID, cfg.Log) storage, err := auth.NewProcessStorage(supervisor.ExitContext(), filepath.Join(cfg.DataDir, teleport.ComponentProcess)) @@ -734,6 +749,52 @@ func NewTeleport(cfg *Config) (*TeleportProcess, error) { cfg.PluginRegistry = plugin.NewRegistry() } + var cloudLabels labels.Importer + + // Check if we're on an EC2 instance, and if we should override the node's hostname. + imClient := newTeleportConf.imdsClient + if imClient == nil { + imClient, err = utils.NewInstanceMetadataClient(supervisor.ExitContext()) + if err != nil { + return nil, trace.Wrap(err) + } + } + + if imClient.IsAvailable(supervisor.ExitContext()) { + ec2Hostname, err := imClient.GetTagValue(supervisor.ExitContext(), types.EC2HostnameTag) + if err == nil { + if ec2Hostname != "" { + cfg.Log.Info("Found %q tag in EC2 instance. Using %q as hostname.", types.EC2HostnameTag, ec2Hostname) + cfg.Hostname = ec2Hostname + } + } else if !trace.IsNotFound(err) { + cfg.Log.Errorf("Unexpected error while looking for EC2 hostname: %v", err) + } + + ec2Labels, err := ec2.New(supervisor.ExitContext(), &ec2.Config{ + Client: imClient, + Clock: cfg.Clock, + }) + if err != nil { + return nil, trace.Wrap(err) + } + cloudLabels = ec2Labels + } + + if cloudLabels != nil { + cloudLabels.Start(supervisor.ExitContext()) + } + + // if user did not provide auth domain name, use this host's name + if cfg.Auth.Enabled && cfg.Auth.ClusterName == nil { + cfg.Auth.ClusterName, err = services.NewClusterNameWithRandomID(types.ClusterNameSpecV2{ + ClusterName: cfg.Hostname, + }) + if err != nil { + return nil, trace.Wrap(err) + } + } + process := &TeleportProcess{ PluginRegistry: cfg.PluginRegistry, Clock: cfg.Clock, @@ -746,6 +807,7 @@ func NewTeleport(cfg *Config) (*TeleportProcess, error) { id: processID, keyPairs: make(map[keyPairKey]KeyPair), appDependCh: make(chan Event, 1024), + cloudLabels: cloudLabels, } process.registerAppDepend() @@ -1949,7 +2011,7 @@ func (process *TeleportProcess) initSSH() error { regular.SetShell(cfg.SSH.Shell), regular.SetEmitter(&events.StreamerAndEmitter{Emitter: asyncEmitter, Streamer: streamer}), regular.SetSessionServer(conn.Client), - regular.SetLabels(cfg.SSH.Labels, cfg.SSH.CmdLabels), + regular.SetLabels(cfg.SSH.Labels, cfg.SSH.CmdLabels, process.cloudLabels), regular.SetNamespace(namespace), regular.SetPermitUserEnvironment(cfg.SSH.PermitUserEnvironment), regular.SetCiphers(cfg.Ciphers), @@ -3741,6 +3803,7 @@ func (process *TeleportProcess) initApps() { Hostname: process.Config.Hostname, GetRotation: process.getRotation, Apps: applications, + CloudLabels: process.cloudLabels, ResourceMatchers: process.Config.Apps.ResourceMatchers, OnHeartbeat: process.onHeartbeat(teleport.ComponentApp), }) diff --git a/lib/services/server.go b/lib/services/server.go index ca15aff44e016..e2d363bb38db8 100644 --- a/lib/services/server.go +++ b/lib/services/server.go @@ -91,7 +91,7 @@ func compareServers(a, b types.Server) int { if a.GetUseTunnel() != b.GetUseTunnel() { return Different } - if !utils.StringMapsEqual(a.GetLabels(), b.GetLabels()) { + if !utils.StringMapsEqual(a.GetStaticLabels(), b.GetStaticLabels()) { return Different } if !cmp.Equal(a.GetCmdLabels(), b.GetCmdLabels()) { diff --git a/lib/services/watcher.go b/lib/services/watcher.go index a8f048247ede4..5cfa40aa42c46 100644 --- a/lib/services/watcher.go +++ b/lib/services/watcher.go @@ -1198,8 +1198,6 @@ type Node interface { GetHostname() string // GetNamespace returns server namespace GetNamespace() string - // GetLabels returns server's static label key pairs - GetLabels() map[string]string // GetCmdLabels gets command labels GetCmdLabels() map[string]types.CommandLabel // GetPublicAddr is an optional field that returns the public address this cluster can be reached at. diff --git a/lib/srv/app/server.go b/lib/srv/app/server.go index 053824e934a67..c069c15e61946 100644 --- a/lib/srv/app/server.go +++ b/lib/srv/app/server.go @@ -87,6 +87,10 @@ type Config struct { // Apps is a list of statically registered apps this agent proxies. Apps types.Apps + // CloudLabels is a service that imports labels from a cloud provider. The labels are shared + // between all apps. + CloudLabels labels.Importer + // OnHeartbeat is called after every heartbeat. Used to update process state. OnHeartbeat func(error) @@ -400,6 +404,9 @@ func (s *Server) getServerInfo(app types.Application) (types.Resource, error) { if labels != nil { copy.SetDynamicLabels(labels.Get()) } + if s.c.CloudLabels != nil { + s.c.CloudLabels.Apply(copy) + } expires := s.c.Clock.Now().UTC().Add(apidefaults.ServerAnnounceTTL) return types.NewAppServerV3(types.Metadata{ Name: copy.GetName(), @@ -493,7 +500,6 @@ func (s *Server) Start(ctx context.Context) (err error) { if s.watcher, err = s.startResourceWatcher(ctx); err != nil { return trace.Wrap(err) } - return nil } diff --git a/lib/srv/db/server.go b/lib/srv/db/server.go index 62a212cec1702..cfe2015be2694 100644 --- a/lib/srv/db/server.go +++ b/lib/srv/db/server.go @@ -85,6 +85,9 @@ type Config struct { AWSMatchers []services.AWSMatcher // Databases is a list of proxied databases from static configuration. Databases types.Databases + // CloudLabels is a service that imports labels from a cloud provider. The labels are shared + // between all databases. + CloudLabels labels.Importer // OnHeartbeat is called after every heartbeat. Used to update process state. OnHeartbeat func(error) // OnReconcile is called after each database resource reconciliation. @@ -527,6 +530,9 @@ func (s *Server) getServerInfo(database types.Database) (types.Resource, error) if labels != nil { copy.SetDynamicLabels(labels.Get()) } + if s.cfg.CloudLabels != nil { + s.cfg.CloudLabels.Apply(copy) + } expires := s.cfg.Clock.Now().UTC().Add(apidefaults.ServerAnnounceTTL) return types.NewDatabaseServerV3(types.Metadata{ Name: copy.GetName(), diff --git a/lib/srv/regular/sshserver.go b/lib/srv/regular/sshserver.go index 6b3a5683d5e9d..f7cd21b59e5be 100644 --- a/lib/srv/regular/sshserver.go +++ b/lib/srv/regular/sshserver.go @@ -99,6 +99,9 @@ type Server struct { // dynamicLabels are the result of command execution. dynamicLabels *labels.Dynamic + // cloudLabels are the labels imported from a cloud provider. + cloudLabels labels.Importer + proxyMode bool proxyTun reversetunnel.Tunnel proxyAccessPoint auth.ReadProxyAccessPoint @@ -333,6 +336,10 @@ func (s *Server) Serve(l net.Listener) error { go s.dynamicLabels.Start() } + if s.cloudLabels != nil { + s.cloudLabels.Start(s.Context()) + } + go s.heartbeat.Run() return s.srv.Serve(l) } @@ -409,7 +416,7 @@ func SetProxyMode(tsrv reversetunnel.Tunnel, ap auth.ReadProxyAccessPoint) Serve // SetLabels sets dynamic and static labels that server will report to the // auth servers. -func SetLabels(staticLabels map[string]string, cmdLabels services.CommandLabels) ServerOption { +func SetLabels(staticLabels map[string]string, cmdLabels services.CommandLabels, cloudLabels labels.Importer) ServerOption { return func(s *Server) error { var err error @@ -433,7 +440,7 @@ func SetLabels(staticLabels map[string]string, cmdLabels services.CommandLabels) if err != nil { return trace.Wrap(err) } - + s.cloudLabels = cloudLabels return nil } } @@ -805,6 +812,20 @@ func (s *Server) getRole() types.SystemRole { return types.RoleNode } +// getStaticLabels gets the labels that the server should present as static, +// which includes EC2 labels if available. +func (s *Server) getStaticLabels() map[string]string { + if s.cloudLabels == nil { + return s.labels + } + labels := s.cloudLabels.Get() + // Let static labels override ec2 labels if they conflict. + for k, v := range s.labels { + labels[k] = v + } + return labels +} + // getDynamicLabels returns all dynamic labels. If no dynamic labels are // defined, return an empty set. func (s *Server) getDynamicLabels() map[string]types.CommandLabelV2 { @@ -828,7 +849,7 @@ func (s *Server) GetInfo() types.Server { Metadata: types.Metadata{ Name: s.ID(), Namespace: s.getNamespace(), - Labels: s.labels, + Labels: s.getStaticLabels(), }, Spec: types.ServerSpecV2{ CmdLabels: s.getDynamicLabels(), diff --git a/lib/srv/regular/sshserver_test.go b/lib/srv/regular/sshserver_test.go index 80a17b747070e..ebb45b3c8849d 100644 --- a/lib/srv/regular/sshserver_test.go +++ b/lib/srv/regular/sshserver_test.go @@ -172,7 +172,7 @@ func newCustomFixture(t *testing.T, mutateCfg func(*auth.TestServerConfig), sshO Period: types.NewDuration(time.Millisecond), Command: []string{"expr", "1", "+", "3"}, }, - }, + }, nil, ), SetBPF(&bpf.NOP{}), SetRestrictedSessionManager(&restricted.NOP{}), diff --git a/lib/teleterm/apiserver/handler/handler_servers.go b/lib/teleterm/apiserver/handler/handler_servers.go index 3a883c010dab6..aa8963addc5f9 100644 --- a/lib/teleterm/apiserver/handler/handler_servers.go +++ b/lib/teleterm/apiserver/handler/handler_servers.go @@ -41,7 +41,7 @@ func (s *Handler) ListServers(ctx context.Context, req *api.ListServersRequest) func newAPIServer(server clusters.Server) *api.Server { apiLabels := APILabels{} - serverLabels := server.GetLabels() + serverLabels := server.GetStaticLabels() for name, value := range serverLabels { apiLabels = append(apiLabels, &api.Label{ Name: name, diff --git a/lib/utils/ec2.go b/lib/utils/ec2.go index 666344b6e9041..5fb2af3633259 100644 --- a/lib/utils/ec2.go +++ b/lib/utils/ec2.go @@ -18,14 +18,20 @@ package utils import ( "context" + "fmt" "io" "regexp" + "strings" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" + "github.com/gravitational/teleport/lib/cloud/aws" "github.com/gravitational/trace" ) +// metadataReadLimit is the largest number of bytes that will be read from imds responses. +const metadataReadLimit = 1_000_000 + // GetEC2IdentityDocument fetches the PKCS7 RSA2048 InstanceIdentityDocument // from the IMDS for this EC2 instance. func GetEC2IdentityDocument() ([]byte, error) { @@ -84,3 +90,57 @@ func IsEC2NodeID(id string) bool { func NodeIDFromIID(iid *imds.InstanceIdentityDocument) string { return iid.AccountID + "-" + iid.InstanceID } + +// InstanceMetadataClient is a wrapper for an imds.Client. +type InstanceMetadataClient struct { + c *imds.Client +} + +// NewInstanceMetadataClient creates a new instance metadata client. +func NewInstanceMetadataClient(ctx context.Context) (*InstanceMetadataClient, error) { + cfg, err := config.LoadDefaultConfig(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + return &InstanceMetadataClient{ + c: imds.NewFromConfig(cfg), + }, nil +} + +// IsAvailable checks if instance metadata is available. +func (client *InstanceMetadataClient) IsAvailable(ctx context.Context) bool { + _, err := client.getMetadata(ctx, "") + return err == nil +} + +// getMetadata gets the raw metadata from a specified path. +func (client *InstanceMetadataClient) getMetadata(ctx context.Context, path string) (string, error) { + output, err := client.c.GetMetadata(ctx, &imds.GetMetadataInput{Path: path}) + if err != nil { + return "", trace.Wrap(aws.ParseMetadataClientError(err)) + } + defer output.Content.Close() + body, err := ReadAtMost(output.Content, metadataReadLimit) + if err != nil { + return "", trace.Wrap(err) + } + return string(body), nil +} + +// GetTagKeys gets all of the EC2 tag keys. +func (client *InstanceMetadataClient) GetTagKeys(ctx context.Context) ([]string, error) { + body, err := client.getMetadata(ctx, "tags/instance") + if err != nil { + return nil, trace.Wrap(err) + } + return strings.Split(body, "\n"), nil +} + +// GetTagValue gets the value for a specified tag key. +func (client *InstanceMetadataClient) GetTagValue(ctx context.Context, key string) (string, error) { + body, err := client.getMetadata(ctx, fmt.Sprintf("tags/instance/%s", key)) + if err != nil { + return "", trace.Wrap(err) + } + return body, nil +} diff --git a/lib/web/ui/server.go b/lib/web/ui/server.go index 93bba58fd9054..72abfebdbec20 100644 --- a/lib/web/ui/server.go +++ b/lib/web/ui/server.go @@ -70,7 +70,7 @@ func MakeServers(clusterName string, servers []types.Server) []Server { uiServers := []Server{} for _, server := range servers { uiLabels := []Label{} - serverLabels := server.GetLabels() + serverLabels := server.GetStaticLabels() for name, value := range serverLabels { uiLabels = append(uiLabels, Label{ Name: name,