* Fix TestDiagnoseSSHConnection to be less strict on the exact unknown user error message, which may vary between OS's.
* Decouple/refactor SkipLocalAuth, UseKeyPrincipal, and static auth methods.
* Resolve comments.
* * Add tests for new methods
* Update proxy ssh principal test to catch regression
* Bump predicate error in switch case priority
Sets `http.Server.IdleTimeout` and `http.Client.IdleConnTimeout`
on clients and servers which didn't have them set. A default of
360s was chosen to be on par with the default of an NLB without
being identical.
This was added as another safety measure to prevent leaking any
idle connections indefinitely as seen in #22757.
`apidefaults.DefaultDialTimeout` was also renamed to
`apidefaults.DefaultIOTimeout` to better reflect its usage.
The HTTP client created by `auth.NewClient` has an idle timeout of
30s and each instance periodically gets cert authorities in
`TeleportProcess.syncRotationStateCycle`. If there has been no
activity when the ticker expires then the request will result in a
brand new connection to Auth to be established. This can cause a
spikes in open file descriptors on the Proxy when there are a large
number of instances connected via a tunnel.
To prevent periodic dialing when retrieving cert authorities the
endpoint has been migrated to the new Trust gRPC service. For now
only the get endpoint has been migrated but the rest of the CRUD
operations for cert authorities should be migrated from the HTTP
api to the gRPC service as well.
* Change formatting for "/version" endpoint
This PR changes the formatting for "/version" endpoint since Kubernetes
clients do not expect a JSON response on that endpoint.
This PR returns the error message directly into the body without any
formatting so that `kubectl` is able to present the desired error.
```
kubectl version --short
Flag --short has been deprecated, and will be removed in the future. The --short output will become the default.
Client Version: v1.25.4
Kustomize Version: v4.5.7
Error from server (InternalError): an error on the server ("this user cannot request kubernetes access, has no assigned groups or users") has prevented the request from succeeding
```
Fixes#20900
* change message wording
* add validation when generating kube creds
* fix typo
- Add a generalized client store made up of a key, profile, and trusted certs store. Each sub store can support different backends (~/.tsh, identity_file, in-memory).
- Replace custom identity file handling with in-memory client store.
- Fix issues with trusted certs handling.
* Connection Diagnostics: Postgres Database tester
When adding a new resource using the Web UI we want to allow users to
test connecting to it.
We have two connection testers already:
- for SSH Nodes
- for Kube clusters
This PR adds a third tester: Postgres Database.
Most of the required changes for any Database are already present but
we're focusing on Postgres for now. Other databases will be added as
future PRs.
Testing a Database is similar to the other tests:
- generate certs for the logged in user
- connect to the resource using those certs
When generating the certificate, we inject an ID so that the Database
Service can add Connection Diagnostic traces.
This PR returns a list of allowed principals that a user is authorized to impersonate for each Kubernetes cluster.
When a Teleport user has multiple Kubernetes users defined for the same Cluster we must allow him to choose one otherwise the request will return an error. Similar to `kubectl get pods --as {user} --as-group {kubeGroup}`.
If the user selects invalid users or groups, it will return invalid Kubernetes principals.
Closes#17382
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
* Reduce number of auth dials for tsh commands
One of the major areas of latency for `tsh ssh` is creating multiple
auth clients. Since the auth client is lazy and only actually performs
the dial on first use we can create an auth client once and simply
reuse it. This is done by adding an `auth.ClientI` to `ProxyClient`
which is created via `connectToProxy`. All attempts to connect to
the current auth server via the `ProxyClient` will be given the
cached `auth.ClientI`.
The new method of retrieving the current auth client also allowed
to remove a number of calls to `GetSites` which were used to obtain
the current cluster name. The local profile already contains the name
of the cluster and calls to `GetSites` were unnecessary. All instances
which relied on the site name now retrieve from information that the
`ProxyClient` already has.
In an effort to reduce ambiguity and confusion `CurrentClusterAccessPoint`
and `ClusterAccessPoint` were also removed. AccessPoint denotes that
you are connecting to a cache, but the `ProxyClient` is always going
to be hitting the auth server directly. The two have been replaced
with `CurrentCluster` and `ConnectToCluster`, which they were merely
wrappers for anyhow.
Update metalinter, fix a few lint warnings and replace deprecated linters.
`deadcode`, `structcheck` and `varcheck` are abandoned and now replaced by [`unused`][1].
Since 1.19, `go fmt` reformats godocs according to https://go.dev/doc/comment. I've done a bulk-reformatting of the codebase to keep the linter happy. Backporting is mostly harmless (the exception being `lib/services/role_test.go`, that for some reason breaks the _old_ linter using the new format).
[1]: https://golangci-lint.run/usage/linters/
* Bump golangci-lint version
* Replace abandoned linters
* Fix bodyclose on lib/auth/github.com
* Fix bodyclose on lib/kube/proxy/streamproto/proto_test.go
* Fix bodyclose on lib/srv/alpnproxy/proxy_test.go
* Fix bodyclose on lib/web/conn_upgrade_test.go
* Silence staticcheck on lib/kube/proxy/forwarder_test.go
* Silence staticcheck on lib/utils/certs_test.go
* Address BuildNameToCertificate deprecation warnings
* Run `go fmt ./...`
* Run `go fmt ./...` on api/
* Ignore formatting in role_test.go
* Remove redundant initializers in lib/srv/uacc/
* Update e/
This PR implements the SSH Tester for ConnectionDiagnostic feature.
This feature is also known as Test Connection, part of Teleport
Discover.
The goal here is to provide immediante feedback about a newly added
resource. Can the user connect to it?
We are targetting SSH Nodes as a first ResourceKind.
To test the access to an SSH Node we require the ResourceName and a
login username (ssh principal).
Then a series of checks will occur in two places:
- SSH client in the Web server
- SSH server in the SSH agent
The ssh client creates a new Connection Diagnostic with some initial
state.
Then it tries to build up the necessary SSH config
This already gives us a couple of things to check for:
- does the node exist and does the current user (inherited from
websession) can access it?
- is the node accepting TCP connections (in the specific port)?
- is the node accepting SSH protocol on top of the TCP connection?
Then, the ConnectionDiagnosticID is inject into the certificate and the
SSH Server receives it and will also Append traces into it:
- is the requested principal allowed for the current user?
- does the requested principal exist in the target node?
This is not an exhaustive list of checks.
For a complete list of which checks are verified please see the
TestDiagnoseSSHConnection test.
After all those checks, it returns if the Connection was successful and
what all of the traces generated along the way.
Demo:



This PR adds the concept of ConnectionTester
ConnectionTester will generate ConnectionDiagnostics by connecting to
the actual resource using a user and some Resource Specific parameters
(principal for SSH access, Database User and Name for Database access,
and so on) and storing the result of multiple checkpoints.
Each resource will have a ConnectionTester (we'll start by SSH access
and then Databases).
It also improves Connection Diagnostics by adding
- update operation (similar to the create one)
- a list of traces, which contain the result of checkpoints in multiple
steps of the connection flow
As an example, for SSH, we'll have at least the following checks:
- Node is reachable
- User has the right permissions
- Node has the expected Principal
The trigger to test a connection will be an endpoint, because our
primary goal is to let the user test the access right after adding the
resource.
This PR does not implement the actual SSHConnectionTester but creates
most of the boilerplate to do so.
The next PR will focus in adding the actual traces.