Commit Graph
2024 Commits
Author SHA1 Message Date
Andrew Lytvynov d40013f33b Send SCP error messages to receiver when upload fails
This serves two purposes:
1. on upload, the receiver (node) will exit with error and generate an
   SCP error audit event.
2. on download, the receiver (tsh) will print a meaningful message from
   the sender (node)

Fixes #2861
2020-05-06 00:03:30 +00:00
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 deae9154b0 lib/kube/proxy: extract auth handling into a separate file
The existing kubeCreds already has tls.Config.
Add a new wrapTransport method to it, which handles added bearer tokens
or basic auth to the request before it goes out.

Use this wrapTransport to inject tokens for both SPDY connections and
catch-all forwarder requests.

Also simplify a few unrelated parts:
- don't manually call serverName verification in SPDY dialer
- have requestCertificate return a finished tls.Config instead of an
  intermediate type
2020-05-05 00:13:29 +00:00
Andrew Lytvynov 042e598ad7 lib/kube/proxy: always use server addr from kubeconfig
TargetAddr from ForwarderConfig wasn't actually ever used. Kubeconfig
parsing would fail if server address was missing.
2020-05-05 00:13:29 +00:00
Andrew Lytvynov faa95af34c Enable all kubeconfig auth plugins
By importing the magic `k8s.io/client-go/plugin/pkg/client/auth`
package, we compile-in support for auth plugins: gcp, azure, oidc,
openstack.

Without this, users can't provide a kubeconfig using those authn
methods to a proxy.
2020-05-05 00:13:29 +00:00
Andrew Lytvynov 24afdc0de6 Ensure all tests run exactly once per package
With gocheck, tests only run if you call `check.TestingT(t)` from a
dummy `func Test(t *testing.T)`.

Added the missing dummy function call in: `lib/services/suite`,
`lib/shell`. The `lib/shell` tests also turned out to be broken.

If you call the dummy wrapper twice, all tests will run twice.
This was happening in `lib/events/s3sessions` and `lib/services/local`.
2020-04-30 16:35:35 +00:00
Andrew Lytvynov 288d4d7062 Add test coverage for kubeconfig identityfile.Write
Turns out, identityfile tests weren't ran in the first place due to
missing a magic incantation.
2020-04-30 00:19:51 +00:00
Andrew Lytvynov 2c1bf076e6 Add support for kubernetes identity file format
There are two new ways you can generate a kubeconfig:
- `tctl auth sign --user=foo --format=kubernetes --out=kubeconfig` for
  admins
- `tsh login --format=kubernetes -o kubeconfig` for users

This allows admins to generate long-lived kubeconfigs for e.g. CI
systems.

A tricky part is getting the kubernetes endpoint for a proxy in `tctl`.
It does its best to guess the address, but falls back to asking user to
pass `--proxy` flag.
It looks like right now, the proxy info available via the auth server's
API doesn't have kubernetes public_addr for proxies.

Fixes #2825
2020-04-30 00:19:51 +00: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
Russell Jones 9c4e556502 Fixed regressions in "tsh login <clusterName>".
Fixed regressions in how the cluster name was set in the profile when
doing "tsh login <clusterName>". The following examples illustrate
expected behavior.

Suppose root cluster is example.com and the leaf cluster is
leaf.example.com.

* "tsh login" will update profile to example.com.
* "tsh login example.com" will update profile to example.com.
* "tsh login leaf.example.com" will update profile to
  leaf.example.com.
* "tsh login invalid.example.com" will return an error.

Note: The profile is only updated when a identity flag is NOT provided.
This means the following command will NOT update the profile:

