Commit graph

30 commits

Author SHA1 Message Date
Andrew Lytvynov d4247cb150
hsm: migrate CA storage schema (#7245)
* hsm: migrate CA storage schema

Migrate types.CertAuthorityV2 schema according to
https://github.com/gravitational/teleport/blob/master/rfd/0025-hsm.md#backend-storage

Includes proto changes, types.CertAuthority wrapper changes and data
migration.

Note that we keep and update the old fields for backwards-compatibility.
If a cluster is upgraded to v7 and then downgraded back to v6,
everything should keep working.

* Address review feedback
2021-06-16 12:17:03 -05:00
Roman Tkachenko a3837f6720
App access cli flow (#5918) 2021-03-22 09:18:53 -07:00
Alexander Klizhentas f17625c1a8
Adds controls for impersonation requests. (#6009) (#6073)
Fixes #5352

```yaml
allow:
  impersonate:
    users: ['alice', 'bob']
    roles: ['*']
    where: 'contains(user.spec.traits["groups"], impersonate_role.traits)'
```

Adds "impersonator" to all X.509 and SSH client certs
issued using impersonation and does best effort to track
requests by impersonators in audit events.

Limits certs TTL to the impersonator's max session TTL.

Prevents impersonating users to recursively impersonate
other users.

Allows impersonating users to renew their own certificate,
for example to set route to cluster.

Adds missing token permission for editor role.
2021-03-19 16:04:43 -07:00
Andrew Lytvynov 6d8f778157
mfa: add WithMFA to session-related audit events (#5833)
* mfa: put device UUID in MFAVerified cert extensions

Instead of just a bool, add the device UUID. This will be used in audit
events when a session is started using MFA-issued certs.

* Add WithMFA to session-related audit events

Also extract a common function for parsing SSH certs.
2021-03-04 14:18:30 -08:00
Acrimon cb701c4743 Refactor lib/asciitable, lib/tlsca, lib/shell, lib/session and lib/config tests to not use gocheck 2021-02-23 18:30:06 +01:00
Andrew Lytvynov 0f49d601a7
auth: API for requesting per-connection certificates (#5527)
* auth: API for requesting per-connection certificates

See https://github.com/gravitational/teleport/blob/master/rfd/0014-session-2FA.md#api

This API is a wrapper around GenerateUserCerts with a few differences:
- performs an MFA check before generating a cert
- enforces a single usage (ssh/k8s/db for now)
- embeds client IP in the cert
- marks a cert to distinguish from regular user certs
- enforces a 1min TTL

* Apply suggestions from code review

Co-authored-by: a-palchikov <deemok@gmail.com>

Co-authored-by: a-palchikov <deemok@gmail.com>
2021-02-10 20:29:00 -08:00
Brian Joerger 626ad243eb
api dependency reduction - utils constants (#5363)
Moved constants and utils used in /api into /api/constants and /api/utils respectively.
2021-01-29 09:37:01 -08:00
Brian Joerger c3e86f1696
Refactor API Dependencies - tlsca and gosaml2 (#5242) 2021-01-20 17:30:03 -08:00
Roman Tkachenko 8e1865464b
Database access (#5005) 2021-01-14 18:21:38 -08:00
Brian Joerger ab3d1a11da
Move /lib/wrappers to /api/types/wrappers. (#5286) 2021-01-14 14:58:44 -08:00
a-palchikov 6684c37103
Use fake clock consistently in units tests. (#5263)
Use fake clock consistently in units tests.
2021-01-12 12:10:00 +01:00
Andrew Lytvynov b16ad647b4
Kubernetes request routing and cluster registration (#4670)
This change has several parts: cluster registration, cache updates,
routing and a new tctl flag.

> cluster registration

Cluster registration means adding `KubernetesClusters` to `ServerSpec`
for servers with `KindKubeService`.

`kubernetes_service` instances will parse their kubeconfig or local
`kube_cluster_name` and add them to their `ServerSpec` sent to the auth
server. They are effectively declaring that "I can serve k8s requests
for k8s cluster X".

> cache updates

This is just cache plumbing for `kubernetes_service` presence, so that
other teleport processes can fetch all of kube services. It was missed
in the previous PR implementing CRUD for `kubernetes_service`.

> routing

Now the fun part - routing logic. This logic lives in
`/lib/kube/proxy/forwarder.go` and is shared by both `proxy_service`
(with kubernetes integration enabled) and `kubernetes_service`.

The target k8s cluster name is passed in the client cert, along with k8s
users/groups information.

`kubernetes_service` only serves requests for its direct k8s cluster
(from `Forwarder.creds`) and doesn't route requests to other teleport
instances.

`proxy_service` can serve requests:
- directly to a k8s cluster (the way it works pre-5.0)
- to a leaf teleport cluster (also same as pre-5.0, based on
  `RouteToCluster` field in the client cert)
- to a `kubernetes_service` (directly or over a tunnel)

The last two modes require the proxy to generate an ephemeral client TLS
cert to do an outbound mTLS connection.

> tctl flag

A flag `--kube-cluster-name` for `tctl auth sign --format=kubernetes`
which allows generating client certs for non-default k8s cluster name
(as long as it's registered in a cluster).
I used this for testing, but it could be used for automation too.
2020-11-09 19:40:02 +00:00
Russell Jones 904b0d0488 Added Application Access.
Added support for an identity aware, RBAC enforcing, mutually
authenticated, web application proxy to Teleport.

* Updated services.Server to support an application servers.
* Updated services.WebSession to support application sessions.
* Added CRUD RPCs for "AppServers".
* Added CRUD RPCs for "AppSessions".
* Added RBAC support using labels for applications.
* Added JWT signer as a services.CertAuthority type.
* Added support for signing and verifying JWT tokens.
* Refactored dynamic label and heartbeat code into standalone packages.
* Added application support to web proxies and new "app_service" to
  proxy mutually authenticated connections from proxy to an internal
  application.
2020-11-03 14:32:13 -08:00
Andrew Lytvynov 92ed2db38a Fixing golint warnings, batch 1
Mostly cosmetic changes:
- making receiver names consistent
- renaming `foo.FooBar` to `foo.Bar` (using package name as prefix)
- removing redundant `else` branches
- changing `a += 1` to `a++`
2020-10-13 00:22:49 +00:00
Andrew Lytvynov e095e30342 Add kubernetes cluster name to TLS certs
K8s cluster name is specified during login (for now) and gets plumbed to
a new extensions on the TLS cert. The name is validated against all
known k8s clusters reported via proxy heartbeats. If no name is
provided, the extension remains empty.

The name in the cert will get used by proxies for routing, once we fully
support multiple k8s clusters per teleport cluster.

This was tested with direct and github login flows.
2020-10-07 16:26:54 +00:00
Andrew Lytvynov 617afc7e6f Fix remaining gosimple findings
List of fixed items:

```
integration/helpers.go:1279:2               gosimple  S1000: should use for range instead of for { select {} }
integration/integration_test.go:144:5       gosimple  S1009: should omit nil check; len() for nil slices is defined as zero
integration/integration_test.go:173:5       gosimple  S1009: should omit nil check; len() for nil slices is defined as zero
integration/integration_test.go:296:28      gosimple  S1019: should use make(chan error) instead
integration/integration_test.go:570:41      gosimple  S1019: should use make(chan interface{}) instead
integration/integration_test.go:685:40      gosimple  S1019: should use make(chan interface{}) instead
integration/integration_test.go:759:33      gosimple  S1019: should use make(chan string) instead
lib/auth/init_test.go:62:2                  gosimple  S1021: should merge variable declaration with assignment on next line
lib/auth/tls_test.go:1658:22                gosimple  S1024: should use time.Until instead of t.Sub(time.Now())
lib/backend/dynamo/dynamodbbk.go:420:5      gosimple  S1004: should use !bytes.Equal(expected.Key, replaceWith.Key) instead
lib/backend/dynamo/dynamodbbk.go:656:12     gosimple  S1039: unnecessary use of fmt.Sprintf
lib/backend/etcdbk/etcd.go:458:5            gosimple  S1004: should use !bytes.Equal(expected.Key, replaceWith.Key) instead
lib/backend/firestore/firestorebk.go:407:5  gosimple  S1004: should use !bytes.Equal(expected.Key, replaceWith.Key) instead
lib/backend/lite/lite.go:317:5              gosimple  S1004: should use !bytes.Equal(expected.Key, replaceWith.Key) instead
lib/backend/lite/lite.go:336:6              gosimple  S1004: should use !bytes.Equal(value, expected.Value) instead
lib/backend/memory/memory.go:365:5          gosimple  S1004: should use !bytes.Equal(expected.Key, replaceWith.Key) instead
lib/backend/memory/memory.go:376:5          gosimple  S1004: should use !bytes.Equal(existingItem.Value, expected.Value) instead
lib/backend/test/suite.go:327:10            gosimple  S1024: should use time.Until instead of t.Sub(time.Now())
lib/client/api.go:1410:9                    gosimple  S1003: should use strings.ContainsRune(name, ':') instead
lib/client/api.go:2355:32                   gosimple  S1019: should use make([]ForwardedPort, len(spec)) instead
lib/client/keyagent_test.go:85:2            gosimple  S1021: should merge variable declaration with assignment on next line
lib/client/player.go:54:33                  gosimple  S1019: should use make(chan int) instead
lib/config/configuration.go:1024:52         gosimple  S1019: should use make(services.CommandLabels) instead
lib/config/configuration.go:1025:44         gosimple  S1019: should use make(map[string]string) instead
lib/config/configuration.go:930:21          gosimple  S1003: should use strings.Contains(clf.Roles, defaults.RoleNode) instead
lib/config/configuration.go:931:22          gosimple  S1003: should use strings.Contains(clf.Roles, defaults.RoleAuthService) instead
lib/config/configuration.go:932:23          gosimple  S1003: should use strings.Contains(clf.Roles, defaults.RoleProxy) instead
lib/service/supervisor.go:387:2             gosimple  S1001: should use copy() instead of a loop
lib/tlsca/parsegen.go:140:9                 gosimple  S1034: assigning the result of this type assertion to a variable (switch generalKey := generalKey.(type)) could eliminate type assertions in switch cases
lib/utils/certs.go:140:9                    gosimple  S1034: assigning the result of this type assertion to a variable (switch generalKey := generalKey.(type)) could eliminate type assertions in switch cases
lib/utils/certs.go:167:40                   gosimple  S1010: should omit second index in slice, s[a:len(s)] is identical to s[a:]
lib/utils/certs.go:204:5                    gosimple  S1004: should use !bytes.Equal(certificateChain[0].SubjectKeyId, certificateChain[0].AuthorityKeyId) instead
lib/utils/parse/parse.go:116:45             gosimple  S1003: should use strings.Contains(variable, "}}") instead
lib/utils/parse/parse.go:116:6              gosimple  S1003: should use strings.Contains(variable, "{{") instead
lib/utils/socks/socks.go:192:10             gosimple  S1025: should use String() instead of fmt.Sprintf
lib/utils/socks/socks.go:199:10             gosimple  S1025: should use String() instead of fmt.Sprintf
lib/web/apiserver.go:1054:18                gosimple  S1024: should use time.Until instead of t.Sub(time.Now())
lib/web/apiserver.go:1954:9                 gosimple  S1039: unnecessary use of fmt.Sprintf
tool/tsh/tsh.go:1193:14                     gosimple  S1024: should use time.Until instead of t.Sub(time.Now())
```
2020-05-27 19:36:38 +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 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
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
Russell Jones f0a455f2ea Use JSON for trait encoding. 2019-09-11 15:13:52 -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
Alexander Klizhentas 96b259348f
Use client cert metadata to route requests. (#2859)
This commit fixes issue #2766.

The prior logic in Kubernetes module used
SNI to route requests to the target kubernetes cluster.

This approach created problems with long cluster names
exceeding 61 character DNS label limit and
required setting up DNS wildcard records.

This commit changes the routing to use the metadata
encoded in client's x509 certificate to route the
request to the target cluster.

SNI approach will be supported for several versions
to preserve backwards compatibility.
2019-07-15 17:40:43 -07:00
Russell Jones ae074ede36 Always validate certificate (or key) algorithm.
Added utils.CertChecker that wraps a ssh.CertChecker. The new
certificate checker first checks if the certificate is a valid
certificate for Teleport. At the moment that is 2048-bit RSA then calls
the underlying certificate checker to perform the requested validation.
2019-03-19 17:47:53 -07:00
Roman Tkachenko 318102c2f8
Sort out principals into DNS names and IP addresses. (#2522) 2019-01-23 15:53:59 -08:00
Alexander Klizhentas fc0566a24f
Sasha/forward ports (#2491)
* Fetch groups for GSuite SSO. (#2456)

Fixes #2455

This commit adds support for fetching
groups for GSuite SSO logins via
OIDC connector interface.

If OIDC connector has a special scope:

`https://www.googleapis.com/auth/admin.directory.group.readonly`

teleport will fetch user's group membership and populate
groups claim.

* Pass kubernetes groups to the remote cluster. (#2484)

This commit allows remote cluster to reference
the kubernetes groups coming from the roles
of the main cluster in the trusted clusters
configuration.

For example, main cluster can have a user
with a role 'main' and kubernetes groups:

kube_groups: ['system:masters']

and SSH logins:

logins: ['root']

Remote cluster can choose to map
this 'main' cluster to it's own:
'remote-admin' cluster in the trusted cluster config:

role_map:
  - remote: 'main'
    local: 'remote-admin'

The role 'remote-admin' of the remote cluster
can now be templated to use the main cluster role main
logins and kubernetes_groups using variables:

logins: ['{{internal.logins}}']
kubernetes_groups: ['{{internal.kubernetes_groups}}']

This is possible because teleport now encodes
both values in X509 certificate metadata
and remote cluster passes these values as 'internal' traits
to the template engine.
2019-01-16 18:55:59 -08:00
Russell Jones e69e67e372 Add support for CA pinning when joining a cluster. 2018-10-15 16:44:27 -07:00
Sasha Klizhentas dca65a5234 Move keypair generation from auth server.
When many nodes join the cluster or rotate certificates,
auth server was forced to generate may private/public
key pairs simultaneosly creating bottleneck
on the auth server side.

This commit pushes the private public key generation
logic back to clients releiving the pressure from
auth server.
2018-09-05 17:48:45 -07:00
Russell Jones d0b638802c Include list of principal into x509 certificate. This allows the
creating a remote user with valid logins (applied from traits) and
roles.
2018-08-27 18:27:16 -07:00
Sasha Klizhentas 66fa34bcde Add framework for trusted cluster K8s access 2018-06-22 12:56:58 -07:00
Sasha Klizhentas 0130c6aa41 Mutual TLS Auth server and clients.
This commit introduced mutual TLS authentication
for auth server API server.

Auth server multiplexes HTTP over SSH - existing
protocol and HTTP over TLS - new protocol
on the same listening socket.

Nodes and users authenticate with 2.5.0 Teleport
using TLS mutual TLS except backwards-compatibility
cases.
2017-12-27 11:37:19 -08:00