Commit Graph
713 Commits
Author SHA1 Message Date
Andrew Lytvynov b1eae4ac4c Remove unused functions and methods throughout lib/...
This code is not caught by linters because it's exported and they assume
there's some external users.
Since teleport is relatively self-contained, we can tell for sure
whether something is called or not.
2020-05-06 00:02:53 +00:00
Andrew Lytvynov 1a09ce4624 Update kube integration tests to generate a correct cert
There seem to be some test stubs in `lib/auth` that can generate TLS
key/cert but without supporting k8s users/groups.
Rewrite cert generation in `kube_integration_test.go` to use the same
logic as `auth.Server.ProcessKubeCSR`.
2020-05-05 23:50:17 +00:00
Andrew Lytvynov c6931551f6 Enforce UsageKubeOnly in ProcessKubeCSR
Auth server has to trust the proxy with all k8s CSR fields. Usage is the
only field it can enforce, to somewhat limit the blast radius of
compromising this cert flow.
2020-05-05 23:50:17 +00:00
Andrew Lytvynov 5f05d3abf2 Preserve roles from user cert when forwarding k8s requests
When a proxy forwards a k8s request to another proxy in a trusted leaf
cluster, it dynamically generates a new client key/cert to impersonate
the user. This key/cert is presented to the leaf proxy as if a user was
directly making a request to it.

Auth server, when processing the CSR, would load user identity from the
backend. If this user had temporary role grants via workflow API, they
would not be loaded from the backend.

This means that if a user accesses k8s through:
```
kubectl -> root proxy -> leaf proxy -> k8s
```
the second hop would drop their temporary role grants.

To fix this, preserve full user identity from the original client cert
presented to root proxy, as encoded in CSR Subject. The auth server
implicitly trusts the CSR Subject that the proxy presents.
This also requires fixing the Subject encoding on the proxy side, which
was inconsistent with how auth server does it.