tsh --proxy=example.com login --out=certs.pem leaf.example.com
2020-04-29 10:49:23 -07:00
Forrest Marshall c341d2bc15 fix agent forwarding for multi-session connections
Changes the lifetime of agent forwarding to be scoped
to the underlying ssh connection, instead of the
specific ssh channel which initially passed the agent
forwarding request.
2020-04-28 17:45:29 -07:00
Andrew Lytvynov bdd388e0d0 Fix remaining staticcheck findings in lib/...
Fixed findings:
```
lib/sshutils/server_test.go:163:2: SA4006: this value of `clt` is never used (staticcheck)
	clt, err := ssh.Dial("tcp", srv.Addr(), &cc)
	^
lib/sshutils/server_test.go:91:3: SA5001: should check returned error before deferring ch.Close() (staticcheck)
		defer ch.Close()
		^
lib/shell/shell_test.go:33:2: SA4006: this value of `shell` is never used (staticcheck)
	shell, err = GetLoginShell("non-existent-user")
	^
lib/cgroup/cgroup_test.go:111:2: SA9003: empty branch (staticcheck)
	if err != nil {
	^
lib/cgroup/cgroup_test.go:119:2: SA5001: should check returned error before deferring service.Close() (staticcheck)
	defer service.Close()
	^
lib/client/keystore_test.go:138:2: SA4006: this value of `keyCopy` is never used (staticcheck)
	keyCopy, err = s.store.GetKey("host.a", "bob")
	^
lib/client/api.go:1604:3: SA4004: the surrounding loop is unconditionally terminated (staticcheck)
		return makeProxyClient(sshClient, m), nil
		^
lib/backend/test/suite.go:156:2: SA4006: this value of `err` is never used (staticcheck)
	result, err = s.B.GetRange(ctx, prefix("/prefix/c/c1"), backend.RangeEnd(prefix("/prefix/c/cz")), backend.NoLimit)
	^
lib/utils/timeout_test.go:84:2: SA1019: t.Dial is deprecated: Use DialContext instead, which allows the transport to cancel dials as soon as they are no longer needed. If both are set, DialContext takes priority.  (staticcheck)
	t.Dial = func(network string, addr string) (net.Conn, error) {
	^
lib/utils/websocketwriter.go:83:3: SA4006: this value of `err` is never used (staticcheck)
		utf8, err = w.encoder.String(string(data))
		^
lib/utils/loadbalancer_test.go:134:2: SA4006: this value of `out` is never used (staticcheck)
	out, err = Roundtrip(frontend.String())
	^
lib/utils/loadbalancer_test.go:209:2: SA4006: this value of `out` is never used (staticcheck)
	out, err = RoundtripWithConn(conn)
	^
lib/srv/forward/sshserver.go:582:3: SA4004: the surrounding loop is unconditionally terminated (staticcheck)
		return
		^
lib/service/service.go:347:4: SA4006: this value of `err` is never used (staticcheck)
			i, err = auth.GenerateIdentity(process.localAuth, id, principals, dnsNames)
			^
lib/service/signals.go:60:3: SA1016: syscall.SIGKILL cannot be trapped (did you mean syscall.SIGTERM?) (staticcheck)
		syscall.SIGKILL, // fast shutdown
		^
lib/config/configuration_test.go:184:2: SA4006: this value of `conf` is never used (staticcheck)
	conf, err = ReadFromFile(s.configFileBadContent)
	^
lib/config/configuration.go:129:2: SA5001: should check returned error before deferring reader.Close() (staticcheck)
	defer reader.Close()
	^
lib/kube/kubeconfig/kubeconfig_test.go:227:2: SA4006: this value of `err` is never used (staticcheck)
	tlsCert, err := ca.GenerateCertificate(tlsca.CertificateRequest{
	^
lib/srv/sess.go:720:3: SA4006: this value of `err` is never used (staticcheck)
		result, err := s.term.Wait()
		^
lib/multiplexer/multiplexer_test.go:169:11: SA1006: printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck)
	_, err = fmt.Fprintf(conn, proxyLine.String())
	        ^
lib/multiplexer/multiplexer_test.go:221:11: SA1006: printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck)
	_, err = fmt.Fprintf(conn, proxyLine.String())
	        ^
```
2020-04-28 15:17:44 +00:00
Andrew Lytvynov 24ae390bb9 Fix staticcheck findings in lib/services/...
Fixed findings:
```
lib/services/github_test.go:99:2: SA4006: this value of `kubeUsers` is never used (staticcheck)
	logins, kubeGroups, kubeUsers = connector.MapClaims(GithubClaims{
	^
lib/services/github_test.go:107:2: SA4006: this value of `kubeUsers` is never used (staticcheck)
	logins, kubeGroups, kubeUsers = connector.MapClaims(GithubClaims{
	^
lib/services/local/configuration_test.go:84:2: SA4006: this value of `clusterConfig` is never used (staticcheck)
	clusterConfig, err := services.NewClusterConfig(services.ClusterConfigSpecV3{
	^
lib/services/local/configuration_test.go:102:2: SA4006: this value of `clusterConfig` is never used (staticcheck)
	clusterConfig, err := services.NewClusterConfig(services.ClusterConfigSpecV3{})
	^
lib/services/local/presence_test.go:108:2: SA4006: this value of `gotTC` is never used (staticcheck)
	gotTC, err = presenceBackend.GetTrustedCluster("foo")
	^
lib/services/suite/suite.go:157:2: SA4006: this value of `err` is never used (staticcheck)
	out, err := s.WebS.GetUser("user1", false)
	^
lib/services/suite/suite.go:208:2: SA4006: this value of `u` is never used (staticcheck)
	u, err = s.WebS.GetUser("foo", false)
	^
lib/services/suite/suite.go:277:2: SA4006: this value of `err` is never used (staticcheck)
	err = s.CAS.CompareAndSwapCertAuthority(&newCA, ca)
	^
lib/services/suite/suite.go:339:2: SA4006: this value of `err` is never used (staticcheck)
	out, err = s.PresenceS.GetProxies()
	^
lib/services/suite/suite.go:1136:5: SA4006: this value of `err` is never used (staticcheck)
				role, err := services.NewRole("role1", services.RoleSpecV3{
				^
lib/services/suite/suite.go:1166:5: SA4006: this value of `err` is never used (staticcheck)
				err := s.Users().UpsertUser(user)
				^
```
2020-04-28 15:17:44 +00:00
Andrew Lytvynov 935375a00d Fix staticcheck findings in lib/events/...
Fixed findings:
```
lib/events/test/suite.go:88:2: SA4006: this value of `err` is never used (staticcheck)
	err := s.Log.EmitAuditEvent(events.UserLocalLogin, events.EventFields{
	^
lib/events/auditlog_test.go:98:2: SA4006: this value of `err` is never used (staticcheck)
	fileHandler, err := filesessions.NewHandler(filesessions.Config{
	^
lib/events/auditlog_test.go:121:2: SA4006: this value of `err` is never used (staticcheck)
	err = os.MkdirAll(filepath.Join(uploadDir, "upload", "sessions", defaults.Namespace), 0755)
	^
lib/events/auditlog_test.go:224:2: SA4006: this value of `err` is never used (staticcheck)
	fileHandler, err := filesessions.NewHandler(filesessions.Config{
	^
lib/events/auditlog_test.go:246:2: SA4006: this value of `err` is never used (staticcheck)
	err = os.MkdirAll(filepath.Join(uploadDir, "upload", "sessions", defaults.Namespace), 0755)
	^
lib/events/auditlog_test.go:381:2: SA4006: this value of `err` is never used (staticcheck)
	fileHandler, err := filesessions.NewHandler(filesessions.Config{
	^
lib/events/auditlog_test.go:403:2: SA4006: this value of `err` is never used (staticcheck)
	fileHandler, err := filesessions.NewHandler(filesessions.Config{
	^
lib/events/auditlog_test.go:431:2: SA4006: this value of `err` is never used (staticcheck)
	err := os.MkdirAll(filepath.Join(uploadDir, "upload", "sessions", defaults.Namespace), 0755)
	^
lib/events/filesessions/fileuploader.go:84:2: SA4006: this value of `err` is never used (staticcheck)
	_, err := os.Stat(filepath.Dir(path))
	^
lib/events/dynamoevents/dynamoevents.go:352:2: SA4006: this value of `err` is never used (staticcheck)
	attributeValues, err := dynamodbattribute.MarshalMap(attributes)
	^
lib/events/dynamoevents/dynamoevents.go:405:2: SA4006: this value of `err` is never used (staticcheck)
	attributeValues, err := dynamodbattribute.MarshalMap(attributes)
	^
```
2020-04-28 15:17:44 +00:00
Andrew Lytvynov c840f16c42 Fix staticcheck findings in lib/web/...
Fixed issues:
```
lib/web/apiserver_test.go:499:2: SA4006: this value of `re` is never used (staticcheck)
	re, err = pack.clt.Get(context.Background(), pack.clt.Endpoint("webapi", "sites"), url.Values{})
	^
lib/web/apiserver_test.go:590:2: SA4006: this value of `re` is never used (staticcheck)
	re, err = newPack.clt.Get(context.Background(), pack.clt.Endpoint("webapi", "sites"), url.Values{})
	^
lib/web/apiserver_test.go:598:2: SA4006: this value of `re` is never used (staticcheck)
	re, err = oldClt.Get(context.Background(), pack.clt.Endpoint("webapi", "sites"), url.Values{})
	^
lib/web/apiserver_test.go:608:2: SA4006: this value of `re` is never used (staticcheck)
	re, err = newPack.clt.Get(context.Background(), pack.clt.Endpoint("webapi", "sites"), url.Values{})
	^
lib/web/apiserver_test.go:1106:2: SA4006: this value of `err` is never used (staticcheck)
	loginReq, err := json.Marshal(createSessionReq{
	^
lib/web/apiserver_test.go:1120:2: SA4006: this value of `err` is never used (staticcheck)
	re, err := clt.Client.RoundTrip(func() (*http.Response, error) {
	^
lib/web/apiserver_test.go:1148:2: SA4006: this value of `re` is never used (staticcheck)
	re, err = clt.Get(context.Background(), clt.Endpoint("webapi", "sites"), url.Values{})
	^
lib/web/apiserver_test.go:1154:2: SA4006: this value of `re` is never used (staticcheck)
	re, err = clt.Get(context.Background(), clt.Endpoint("webapi", "sites"), url.Values{})
	^
lib/web/apiserver_test.go:1192:2: SA4006: this value of `err` is never used (staticcheck)
	data, err := json.Marshal(auth.ChangePasswordWithTokenRequest{
	^
lib/web/apiserver_test.go:1206:2: SA4006: this value of `err` is never used (staticcheck)
	re, err = clt.Client.RoundTrip(func() (*http.Response, error) {
	^
lib/web/apiserver_test.go:1246:2: SA4006: this value of `err` is never used (staticcheck)
	data, err := json.Marshal(auth.ChangePasswordWithTokenRequest{
	^
lib/web/apiserver_test.go:1260:2: SA4006: this value of `err` is never used (staticcheck)
	re, err = clt.Client.RoundTrip(func() (*http.Response, error) {
	^
lib/web/static_test.go:93:2: SA4006: this value of `n` is never used (staticcheck)
	n, err = f.Seek(-50, io.SeekEnd)
	^
lib/web/static_test.go:100:2: SA4006: this value of `n` is never used (staticcheck)
	n, err = f.Seek(-50, io.SeekCurrent)
	^
```
2020-04-28 15:17:44 +00:00
Andrew Lytvynov 1755824b9f Add nil checks to TeleportClient.localAgent usages
`localAgent` can be nil if `Config.SkipLocalAuth` was set (such as when
passing `-i` flag to `tsh`). Several places in client code didn't handle
missing `localAgent` causing nil pointer panics.

