This reverts commit 4f3aa9a3f2.
We're unable to build for 32-bit Linux due to
https://github.com/golang/go/issues/55152,
which looks like it will be fixed with Go 1.19.2 next week.
We'll re-evaluate with the next Go release and reintroduce this change
as soon as we can.
Label based tsh was sending UUID:0 as the node name to the
IsMFARequired check. The server was checking this name against each
nodes name and uuid. However the port included in the name prevented
any matches from being found. Which resulted in the ssh session being
rejected with an access denied message by the node because mfa was
required but never performed.
This removes the :0 from the node name to the IsMFARequired check and
adds a test case to TestSSHOnMultipleNodes that uses role based
per session mfa.
* switch underlying protocol used for 'tsh scp' to SFTP
* address TODO
* appease linter
* add method to make it easier for other callers to transfer files
* add tests
* print transfer progress with progress bar by default
Also allow a SIGINT to gracefully stop the SFTP connection. This is
necessary because the progress bar will ignore signals and prevent the
process from exiting.
* address SFTP fork issues
* make tests less flakey
* fix specifying dir for dst not copying files to correct paths
* make tests less flakey (again)
* don't check file access times, often differs when run in CI
* few small fixes from review, simplify Create method now that HTTP FS isn't needed
* create dst files and dirs with src mode
* improved error messages when doing file operations
* expand home dirs in remote paths
* addressed more feedback
* add license to get_home_dir.go
* address minor feedback of tests, add home dir expansion test
* update sftp fork to point to latest commit on master branch
* addressed feedback
* don't cache home dir lookups, only one remote path can ever be used
* 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.
* Allow tsh to retrieve cluster details in one request
Prior to connecting to a node via `tsh ssh` we need two bits of
information about the cluster:
1) The session recording mode
2) Whether FIPS is enabled
In order to retrieve the information `tsh` first would send the
global ssh request `RecordingProxyReqType` to determine the
session recording mode. Later on `tsh` would Ping the auth
server to determine if the cluster was running in FIPS mode.
In an effort to reduce the number of round trips to retrieve
this data, a new global ssh request `ClusterDetailsReqType` is
introduced that returns both the session recording mode and
whether FIPS is enabled. This allows `tsh` to leverage the new
request to get all the information it needs, and is extensible
in case more information is needed` in one request which helps
reduce latency for `tsh ssh`.
* Add Yubikey PrivateKey implementation for use by Teleport clients.
- Add yubikey login logic, reusing previously stored private keys.
- Fix identity file decoding with PIV keys, which sign ecdsa certificates.
- Add libpcsclite-dev pre-req for building on linux.
- Remove unnecessary keys.Signer interface and move its functionality to keys.PrivateKey.
- Move retry and jitter utils to new api/utils/retryutils package.
Label based tsh, `tsh ssh root@foo=bar uptime`, may potentially match
a number of nodes that exceeds the users `max_connections` limit.
However, tsh would blindly connect to all matching nodes and execute
the provided command simultaneously. This results in a number of
commands to fail because the user has too many concurrent sessions
open.
Now that #15641 has introduced running multiple commands inside
an `errgroup.Group` we can adjust the limit such that tsh will
never exceed the users `max_connections` limit. In order to
prevent label based tsh from consuming all of a users connections,
the `errgroup.Group` limit is set to half of `max_connections`.
Closes#4626
While looking up github.com/gokyle/hotp I found some old deprecation warnings
and decided to address them.
* Remove HOTP support
* Update comment on checkOTP
* Remove OTPType
* Remove a few more HOTP references
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/
* Refactor our `utils/fs` locking to use `flock`
library and add support for windows.
Flock works differently on linx/mac vs windows. On windows it's impossible to
read/write file after locking, so we need to create separate lockfile.
Switches label based ssh to always use the node UUID instead of its
address. This prevents issues that occurred when dialing by address
if the public_addr isn't set correctly.
Closes#3214
* Prevent ssh.Session SendRequest from wrapping payload twice
Payloads were inadvertently being wrapped twice by sessions making
the ssh server unable to parse the request payload. This is largely
only an issue for window-change requests, as they are the only request
being sent directly via a session that contains a payload. All window-change
requests now use ssh.Session WindowChange instead or sending the request
manually.
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:



Primary Changes:
- Remove reliance on Private Key PEM:
- Update native and keygen packages to return PrivateKey instead of PEM key
- Add new PrivateKey interface which implements crypto.Signer
- Replace PEM encoded private key usage where possible
- Replace calls to tls.(Load)X509KeyPair with keys.(Load)X509KeyPair in
client packages
Minor Changes:
- Remove unused agent.AddedKey return from LoadKey
- Simplify sshutils and removed unused code paths
- Add ecdsa and ed25519 key support
* Add spans to TeleportClient/ProxyClient/NodeSession
* Improve dialer tracing
* Alter default http client span name to include path
* propagate tracing options in NewClientConn
* Make tctl write out kube tls server name if tls routing is enabled
Fixes#14489
* Extract kube TLS name generation function to shareable location
We want tctl to be able to use this function as well, so we're locating it
in a place where both tctl and tsh can use it.
Also changing input parameter to k8s host, since it doesn't really care
about port number.
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.
Adds a wrapper around `ssh.Session` which injects tracing context
in a similar manner to the `ssh.Client` wrapper. All usages of
`ssh.Session` have now been replaced and have the appropriate
`context.Context` passed along
Part of #12241
## What
First part of the Kubernetes [Discovery RFD](https://github.com/gravitational/teleport/pull/13376/) to introduce a Kubernetes server per cluster.
This PR introduces a separate Kubernetes server that uses the already introduced `KubernetesClusterV3`.
## Compatibility
In previous versions, Kubernetes Clusters were part of regular `ServerV2` resource and this refactoring deprecates the `ServerV2` usage but keeps them for compatibility with previous version.
Everything is backward compatible, so v10 kubernetes agents and trusted clusters can connect fine.
## Next steps
Once this is merged, a new PR will introduce dynamic registration for Kubernetes Clusters discovered through EKS Discovery.
In the context of Teleport Discover we are trying to ease the usage of Teleport for the user's first interaction.
When adding a new database resource the user must, among other things, generate the mTLS files
Examples:
https://goteleport.com/docs/database-access/guides/postgres-self-hosted/#step-25-create-a-certificatekey-pairhttps://goteleport.com/docs/database-access/guides/mysql-self-hosted/#step-24-create-a-certificatekey-pair
This PR aims to reduce this friction: the user should be able to setup the resource without prior setup of local tools (`tsh login`)
We're doing this by providing an endpoint that will return those exact files
Demo
```shell
marco@lenix ~/p/downloadmtls> curl --silent --insecure 'https://127.0.0.1.nip.io:3080/v1/webapi/sites/lenix/sign' --dat
a '{"hostname":"discover.example.com", "ttl":"9999h", "format": "db"}' --header 'Authorization: Bearer 308bf3dd3019ddc4
2cff44a48e028480' --header 'Content-Type: application/json' -OJ
marco@lenix ~/p/downloadmtls> tar -xvf teleport_mTLS_discover.example.com.tar.gz
server.key
server.crt
server.cas
marco@lenix ~/p/downloadmtls> head -1 server.*
==> server.cas <==
-----BEGIN CERTIFICATE-----
==> server.crt <==
-----BEGIN CERTIFICATE-----
==> server.key <==
-----BEGIN RSA PRIVATE KEY-----
```
Fixes https://github.com/gravitational/teleport/issues/14049
* SSH request tracing
Add tracing support for ssh global requests and channels. Wrappers
for `ssh.Client`, `ssh.Channel`, and `ssh.NewChannel` provide a
mechanism for tracing context to be propagated via a `context.Context`.
In order to maintain backwards compatibility the ssh.Client wrapper
tries to open a TracingChannel when constructed. Any servers that
don't support tracing will reject the unknown channel. The client
will only provide tracing context to servers which do NOT reject
the TracingChannel request.
In order to include pass tracing context along all ssh payloads
are wrapped in an Envelope that includes the original payload
AND any tracing context. Servers now try to unmarshal all payloads
into said Envelope when processing messages. If there is an Envelope
provided, a new span will be created and the original payload will
be pass along to handlers.
Part of #12241
* `tsh ssh`: graceful error handling for forwarding.
Both regular and dynamic port forwarding will now:
- continue to accept connections even if an error occurred
for whatever reason (e.g., invalid proxy protocol.)
- log richer information
- shut down the listen loop on parent context closure
* Add app access support to Machine ID
This adds support for app access to Machine ID. Users can specify a
new destination-level `app` field which will request certificates
with the given app. Users can then either open a proxied connection
to the app, or supply the credentials via `curl` and access the app
through the public-facing proxy.
This includes a small change to `tsh` to support identity files in
various app-related commands (`proxy app`, `app ls`, etc). The
existing `tsh` wrappers in `tbot` automatically support these app
commands.
* Add app request test
* Clean up test
* Update lib/tbot/config/config_destination.go
Co-authored-by: Noah Stride <noah.stride@goteleport.com>
* Address review feedback
* Simplify `getApp` call
* Simplify `getApp` further
Co-authored-by: Noah Stride <noah.stride@goteleport.com>
This change, along with gravitational/webapps#530, adds a new error message for when a user successfully authenticates with SSO but fails to match any roles.
* configure golangci-lint misspell to check for anglicized spellings
* Americanize spellings
* fix aws constant value with british spelling 🇬🇧
* update api types with americanized spellings
* use american spellings .cloudbuild/scripts