In “tsh login” show only alerts with on-login label.
In “tsh status” show only alerts with “high” severity. Which license warning should match.
In all “tctl” commands show only alerts with “high” severity.
Moves from github.com/golang/protobuf protoc-gen-go plugin to google.golang.org/
plugins.
This change was a long-time coming, but is now possible to do since our
dependencies are up-to-date.
* Move away from deprecated protoc-gen-go plugin
* Embed unimplemented server in handler.Handler
* Embed unimplemented server in multiplexer_test.go
* Update generated protos
* Add X-Forwarded-SSL and X-Forwarded-Port to appaccess.
Application Access now adds in X-Forwarded-Ssl and X-Forwarded-Port headers.
Tests have been added and adjusted to look for these new headers as well.
* Update lib/srv/app/header_rewriter.go
Co-authored-by: Ryan Clark <ryan.clark@goteleport.com>
* Update integration/appaccess/fixtures.go
Co-authored-by: Roman Tkachenko <roman@goteleport.com>
* Remove common.XForwardedPort
* Change order of websocket delegates.
* Make ReservedHeaders more future-proofed.
* access requests for teleterm
* removed unused imports and named returns
* remove comment
* using timestamppb instead of string for access requests
* updated proto with some more comments
* updated protos with comments
* using clusterClient, comments, and moving validation to daemon for access request delete
* separated GetAccessRequests into separate RPCs
* protobuf updates
* moved requestid check before resolving cluster
* fullstops in comments
* used standard access_request_id through rpc messages
* updated protofiles
* updated daemon service types to match grpc
* added kube advanced search support
* updated protos for kubes in access requests
* testing tag build
* fix detached head
* new tag build
* protobuf update
* lint fixes
* allow drone windows Connect build to include webapps.e
* protobuf files
* remove drone changes and updated comment
* proto changes with comment fixes and changed field order
* protobuf updates
Add definitions for Device Trust RPCs.
DeviceTrustService is fairly isolated from other services, so it is generated
using plain `protoc-gen-go` instead of Gogo.
teleport.e#514
* Add Device Trust proto definitions
* Allow proto generation without gogo
* Drop Gogo from lib/multiplexer protos
* Update generated protos
* Tidy modules
This PR presents a watcher for automatic `kube_cluster` discovery for Azure AKS clusters. Given a user with access to the Azure cloud, the auto-discovery service will scan the cloud and register all clusters available in AKS .
Once the discovery service creates a `kube_cluster` in Auth Server, the Kubernetes Service will start serving it. The credentials used to access the cluster depend on the different AKS clusters configurations:
# Authentication
## Local Accounts
If the AKS cluster auth is based on local accounts created during the provisioning phase of the cluster, the agent will use the [`aks:ListClusterUserCredentials`](https://learn.microsoft.com/en-us/rest/api/aks/managed-clusters/list-cluster-user-credentials?tabs=HTTP) endpoint.
This endpoint returns a `kubeconfig` fully populated with user credentials that Teleport can use to access the cluster.
## AZ Active Directory
When AZ active directory integration is enabled, Azure allows login with AD users. Azure forces the login to happen with dynamic short-lived user tokens. These tokens are generated by calling `credentials.GetToken` with a fixed Scope: `6dae42f8-4368-4678-94ff-3960e28e3630` and with the cluster's `tenant_id`. The token contains the user details as well as `group_ids` to match with authorization rules.
```go
// getAzureToken generates an authentication token for clusters with AD enabled.
func (a *aKSClient) getAzureToken(ctx context.Context, tentantID string, clientCfg *rest.Config) (time.Time, error) {
const (
azureManagedClusterScope = "6dae42f8-4368-4678-94ff-3960e28e3630"
)
cred, err := a.azIdentity(&azidentity.DefaultAzureCredentialOptions{
TenantID: tentantID,
})
if err != nil {
return time.Time{}, trace.Wrap(ConvertResponseError(err))
}
cliAccessToken, err := cred.GetToken(ctx, policy.TokenRequestOptions{
// azureManagedClusterScope is a fixed scope that identifies azure AKS managed clusters.
Scopes: []string{azureManagedClusterScope},
},
)
if err != nil {
return time.Time{}, trace.Wrap(ConvertResponseError(err))
}
// reset the old exec provider credentials
clientCfg.ExecProvider = nil
clientCfg.BearerToken = cliAccessToken.Token
return cliAccessToken.ExpiresOn, nil
}
```
# Authorization
## Local Accounts
The [`aks:ListClusterUserCredentials`](https://learn.microsoft.com/en-us/rest/api/aks/managed-clusters/list-cluster-user-credentials?tabs=HTTP) endpoint returns credentials with enough permissions for Teleport to enroll the cluster.
## AZ AD
### Azure RBAC
When Azure RBAC mode is enabled, the cluster authorization is based on rules specified in the Azure Identity permissions.
The AZ group associated with the AZ identity the Teleport Process is running has to define the following permissions:
```json
{
"Name": "AKS Teleport Discovery Permissions",
"Description": "Required permissions for Teleport auto-discovery.",
"Actions": [],
"NotActions": [],
"DataActions": [
"Microsoft.ContainerService/managedClusters/pods/read",
"Microsoft.ContainerService/managedClusters/users/impersonate/action",
"Microsoft.ContainerService/managedClusters/groups/impersonate/action",
"Microsoft.ContainerService/managedClusters/serviceaccounts/impersonate/action",
"Microsoft.ContainerService/managedClusters/authorization.k8s.io/selfsubjectaccessreviews/write",
"Microsoft.ContainerService/managedClusters/authorization.k8s.io/selfsubjectrulesreviews/write",
],
"NotDataActions": [],
"assignableScopes": [
"/subscriptions/{subscription_id}"
]
}
```
If correctly specified, the Azure authentication service automatically grants access to any cluster within `subscription_id`
without any other definition. On the other hand, if it's incorrectly configured, an error is triggered but Teleport cannot gain access to the cluster.
### Kubernetes RBAC
If AZ RBAC integration is disabled, the authorization to the cluster is processed by Kubernetes RBAC. This is done by matching the Az Identity principals (`group_ids`) with `Role`, `ClusterRole` objects that live in the AKS cluster. This mode requires that the `ClusterRole` and `ClusterRoleBinding` must exist and must be well configured for each cluster to enroll.
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: teleport-role
rules:
- apiGroups:
- ""
resources:
- users
- groups
- serviceaccounts
verbs:
- impersonate
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- "authorization.k8s.io"
resources:
- selfsubjectaccessreviews
- selfsubjectrulesreviews
verbs:
- create
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: teleport-role-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: teleport-role
subjects:
- kind: Group
name: {group_name}
apiGroup: rbac.authorization.k8s.io
```
#### `ClusterRole` and `ClusterRoleBinding` configured
If cluster operators or previous Teleport run has configured access to the cluster, no further action is required since Teleport already has access to the cluster.
#### Cluster `aks:ListClusterAdminCredentials` returns valid credentials
If the Teleport process has access to [`aks:ListClusterAdminCredentials`](https://learn.microsoft.com/en-us/rest/api/aks/managed-clusters/list-cluster-admin-credentials?tabs=HTTP) and the endpoint returns valid cluster admin credentials, Teleport will automatically create the `ClusterRole` and `ClusterRoleBinding` objects in the cluster configured to the `group_id` that is listed in the access token. In order to extract the `group_id` from the token, Teleport parses the JWT claims and extracts the first element.
If the object creation was successful, Teleport can access it, otherwise, it will use the `aks:BeginRunCommand` method to try to configure access to itself.
#### Cluster `aks:BeginRunCommand` returns valid credentials
When we reach this mode, Teleport tries to run a `kubectl` command against the cluster to configure the `ClusterRole` and `ClusterRoleBinding`. `aks:BeginRunCommand` allows any user with access to that endpoint to run arbitrary commands in the cluster (commands cannot be validated). Teleport will use it as the last resource to configure the access to itself.
If the command failed, Teleport cannot grant access to the cluster and an error is returned.
# UX
Currently, to discover AKS resources created and to have them dynamically served by the `kubernetes_service`one can define the following configuration.
```yaml
discovery_service:
enabled: true
azure:
- subscriptions: ["*"]
types: ["aks"]
regions: ["*"]
tags:
'*': '*'
kubernetes_service:
enabled: true
resources:
labels:
'*': '*'
```
# Future work
- Support AWS dynamic authentication
Part of #16135, #13376
Related to #12048, #16276, #16281
V10 Leaf clusters when connecting to a V11 Root cluster failed to initialize because they do not have `kube_server` resources defined.
This PR bumps the OLD remote proxy to versions <11 and removes the expected `kube_server` watcher.
It also removes `types.KindInstaller`, `types.KindDatabase`, and `types.KindApp` watchers from Remote Proxies since they do not affect remote reverse tunnels tracked from leaf clusters.
Fix incompatibility with pre/post v10.2.1 versions as the `types.KindInstaller` feature did not exist in older versions.
Fixes#17211Fixes#17219
This PR implements the Kubernetes Tester for the ConnectionDiagnostic feature.
The goal is to validate if the Kubernetes cluster is available and if the user can access it.
A series of checks are performed against Teleport using a Kubernetes Client populated with the user's certificates for accessing the desired cluster.
Currently, the checks are:
- Kubernetes Cluster is up and running
- User's role specifies at least one `kubernetes_groups` or `kubernetes_users`
- User's roles allow RBAC access to the cluster: `kubernetes_labels` match.
- Values specified under `kubernetes_groups` or `kubernetes_users` exist in the cluster and allow the user to list pods in the desired namespace.
Testing:
Post: `/v1/webapi/sites/<teleport-cluster>/diagnostics/connections`
```json
{
"resource_kind": "kube_cluster",
"resource_name": "<cluster_name>",
"kubernetes_namespace": "default"
}
```
Closes#16824
This test is flaky because we use precomputed keypairs to speed up
the tests, and it's possible that the test selects the same keypair
for both the root and leaf clusters.
Fix this by requesting new keypairs until we get one we haven't
seen before.
Closes#17198
* Add local proxy middleware for db cert checking
* Use tls conversion util instead of inline
* Add middleware to local proxy config
* Add middleware configuration in tsh
* Use route to database check and set defaults func
* Dont trigger normal db login flow if using local proxy tunnel
* Split out adding client creds into helper func for testing
* Add integration test for local proxy tunnel db cert middleware
* Add unit test for local proxy middleware
* Update comment
* Make middleware on new conn block
* godoc
* Make any cert check error trigger cert renewal in local proxy middleware
* Move dbcertchecker into lib/client
* Remove unneeded mutex in local proxy and unused func in lib/utils
* Make local proxy middleware integration test more robust
* Print message before mfa prompt in proxy tunnel
* Add before prompt option to test
* Remove unneeded comment
* Change local proxy messages to be more clear
* Pass local proxy opts by reference
* Pass certs in opts instead of cert/key file path
This is so we can check if the error is recoverable while preparing
local proxy options. A tunneled local proxy can ignore the error because
it does not rely on cert files - it can just renew its certs if
necessary.
* Move db route checking back to tsh
* Fix lint err
* Fix typo and print the hint to same writer as the mfa prompt
Attempt to upgrade the connection between browser/proxy to websockets
first. This way, we have a mechanism to send errors to the browser for
anything else that might go wrong.
A misbehaving server could send a single byte to the clipboard
using format CF_UNICODETEXT, which would cause an underflow.
Fixesgravitational/teleport-private#177
* Revert "Azure AD authentication for the Postgres backend (#15757)"
This reverts commit 33c6d82dc3.
* Revert "SQL Backend (#11048)"
This reverts commit 06fef2abf1.
* Remove Postgres backend from the docs
* Remove the Postgres backend from the testplan
ListResources was adding the namespace to the backend key when
retrieving WindowsDesktopServices, however UpsertWindowsDesktopService
doesn't include the namespace in the prefix. This results in never
getting any items from the backend.
Removing the namespace in the prefix to match GetWindowsDesktopService
revealed that we were also trying to unmarshal the resource as a
types.Server. Switching the unmarshal function to use
`services.UnmarshalWindowsDesktopService` as GetWindowsDesktopService
allows ListResources to provide the correct resources.
A new test case for WindowsDesktops was added to `local.TestListResources` to
prevent any regressions.
Address TODOs, add deprecation warnings and remove as many U2F code references
as possible.
Existing behavior is kept unaltered: it's still possible to inform Teleport of
old U2F AppIDs and U2F configurations are still silently converted to WebAuthn.
There's no reason to break that, so we don't.
Most server-side references to SecondFactorU2F are removed, but client-side
references remain: this makes it possible to interop newer clients with old
clusters (something else may break, but hopefully not this part).
Closes#10375.
* Introduce Github Actions join support
* Go mod tidy
* run goimports on source files
* Address PR comments
* More PR review comments
* Changes to tests based on PR feedback
* Improve error message in github rule validation
* Add support for SHA
* Add short message describing which fields shouldb be included
From the etcd docs:
> To obtain lower latencies and higher throughput for read requests
> clients can configure a request’s consistency mode to serializable,
> which may access stale data with respect to quorum, but removes the
> performance penalty of linearized accesses' reliance on live consensus.
By leveraging serializable mode it is entirely possible to retrieve
stale data. This means that a Create followed by a Get could result
in a NotFound error, which results in issues like #13276. While this
improves latency it breaks the consistency guarantees required by
Teleport.
To ensure that our consistency requirements are met all etcd operations
are converted to use the default linearized mode by removing the
`WithSerializable` option.
Closes#13276.
This includes 3 optimizations to improve performance of desktop sessions:
1. Reuse the same image object when encoding PNGs. This prevents us from making
a 16KB allocation for every single bitmap that comes through.
2. Introduce a new PNG frame message that has a length as part of the header.
The original message had no length, which required a costly decode operation
just to find the message boundary. This fixes a performance regression in the
proxy for v10.2.x.
3. Eliminate the use of binary.Write when encoding the most common message types.
While convenient, binary.Write uses reflection to detect the type of the input, which slows encoding down.
Co-authored-by: Isaiah Becker-Mayer <isaiah@goteleport.com>
* Predicate expressions using the "name" identifier will now use
field "hostname" when `ls` querying for nodes, as expected by
the user
* Change predicate expression for access request that use
name identifier to using the actual json field names