Fixes #3032
2020-04-24 20:07:49 +00:00
Andrew Lytvynov a6994db3f8 Make sure all needed credentials are present in kubeconfig.Update
If TLS client key/cert or CA cert are missing, the kubeconfig ends up
generated successfully, but with those fields empty. For a user, this
looks like a successful `tsh login` with `kubectl` not working
afterwards with cryptic x509 errors.

We should always have the necessary fields provided. If not, `tsh login`
should say exactly what was missing.
2020-04-24 18:07:20 +00:00
Andrew Lytvynov 64edb20ea1 Load trusted TLS CA with keys in local keystore
Local keystore records trusted TLS CA certs in `<host>/certs.pem`.
When loading client.Key, also load the TLS CA cert for
`key.TrustedCertificates` field.

Without this field, `kubeconfig.Update` called by tsh can't populate the
CA cert in kubeconfig, which causes x509 validation errors with kubectl.
2020-04-24 18:07:20 +00:00
Andrew Lytvynov 2dc8690e9a Add --k8s-users flag to tctl users add
This allows users to be provided with k8s usernames, in addition to
groups. Default this flag to local login, same as for SSH logins.
2020-04-24 16:23:18 +00:00
Andrew Lytvynov 3f9b14b5f7 Add internal.kubernetes_users to kubernetes_users on admin role
With OSS version and without using the github connector (only local
auth), logged in user won't have any `kubernetes_groups`. Without
usernames too, user can login but can't use kubectl.
2020-04-24 16:23:18 +00:00
Andrew Lytvynov 7ccdd87496 Enable more Go linters: varcheck,bodyclose,structcheck
All changes should be noop, except for
`integration/integration_test.go`.