One downside here is: a compromised proxy can mint k8s client certs for
known users with arbitrary roles.
2020-05-05 23:50:17 +00:00
Lisa Kim 118ad19101 Emit correct event user who updates user records (#3635)
* Add UpdateUser rpc to proto
* Differentiate between create and update in github,oidc,saml
* Edit updated_by event field to be more generic (used with contexts to capture user modifying records)
* Update security issue by removing secrets from user when update/upsert/create (forrest)
* Update createUser in resource_command and require force for updates
2020-05-05 16:49:32 -07:00
Andrew Lytvynov bd2c9a0828 Fix staticcheck findings in lib/auth
Fixed findings:
```
lib/auth/clt.go:294:12: SA1019: grpc.WithDialer is deprecated: use WithContextDialer instead.  Will be supported throughout 1.x.  (staticcheck)
	dialer := grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {ion error: desc = "transport: Erro
	         ^
lib/auth/clt.go:1462:5: SA1019: grpc.Code is deprecated: use status.Code instead.  (staticcheck)site-A Type:proxy Addr:{Addr:local
	if grpc.Code(err) != codes.Unimplemented {
	  ^
lib/auth/clt.go:1500:5: SA1019: grpc.Code is deprecated: use status.Code instead.  (staticcheck)rsetunnel/agentpool.go:312
	if grpc.Code(err) != codes.Unimplemented {
	  ^
lib/auth/saml.go:294:33: SA5011: possible nil pointer dereference (staticcheck)
		events.EventUser:          re.auth.Username,
		                             ^
lib/auth/auth_test.go:119:2: SA4006: this value of `ws` is never used (staticcheck)ats. stats:map[connected:1 connect
	ws, err := s.a.AuthenticateWebUser(AuthenticateUserRequest{
	^
lib/auth/auth_test.go:160:2: SA4006: this value of `ws` is never used (staticcheck)ver.go:425
	ws, err := s.a.AuthenticateWebUser(AuthenticateUserRequest{
	^
lib/auth/auth_test.go:243:2: SA4006: this value of `roles` is never used (staticcheck)es that discovery protocol recover
	roles, err = s.a.ValidateToken(tok)
	^
lib/auth/password_test.go:228:2: SA4006: this value of `err` is never used (staticcheck)necting -> connected. leaseID:5 ta
	token, err := s.a.CreateResetPasswordToken(context.TODO(), CreateResetPasswordTokenRequest{7.0.0.1:46150. reversetunnel/srv.g
	^
lib/auth/tls_test.go:109:2: SA4006: this value of `err` is never used (staticcheck)ry(c *check.C) {
	err = s.server.AuthServer.Trust(remoteServer, nil)
	^
lib/auth/tls_test.go:195:2: SA4006: this value of `err` is never used (staticcheck)meout=10000&_sync=OFF, poll stream
	err = s.server.AuthServer.Trust(remoteServer, nil)
	^
lib/auth/tls_test.go:360:2: SA4006: this value of `newProxy` is never used (staticcheck) be received and the connection ad
	newProxy, err := s.server.NewClient(TestBuiltin(teleport.RoleProxy))o/src/github.com/gravitational/tel
	^
lib/auth/tls_test.go:388:2: SA4006: this value of `err` is never used (staticcheck)o/src/github.com/gravitational/tel
	err = s.server.Auth().autoRotateCertAuthorities()
	^
lib/auth/tls_test.go:1074:2: SA4006: this value of `err` is never used (staticcheck)uest, we will recover session id a
	err = os.MkdirAll(filepath.Join(uploadDir, "upload", "sessions", defaults.Namespace), 0755)reversetunnel/agent.go:458
	^
lib/auth/tls_test.go:1263:2: SA4006: this value of `err` is never used (staticcheck)quests channel. leaseID:5 target:l
	err = clt.UpsertPassword(user, pass)
	^
lib/auth/tls_test.go:1691:2: SA4006: this value of `err` is never used (staticcheck)
	userCerts, err = adminClient.GenerateUserCerts(context.TODO(), proto.UserCertsRequest{et:localhost:20088 reversetunnel/t
	^
lib/auth/auth_with_roles.go:860:32: SA1029: should not use built-in type string as key for value; define your own type to avoid collisions (staticcheck)
	return context.WithValue(ctx, events.AccessRequestUpdateBy, user)ts is received, if it's been longe
	                             ^
lib/auth/auth_with_roles.go:876:32: SA1029: should not use built-in type string as key for value; define your own type to avoid collisions (staticcheck)
	return context.WithValue(ctx, events.AccessRequestDelegator, delegator)ime = f.process.Clock.Now()
	                             ^
lib/auth/middleware.go:316:69: SA1029: should not use built-in type string as key for value; define your own type to avoid collisions (staticcheck)
	requestWithContext := r.WithContext(context.WithValue(baseContext, ContextUser, user))rocess.Infof("Teleport has recover
	                                                                  ^ion to @remote-auth-server [] in r
lib/auth/apiserver.go:285:42: SA1029: should not use built-in type string as key for value; define your own type to avoid collisions (staticcheck)
			ctx := context.WithValue(r.Context(), contextParams, p)et:localhost:20088 reversetunnel/t
			                                     ^
```
2020-04-29 22:40:15 +00:00
aelkugia 9d6c678fea Updating link to generic ssh_sso page. 2020-04-29 14:07:44 -07:00
aelkugia 3986b2e2e0 Added clarification to error handling in audit log when Teleport receives empty claims or attribute statements.
Resolves: #3111
2020-04-29 14:07:44 -07:00
Forrest Marshall c0c1aa063d support access-request update delegators 2020-04-23 14:57:09 -07:00
Andrew Lytvynov 703708ac79 Improve error message for revoked node join token
The node first tries using the token with auth server. If that fails, it
tries the same address as a proxy server.
If both fail, user only sees the error from the latter attempt. If using
CA pin, this error will be "x509: certificate signed by unknown
authority", which is confusing.

Log both errors, and mention that a fallback is happening. The output
looks like:

    ERRO [AUTH]      Failed to register through auth server: "my-hostname" [3e53a982-afd1-4d2f-8864-54c25fbe5865] can not join the cluster with role Node, the token is not valid; falling back to trying the proxy server auth/register.go:123
    ERRO [PROC:1]    Node failed to establish connection to cluster: failed to register through proxy server: x509: certificate signed by unknown authority. time/sleep.go:149
2020-04-23 20:09:35 +00:00
Lisa Kim 6bb9ef65fa Define create user rpc and event (#3602)
* Define a CreateUser event, code, and its related const
* Define CreateUser rpc in auth/proto file
* Define CreateUser between layers
* Replace UpsertUser with CreateUser in tctl and in unit test
2020-04-22 13:04:40 -07:00
Andrew Lytvynov d1ea40d074 Enable linters: deadcode,goimports,govet,typecheck
And fix the relevant findings for these linters.

Also, set extra flags for `golangci-lint run` to make sure no findings
are suppressed.
2020-04-17 17:46:51 +00:00
Lisa Kim 1606b30281 Wrap error from u2f library with Trace.BadParameter when registry fails (#3592)
* Removed proxy/auth version mismatch check
2020-04-16 15:32:26 -07:00
3c670d5d58 Merge Teleport V4.3 UI branch to master (#3583)
* Add monorepo

* Add reset/passwd capability for local users (#3287)

* Add UserTokens to allow password resets

* Pass context down through ChangePasswordWithToken

* Rename UserToken to ResetPasswordToken

* Add auto formatting for proto files

* Add common Marshaller interfaces to reset password token

* Allow enterprise "tctl" reuse OSS user methods (#3344)

* Pass localAuthEnabled flag to UI (#3412)

* Added LocalAuthEnabled prop to WebConfigAuthSetting struct in webconfig.go
* Added LocalAuthEnabled state as part of webCfg in  apiserver.go

* update e-refs

* Fix a regression bug after merge

* Update tctl CLI output msgs (#3442)

* Use local user client when resolving user roles

* Update webapps ref

* Add and retrieve fields from Cluster struct (#3476)

* Set Teleport versions for node, auth, proxy init heartbeat
* Add and retrieve fields NodeCount, PublicURL, AuthVersion from Clusters
* Remove debug logging to avoid log pollution when getting public_addr of proxy
* Create helper func GuessProxyHost to get the public_addr of a proxy host
* Refactor newResetPasswordToken to use GuessProxyHost and remove publicUrl func

* Remove webapps submodule

* Add webassets submodule

* Replace webapps sub-module reference with webassets

* Update webassets path in Makefile

* Update webassets

1b11b26 Simplify and clean up Makefile (#62) https://github.com/gravitational/webapps/commit/1b11b26

* Retrieve cluster details for user context (#3515)

* Let GuessProxyHost also return proxy's version
* Unit test GuessProxyHostAndVersion & GetClusterDetails

* Update webassets

4dfef4e Fix build pipeline (#66) https://github.com/gravitational/webapps/commit/4dfef4e

* Update e-ref

* Update webassets

0647568 Fix OSS redirects https://github.com/gravitational/webapps/commit/0647568

* update e-ref

* Update webassets

e0f4189 Address security audit warnings Updates  "minimist" package which is used by 7y old "optimist". https://github.com/gravitational/webapps/commit/e0f4189

* Add new attr to Session struct (#3574)

* Add fields ServerHostname and ServerAddr
* Set these fields on newSession

* Ensure webassets submodule during build

* Update e-ref

* Ensure webassets before running unit-tests

* Update E-ref

Co-authored-by: Lisa Kim <lisa@gravitational.com>
Co-authored-by: Pierre Beaucamp <pierre@gravitational.com>
Co-authored-by: Jenkins <jenkins@gravitational.io>
2020-04-15 15:35:26 -04:00
Andrew Lytvynov 7890b4b7a7 Add local aliases to default host cert principals
Adding following principals:
- `localhost`
- `127.0.0.1`
- `::1`

With these, `tsh` (both `ssh` and `join`) works with a local proxy
without any SSH handshake errors.

Removed the warning from quickstart docs, but keeping `--proxy=grav-00`
since that implies to the reader that proxy is usually remote.

Fixes #2910
2020-04-15 01:23:03 +00:00
Andrew Lytvynov f8661edea3 Clean up dead code across the codebase
Spring cleaning!
A very mechanical cleanup using several linters (unused, deadcode,
structcheck). Build and tests still pass so no behavior should be
affected.
2020-04-09 21:10:12 +00:00
Steven Martin c276f0e10b Correct misspelling in output 2020-04-02 14:54:43 -04:00
Steven Martin 8ca47def00 Correct spelling in oidc debugging 2020-04-02 14:51:06 -04:00
Alexander Klizhentas 924dd8fdb0 Adds support for custom OIDC prompts (#3409)
This commit adds support for custom OIDC prompt values.

Read about possible prompt values here:

https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest

Three cases are possible:

* Prompt value is not set, this defaults to
OIDC prompt value to select_account value to preserve backwards
compatibility.

```yaml
kind: oidc
version: v2
metadata:
  name: connector
spec:
  prompt: 'login consent'
```

* Prompt value is set to empty string, it will be omitted
from the auth request.

```yaml
kind: oidc
version: v2
metadata:
  name: connector
spec:
  prompt: ''
```

* Prompt value is set to non empty string, it will be included
in the auth request as is.

```yaml
kind: oidc
version: v2
metadata:
  name: connector
spec:
  prompt: 'login consent'
```

Tested with Auth0 OIDC connector on teleport 4.2 enterprise.
2020-03-20 17:57:05 -07:00
Roman TkachenkoandRussell Jones 976f065027 Update the way auth server extracts server id from identity. (#3417)
Co-authored-by: Russell Jones <russjones@users.noreply.github.com>
2020-03-10 09:12:20 -07:00
Alexander Klizhentas 73ecb48232 Adds support for kubernetes_users, extend interpolation (#3404) (#3418)
This commit fixes #3369, refs #3374

It adds support for kuberenetes_users section in roles,
allowing Teleport proxy to impersonate user identities.

It also extends variable interpolation syntax by adding
suffix and prefix to variables and function `email.local`:

Example:

```yaml
kind: role
version: v3
metadata:
  name: admin
spec:
  allow:
    # extract email local part from the email claim
    logins: ['{{email.local(external.email)}}']

    # impersonate a kubernetes user with IAM prefix
    kubernetes_users: ['IAM#{{external.email}}']

  # the deny section uses the identical format as the 'allow' section.
  # the deny rules always override allow rules.
  deny: {}
```

Some notes on email.local behavior:

* This is the only function supported in the template variables for now
* In case if the email.local will encounter invalid email address,
it will interpolate to empty value, will be removed from resulting
output.

Changes in impersonation behavior:

* By default, if no kubernetes_users is set, which is a majority of cases,
  user will impersonate themselves, which is the backwards-compatible behavior.

* As long as at least one `kubernetes_users` is set, the forwarder will start
  limiting the list of users allowed by the client to impersonate.

* If the users' role set does not include actual user name, it will be rejected,
  otherwise there will be no way to exclude the user from the list).

* If the `kuberentes_users` role set includes only one user
  (quite frequently that's the real intent), teleport will default to it,
  otherwise it will refuse to select.

  This will enable the use case when `kubernetes_users` has just one field to
  link the user identity with the IAM role, for example `IAM#{{external.email}}`

* Previous versions of the forwarding proxy were denying all external
impersonation headers, this commit allows 'Impesrsonate-User' and
'Impersonate-Group' header values that are allowed by role set.

* Previous versions of the forwarding proxy ignored 'Deny' section of the roles
when applied to impersonation, this commit fixes that - roles with deny
kubernetes_users and kubernetes_groups section will not allow
impersonation of those users and groups.
2020-03-07 16:32:37 -08:00
Forrest Marshall 56eea87d13 implement transparent UUID based routing 2020-03-05 10:30:20 -08:00
Forrest Marshall 3967075503 Add Ping method to auth server (#3298) 2020-02-06 12:49:19 -08:00
Russell Jones de25684689 Added testing.Verbose to allow silencing of tests. 2020-02-06 11:15:44 -08:00
Forrest Marshall 257274b26f Implement per-resource PluginData storage (#3286)
- Also addresses #3282 by adding retries for CompareAndSwap
on SetAccessRequestState and UpdatePluginData.
2020-01-30 14:27:40 -08:00
Sasha Klizhentas 83d0f7e7bb Fix role mapping for trusted clusters
This commit fixes #3252

Security patches 4.2 introduced a regression - leaf clusters ignore role mapping
and attempt to use role names coming from identity of the root cluster
whenever GetNodes method was used.

This commit reverts back the logic, however it ensures that the original
fix is preserved - traits and groups are updated on the user object.

Integration test has been extended to avoid the regression in the future.
2020-01-15 12:57:33 -08:00
Forrest Marshall 088be329af implement delayed access-request cleanup 2019-12-06 15:56:04 -08:00
Russell Jones 77e8b63470 Enhanced Session Recording.
Added package cgroup to orchestrate cgroups. Only support for cgroup2
was added to utilize because cgroup2 cgroups have unique IDs that can be
used correlated with BPF events.

Added bpf package that contains three BPF programs: execsnoop,
opensnoop, and tcpconnect. The bpf package starts and stops these
programs as well  correlating their output with Teleport sessions
and emitting them to the audit log.

Added support for Teleport to re-exec itself before launching a shell.
This allows Teleport to start a child process, capture it's PID, place
the PID in a cgroup, and then continue to process. Once the process is
continued it can be tracked by it's cgroup ID.

Reduced the total number of connections to a host so Teleport does not
quickly exhaust all file descriptors. Exhausting all file descriptors
happens very quickly when disk events are emitted to the audit log which
are emitted at a very high rate.

Added tarballs for exec sessions. Updated session.start and session.end
events with additional metadata. Updated the format of session tarballs
to include enhanced events.

Added file configuration for enhanced session recording. Added code to
startup enhanced session recording and pass package to SSH nodes.
2019-12-02 15:10:39 -08:00
Forrest Marshall ec327b6e03 Implment access-request system (workflow API) 2019-12-02 14:05:51 -08:00
Sasha Klizhentas 21e0342021 Fix support for GSuite logins
This commit fixes support for GSuite logins
by using service accounts for access purposes.

The resulting connector now looks like:

```yaml
kind: oidc
version: v2
metadata:
  name: gsuite
spec:
  redirect_url: https://example.com/v1/webapi/oidc/callback
  client_id: exampleclientid.apps.googleusercontent.com
  client_secret: exampleclientsecret
  issuer_url: https://accounts.google.com
  # Notice that scope here is not requiested from OIDC exchange anymore, this scope
  #
  # https://www.googleapis.com/auth/admin.directory.group.readonly
  #
  # is now implicitly requested by the client
  #
  scope: ['openid', 'email']
  # The setup below is involved and requires careful following of the guides:
  #
  # https://developers.google.com/admin-sdk/directory/v1/guides/delegation
  # https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority
  #
  # The service account scopes have to be set to
  #
  # https://www.googleapis.com/auth/admin.directory.group.readonly
  # https://www.googleapis.com/auth/admin.directory.group.member.readonly
  #
  # the following paths are supported:
  # 1. plain path
  # /var/lib/secrets/gsuite-creds.json
  #
  # 2. explicit scheme file://
  # file:///var/lib/secrets/gsuite-creds.json
  #
  # other schemes are not supported at the moment
  #
  google_service_account_file: "/var/lib/secrets/gsuite-creds.json"
  google_admin_email: "admin@example.com"
  claims_to_roles:
    - {claim: "groups", value: "admin@example.com", roles: ["clusteradmin"]}
```
2019-11-06 18:52:52 -08:00
Alexander Klizhentas 8be98bcc21 Remove blacklisted FIPS ciphersuites, fix local_auth (#3103)
This commit fixes Web UI in FIPS mode when local_auth is false
and removes two ciphers banned by HTTP2 rfc spec:

https://tools.ietf.org/html/rfc7540#appendix-A

and used by FIPS, causing Teleport GRPC to fail.
2019-10-23 13:55:40 -07:00
Roman Tkachenko 0956a6b1d8 Fix CreateWebSession method. (#3080) 2019-10-14 10:30:39 -07:00
Alexander Klizhentas 5055656572 Close access point cache on cluster disconnect. (#3037)
This commit fixes goroutine leak - whenever
a leaf cluster disconnects from the root cluster,
the caching access point cache update loop has to be closed
as well.
2019-10-01 10:25:01 -07:00
Russell Jones e8aae88112 Restore CreateWebSession endpoint.
Revert 04b4469  to restore the CreateWebSession endpoint.
2019-09-12 11:43:49 -07:00
Russell Jones f0a455f2ea Use JSON for trait encoding. 2019-09-11 15:13:52 -07:00
Russell Jones d8c638a3b6 Always emit session related events with host UUID.
When emitting session related events, emit them with the ID of the host
not of the server. This is because the forwarding server has a randomly
generated ID that will note validate with TLS identity that connects to
the Auth Server.
2019-09-05 17:02:00 -07:00
Russell Jones 100a9d15ea Fix failing test. 2019-09-03 13:44:20 -07:00
Russell Jones 9460c6f15e Rate limit password check endpoint.
Wrap the password check endpoint with a rate limiter to prevent brute
force attacks.
2019-09-03 13:44:20 -07:00
Russell Jones 1c49f681bd Fixed unauthenticated user creation.
The currentUserAction endpoint on the Auth Server allows access to a
user "Nop" if no form of client authentication is provided. Since this
user is not associated with a role, it has no logins, and can not obtain
SSH x509 credentials.

To strengthen access controls, currentUserAction only allows locally
authenticated users whose with a name match access.
2019-09-03 13:44:20 -07:00
Russell Jones 04b4469a66 Removed CreateWebSession endpoint. 2019-09-03 13:44:20 -07:00
Russell Jones 9135a5ade7 Use roles and traits in certificate for RBAC.
If an attacker can force a username change at an IdP, upon second login,
the services.User object of the original user can be updated with new
roles and traits. If these new roles and traits differ, the original
user can have their privileges raised (or lowered).

To mitigate this, encode roles and traits within the certificate and use
these when fetching roles to make RBAC decisions. If roles and traits are
not encoded within an certificate (for example for old style SSH
certificates then fallback to using the services.User object and log a
warning.
2019-09-03 13:44:20 -07:00
Russell Jones 9a5acfb9de Mask errors to mitigate user enumeration. 2019-09-03 13:44:20 -07:00
Russell Jones ba7bdab41c Validate session ID upon upload.
Before sending and receiving a session recording, parse the session ID
to make sure it's a UUID to prevent an attacker from uploading an
arbitrary file.
2019-09-03 13:44:20 -07:00
Russell Jones 5a38647896 Constant time compare for tokens. 2019-09-03 13:44:20 -07:00
Russell Jones 8bd706d56a Validate incoming events against x509 identity.
Validate all incoming events (and archives) to ensure that the server ID
within the event matches the x509 identity of the connected host. This
check makes sure nodes can only submit events for themselves.

In addition, make sure session recordings to disk or S3 can not be
overwritten.
2019-09-03 13:44:20 -07:00
Forrest Marshall 05f3eeaf00 Support resource-based bootstrapping for backend. (#2871)
* Support resource-based bootstrapping for backend.

Outside of static configuration, most of the persistent state of an
auth server exists as a collection of resources, stored in its
backend.  The resource API also forms the basis of Teleport's more
advanced dynamic configuration options.

This commit extends the usefulness of the resource API by adding
the ability to bootstrap backend state with a set of previously
exported resources.  This allows the resource API to serve as a
rudimentary backup/migration tool.

Notes: This features is a work in progress, and very easy to misuse;
while it will prevent you from overwriting the state of an existing
auth server, it won't stop you from bootstrapping into a wildly
misconfigured state.  In general, resource-based bootstrapping is
not a complete solution for backup or migration.

* update e-ref
2019-08-29 16:16:03 -07:00
Sasha Klizhentas 1327929811 Include identity traits in the audit log.
Implements #2823
2019-08-07 11:07:33 -07:00
Sasha Klizhentas aad397fbbd Better error message for IdP initated logins.
Fixes #2648

Teleport does not support SAML identity provider
initiated logins, this commit gives a better
error message to the user instructing them
what to do.
2019-08-06 16:40:29 -07:00
Sasha Klizhentas 838e75468c Add support for ProxyJump.
This commit implements #2543

In SSH terms ProxyJump is a shortcut for SSH client
connecting the proxy/jumphost and requesting .port forwarding to the
target node.

This commit adds support for direct-tcpip request support
in teleport proxy service that is an alias to the existing proxy
subsystem and reuses most of the code.

This commit also adds support to "route to cluster" metadata
encoded in SSH certificate making it possible to have client
SSH certificates to include the metadata that will cause the proxy
to route the client requests to a specific cluster.

`tsh ssh -J proxy:port ` is supported in a limited way:

Only one jump host is supported (-J supports chaining
that teleport does not utilise) and tsh will return with error
in case of two jumphosts: -J a,b will not work.

In case if `tsh ssh -J user@proxy` is used, it overrides
the SSH proxy coming from the tsh profile and port-forwarding
is used instead of the existing teleport proxy subsystem
2019-07-26 10:58:11 -07:00
Alexander Klizhentas 32b84e6765 Read join tokens from file, fixes #2515. (#2864) 2019-07-17 12:51:18 -07:00