The integration test was ignoring `recordingMode` test case parameter
and always used `RecordAtNode`. When switching to `recordingMode`, test
cases with `RecordAtProxy` fail with a confusing error about missing
user agent. Filed https://github.com/gravitational/teleport/issues/3606
to track that separately and unblock enabling `structcheck` linter.
2020-04-24 15:52:43 +00:00
Forrest Marshall c0c1aa063d support access-request update delegators 2020-04-23 14:57:09 -07:00
Forrest Marshall 4e9eed9ac0 cache event fanout & reversetunnel improvements
- cache now perforams in-memory fanout of events, eliminating
spurious event generation due to cache init/reset.

- removed old unused logic from reversetunnel agents.

- replaced seekpool with simpler ttl-cache and semaphore-like
lease system.

- add jittered backoff to agent connection attempts to
reduce "thundering herd" effect.

- improved reversetunnel logging.

- improved LB usage in tests.
2020-04-23 14:03:52 -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
Andrew Lytvynov 64b11dd5ab Prevent nil pointer panic on node shutdown
If node hasn't fully initialized before getting stopped (such as when
join token isn't valid), most pointer vars in `initSSH` will be nil.
Handle that cleanly.
2020-04-23 20:09:35 +00:00
Andrew Lytvynov a7d9a03a09 Improve error messages for trusted cluster updates
Trusted cluster objects need to be re-created for most updates other
than enable/disable. Suggest that via error messages to the user.

Fixes #2998
2020-04-23 17:04:23 +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 84af6958fc Extract identity file formatting/parsing into a package
Identity file formatting (former `client.MakeIdentityFile`) will soon
support writing a `kubeconfig` file.

`lib/kube/kubeconfig` depends on `lib/client`, if calls to
`kubeconfig.Update` were added to `client.MakeIdentityFile`, we'd have
an import cycle:
tool/tctl -> lib/client -> lib/kube/kubeconfig -> lib/client

To break the cycle, I extract the identity file formatting (and parsing)
code into a standalone package. It's logically isolated functionality
anyway.

Now the imports will be:
tool/tctl┬─> lib/client
         ├─> lib/kube/kubeconfig ─> lib/client
         ╰─> lib/client/identity ┬─> lib/client
                                 ╰─> lib/kube/kubeconfig -> lib/client
2020-04-21 23:12:38 +00:00
Andrew Lytvynov 97908e2885 Report actual files written by client.MakeIdentityFile
The path passed in is used as a base, different output formats generate
different file sets based on it. To make things less confusing, return
the list of filepaths written and report it to the user.
2020-04-21 23:12:38 +00:00
Andrew Lytvynov df535f50a0 Refactor lib/kube/client
- rename package from `client` to `kubeconfig` and remove "kubeconfig"
  from function names
  (https://github.com/golang/go/wiki/CodeReviewComments#package-names)
- export `Update` and `UpdateWithClient` to allow updates without
  building a full `TeleportClient`
- accept an optional user-specified path to kubeconfig, to bind to CLI
  flags
2020-04-21 19:51:52 +00:00
Andrew Lytvynov f0ee948050 Use k8s-provided tls.Config constructor
`rest.TLSConfigFor` helper function exists to create `tls.Config` from
`rest.Config` (which represents `kubeconfig` essentially).

This commit uses the `rest.TLSConfigFor` helper from k8s packages
instead of doing manual conversion.

The previous code here re-implemented this logic, missing several parts:
- `CertFile`/`KeyFile` not supported, only `CertData`/`KeyData`
- `AuthProvider`/`ExecProvider` not supported
- `Insecure` not supported
- `ServerName` not verified

Effectively, this meant that a teleport proxy provided with kubeconfig
would only use a subset of authentication options.

Side note: the forwarder code should offload even more transport and
auth concerns to k8s libraries. Handling things like bearer tokens
shouldn't be our job.
2020-04-21 17:15:15 +00:00
Andrew Lytvynov 4c51cd4f46 Fix a data race in reversetunnel.AgentPool
`AgentPool.Counts` was accessing the agents map without holding the
lock. All access to the map must happen under a lock.
2020-04-17 20:05:38 +00:00
Andrew Lytvynov be8d931877 Fix a data race in utils.SyncBuffer
`SyncBuffer` has a goroutine running `io.Copy` to read from the
underlying pipe. Close stops the pipe, but doesn't wait for the last
chunk of data to be written by `io.Copy` to the buffer.

Both `Bytes` and `String` assume that the buffer received no further
writes after `Close`.

Add explicit synchronization between `io.Copy` goroutine and `Close`.
2020-04-17 20:05:38 +00: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 c5ca671d67 Emit node hostname as part of session.end event (#3595)
* Test active Session fields are populated
2020-04-16 17:14:47 -07: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
Andrew Lytvynov 8c75759b98 Add unit tests for kubeconfig updates
Several tests to confirm correctness of kubeconfig update logic.
Specifically - to make sure existing configuration is not deleted.

`UpdateKubeconfig` was split into two functions because mocking
`*client.TeleportClient` was really difficult.

Fixes #3209
2020-04-16 17:21:02 +00:00
Andrew Lytvynov 12952b4904 Set PDEATHSIG to SIGKILL on child processes after reexec
To execute an SSH command, Teleport re-executes itself and execs the
command from this child process:
  teleport -> teleport exec -> sh -c "user command"

Both parent teleport processes could exit unexpectedly (from SIGKILL or
even connection interruption).

Make sure all child processes get cleaned up and not orphaned to PID 1:
- teleport exec via SIGQUIT to request graceful shutdown
- user command via SIGKILL because it might ignore other signals
2020-04-16 16:56:22 +00: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
Forrest Marshall 924fb9cd00 synchronize bpf watch map reads 2020-04-01 11:41:44 -07:00