Commit graph

247 commits

Author SHA1 Message Date
Andrew Lytvynov cd2f4fceb7
Remove JSON schema validation (#6685)
* Remove JSON schema validation

Removing JSON schema validation from all resource unmarshalers.

--- what JSON schema gets us

Looking at the JSON schema spec and our usage, here are the supposed benefits:
- type validation - make sure incoming data uses the right types for the right fields
- required fields - make sure that mandatory fields are set
- defaulting - set defaults for fields
- documentation - schema definition for our API objects

Note that it does _not_ do:
- fail on unknown fields in data
- fail on a required field with an empty value

--- what replaces it

Based on the above, it may seem like JSON schema provides value.
But it's not the case, let's break it down one by one:
- type validation - unmarshaling JSON into a typed Go struct does this
- required fields - only checks that the field was provided, doesn't actually check that a value is set (e.g. `"name": ""` will pass the `required` check)
  - so it's pretty useless for any real validation
  - and we already have a separate place for proper validation - `CheckAndSetDefaults` methods
- defaulting - done in `CheckAndSetDefaults` methods
  - `Version` is the only annoying field, had to add it in a bunch of objects
- documentation - protobuf definitions are the source of truth for our API schema

--- the benefits

- performance - schema validation does a few rounds of `json.Marshal/Unmarshal` in addition to actual validation; now we simply skip all that
- maintenance - no need to keep protobuf and JSON schema definitions in sync anymore
- creating new API objects - one error-prone step removed
- (future) fewer dependencies - we can _almost_ remove the Go libraries for schema validation (one transient dependency keeping them around)

* Remove services.SkipValidation

No more JSON schema validation so this option is a noop.
2021-06-01 15:27:20 -07:00
Marek Smoliński eb7bb01d34
Support disconnect_expired_cert for database access (#6857) 2021-05-31 10:26:50 +02:00
Brian Joerger 5fbffaab80
keypaths package (#6848) 2021-05-27 10:31:05 -07:00
Trent Clarke d710424ae7
Ports some integration tests to Testify/Subtests (#6884)
In an attempt to make it easier to
 1) navigate the integration test output,
 2) find the cause of test failures, and
 3) run individual tests, make it easier to run individual
    integration tests from the command line,

...this change ports some of the OSS integration tests away from
GoCheck and implements them in terms of the standard `testing`
package.

The main changes are:
 * Test suites are now constructed as a normal Test function
   with many subtests.
 * The GoCheck assertions have been replaced with equivalent
   assertions from `testify/require`, for example:
     `c.Assert(err, check.IsNil)`
   becomes
     `require.NoError(t, err)`

   ... and so on
2021-05-26 19:05:46 -07:00
Nic Klaassen f268ba173e
Stop registering a Kubernetes cluster named after the Teleport cluster (#6786) 2021-05-25 17:50:35 -07:00
Andrej Tokarčík 555695dfdd
Introduce SessionRecordingConfig extracting fields from ClusterConfig (#6708) 2021-05-19 12:01:37 -07:00
a-palchikov ee6e2c85d8
AuditLog/grpc server data race (#6170)
* Avoid test flake by ensuring the gRPC server is shutdown gracefully before closing the audit log

* Fix lint warnings. Nove tunnel server's Close to earlier to close the proxy watcher and release grpc traffic

* Use graceful shutdown selectively until all tests have improved support for it

* Move session recorder clean up to session.Close

* Always use graceful shutdown for TLS.
2021-05-18 17:57:57 -07:00
Joel b68c519b4c
Implement RFD 19: Event Iteration API (#6731) 2021-05-18 16:46:01 +02:00
Andrej Tokarčík ad00c6c789
Introduce ClusterNetworkingConfig extracting fields from ClusterConfig (#6638) 2021-05-07 13:54:08 +02:00
Trent Clarke 769b4b5eec
Implements RFD-0022 - OpenSSH-compatible Agent Forwarding (#6525)
Prior to this change, `tsh` will only ever forward the internal key
agent managed by `tsh` to a remote machine.

This change allows a user to specify that `tsh` should forward either
the `tsh`-internal keystore, or the system key agent at `$SSH_AUTH_SOCK`.

This change also brings the `-A` command-line option into line with
OpenSSH.

For more info refer to RFD-0022.

See-Also: #1571
2021-05-06 17:17:50 -07:00
Roman Tkachenko db6fb57dae
Add app access headers rewrite (#6601) 2021-05-06 11:24:49 -07:00
Roman Tkachenko 7f01f2d4b6
Propagate external traits to leaf clusters (#6540) 2021-04-29 09:39:43 -07:00
Brian Joerger 9def18cb9f
gRPC conversions - Nodes (#6535) 2021-04-28 18:27:12 -07:00
Andrej Tokarčík 8e5ff95014
Provide a dedicated API endpoint for app FQDN resolving (#6449)
Currently, an app's target FQDN can be obtained only using the endpoint
for creating new app sessions.  The OAuth-style back-and-forth redirects
between the app launcher and the app itself are therefore forced to
generate an unnecessary additional app session just to resolve the FQDN.

The new endpoint introduced here allows to resolve such FQDNs by
invoking a dedicated endpoint.
2021-04-26 13:31:56 -07:00
Andrew Lytvynov 5265688fc8 Revert "Node session race (#6195)"
This reverts commit 4acf50902c.
2021-04-26 17:24:06 +00:00
a-palchikov 4acf50902c
Node session race (#6195)
* Attempt to isolate and improve state handling of a NodeSession.

* Add terminal close for kube terminal tests

* Address review comments

* Small tweaks

Co-authored-by: Andrew Lytvynov <andrew@goteleport.com>
2021-04-22 17:16:28 -07:00
Brian Joerger d830ed6db7
Refactor api package and docs to use pkg.go.dev effectively. (#6388) 2021-04-20 16:44:17 -07:00
a-palchikov d5bc20bf95
Implement alternative reverse tunnel address support and add a test case. (#6056) 2021-04-15 12:11:48 -07:00
xacrimon 3f9f33408d add PAM environment with interpolation support 2021-03-30 18:23:38 +02:00
Andrej Tokarčík 52dfeec63e
Cache per-cluster SSH certificates under ~/.tsh (#5938)
```diff
 ~/.tsh/
 └── keys
    ├── one.example.com            --> Proxy hostname
    │   ├── certs.pem              --> TLS CA certs for the Teleport CA
    │   ├── foo                    --> RSA Private Key for user "foo"
    │   ├── foo.pub                --> Public Key
-   │   ├── foo-cert.pub           --> SSH certificate for proxies and nodes
    │   ├── foo-x509.pem           --> TLS client certificate for Auth Server
+   │   ├── foo-ssh                --> SSH certs for user "foo"
+   │   │   ├── root-cert.pub      --> SSH cert for Teleport cluster "root"
+   │   │   └── leaf-cert.pub      --> SSH cert for Teleport cluster "leaf"
```

When `-J` is provided, this also loads/reissues the SSH cert for the cluster associated with the jumphost's certificate. Fixes #5637.
2021-03-29 14:14:31 -07:00
Brian Joerger 4398797f14
Pass context through new gRPC converted endpoints. (#6118) 2021-03-23 18:26:52 -07:00
Brian Joerger 32c4ae255f
Add Credential loader support for tsh profiles. (#5993) 2021-03-23 16:35:42 -07:00
Roman Tkachenko a3837f6720
App access cli flow (#5918) 2021-03-22 09:18:53 -07:00
Roman Tkachenko b2ff4df8fa
Fix app access websockets support (#6072) 2021-03-22 08:56:44 -07:00
Andrew Lytvynov 3d02ae6279
mfa: per-session MFA certs for SSH and Kubernetes (#5564)
* mfa: per-session MFA certs for SSH and Kubernetes

This is client-side support for requesting single-use certs with an MFA
check.

The client doesn't know whether they need MFA check when accessing a
resource, this is decided during an RBAC check on the server. So a
client will always try to get a single-use cert, and the server will
respond with NotNeeded if MFA is not required. This is an extra
round-trip for every session which causes ~20% slowdown in SSH logins:

```
$ hyperfine '/tmp/tsh-old ssh talos date' '/tmp/tsh-new ssh talos date'
Benchmark #1: /tmp/tsh-old ssh talos date
  Time (mean ± σ):      49.9 ms ±   1.0 ms    [User: 15.1 ms, System: 7.4 ms]
  Range (min … max):    48.4 ms …  54.1 ms    59 runs

Benchmark #2: /tmp/tsh-new ssh talos date
  Time (mean ± σ):      60.2 ms ±   1.6 ms    [User: 19.1 ms, System: 8.3 ms]
  Range (min … max):    59.0 ms …  69.7 ms    50 runs

  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet PC without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Summary
  '/tmp/tsh-old ssh talos date' ran
    1.21 ± 0.04 times faster than '/tmp/tsh-new ssh talos date'
```

Another few other internal changes:

- client.LocalKeyAgent will now always have a non-nil LocalKeyStore.
  Previously, it would be nil (e.g. in a web UI handler or when using an
  identity file) which easily causes panics. I added a noLocalKeyStore
  type instead that returns errors from all methods.

- requesting a user cert with a TTL < 1min will now succeed and return a
  1min cert instead of failing

* Capture access approvals on MFA-issued certs

* Address review feedback

* Address review feedback

* mfa: accept unknown nodes during short-term MFA cert creation

An unknown node could be an OpenSSH node set up via
https://goteleport.com/teleport/docs/openssh-teleport/

In this case, we shouldn't prevent the user from connecting.

There's a small risk of authz bypass - an attacker might know a
different name/IP for a registered node which Teleport doesn't know
about. But a Teleport node will still check RBAC and reject the
connection.

* Validate username against unmapped user identity

IssueUserCertsWithMFA is called on the leaf auth server in case of
trusted clusters. Username in the request object will be that of the
original unmapped caller.

* mfa: add IsMFARequired RPC

This RPC is ran before every connection to check whether MFA is
required. If a connection is against the leaf cluster, this request is
forwarded from root to leaf for evaluation.

* Fix integration tests

* Correctly treat "Username" as login name in IsMFARequired

Also, move the logic into auth.Server out of ServerWithRoles.

* Fix TestHA

* Address review feedback
2021-03-10 15:42:16 -08:00
Roman Tkachenko 3dd86eba3f
Fix --insecure-no-tls flag (#5924) 2021-03-10 07:42:23 -08:00
Andrej Tokarčík a7f3a05e53 Fix AAP headers injection 2021-03-01 22:14:10 +01:00
Acrimon e9f90cb049 utmp fix for symlinked path 2021-02-25 20:50:30 +01:00
Andrew Lytvynov fc1c1dbd14 Move all utils.InitLoggerForTests calls to TestMain
This prevents data races between changing the standard logger and it
acutally being used.
2021-02-23 18:04:55 -08:00
Jane Quintero c841f2e8dd add test for exec events 2021-02-19 20:15:20 -08:00
Jane Quintero c50133bfcf remove integration testing and use already implemented emitting exec events function 2021-02-19 20:15:20 -08:00
Jane Quintero cbf7f7bb7c emit exec event even if PTY is allocated 2021-02-19 20:15:20 -08:00
Andrew Lytvynov 6ae441a541
Verify access to a remote cluster on GenerateUserCerts (#5593)
Cluster labels were added in 5.0 to restrict access to trusted clusters.
Enforce this restriction on `tsh login leafName` (aka `GenerateUserCerts`).

Note: access check is already enforced on actual user connections
(ssh/k8s/etc) and listing of trusted clusters (`tsh clusters`). You
cannot bypass authz to actually connect to that cluster.
2021-02-17 16:13:32 -08:00
Acrimon 324ccda21f Implemented utmp/wtmp support. 2021-02-15 20:58:30 +01:00
Roman Tkachenko 8dcfbfc5f0
Add mysql functional/integration tests (#5472) 2021-02-12 15:09:26 -08: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 efe91c4def
api dependency reduction - ssh (#5379)
Move Cert Authority methods out of api to remove dependency on crypto/ssh.
2021-01-29 10:28:24 -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 3c3ce160d9
Move API types and functionality from lib/services to api/types. (#5143) 2021-01-11 10:02:34 -08:00
a-palchikov 7c87576a8b
flaky tests: consistent logging (#4849)
* Update logrus package to fix data races
* Introduce a logger that uses the test context to log the messages so they are output if a test fails for improved trouble-shooting.
* Revert introduction of test logger - simply leave logger configuration at debug level outputting to stderr during tests.
* Run integration test for e as well
* Use make with a cap and append to only copy the relevant roles.
* Address review comments
* Update integration test suite to use test-local logger that would only output logs iff a specific test has failed - no logs from other test cases will be output.
* Revert changes to InitLoggerForTests API
* Create a new logger instance when applying defaults or merging with file service configuration
* Introduce a local logger interface to be able to test file configuration merge.
* Fix kube integration tests w.r.t log
* Move goroutine profile dump into a separate func to handle parameters consistently for all invocations
2020-12-07 15:35:15 +01:00
Russell Jones 898088a282 Fixed application dialing in proxy recording mode.
Only use the forwarded agent when dialing in proxy recording mode when
the connection type is SSH.
2020-11-17 17:57:00 -08:00
Russell Jones f13040a433 Added integration tests for Application Access. 2020-11-12 18:01:45 -08: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
Sasha Klizhentas c623aa4dc5 Add cluster labels
Fixes #3604

This commit adds support for cluster_labels
role parameter limiting access to remote clusters by label.
New tctl update rc provides interface to set labels on remote clusters.

Consider two clusers, `one` - root and `remote` - leaf.

```bash
$ tsh clusters
Cluster Name Status
------------ ------
one          online
two          online
```

Create the trusted cluster join token with labels:

```bash
$ tctl tokens add --type=trusted_cluster --labels=env=prod
```

Every cluster joined using this token will inherit env:prod labels.

Alternatively, update remote cluster labels by modifying
`rc` command. Letting remote clusters to propagate their labels
creates a problem of rogue clusters updating their labels to bad values.

Instead, administrator of root cluster control the labels
using remote clusters API without fear of override:

```bash
$ tctl get rc

kind: remote_cluster
metadata:
  name: two
status:
  connection: online
  last_heartbeat: "2020-09-14T03:13:59.35518164Z"
version: v3
```

```bash
$ tctl update rc/two --set-labels=env=prod

cluster two has been updated
```

```bash
$ tctl get rc
kind: remote_cluster
metadata:
  labels:
    env: prod
  name: two
status:
  connection: online
  last_heartbeat: "2020-09-14T03:13:59.35518164Z"
```

Update the role to deny access to prod env:

```yaml
kind: role
metadata:
  name: dev
spec:
  allow:
    logins: [root]
    node_labels:
      '*': '*'

    # Cluster labels control what clusters user can connect to. The wildcard ('*') means
    # any cluster. If no role in the role set is using labels and cluster is not labeled,
    # the cluster labels check is not applied. Otherwise, cluster labels are always enforced.
    # This makes the feature backwards-compatible.
    cluster_labels:
      'env': 'staging'
  deny:
    # cluster labels control what clusters user can connect to. The wildcard ('*') means
    # any cluster. By default none is set in deny rules to preserve backwards compatibility
    cluster_labels:
      'env': 'prod'
```

```bash
$ tctl create -f dev.yaml
```

Cluster two is now invisible to user with `dev` role.

```bash
$ tsh clusters
Cluster Name Status
------------ ------
one          online
```
2020-11-03 16:10:15 -08: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
Russell Jones d9c6119a14 Fixed PAM integration tests. 2020-10-16 17:36:19 -07: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 c0335d4f6f Reduce the necessary k8s permissions for integration tests
Previously, we needed:
- create on namespaces
- impersonate on all users/groups/service accounts
- list pods in kube-system namespace (via teleport-ci-test-group)
- exec/portforward on kube-dns pod in kube-system namespace (via teleport-ci-test-group)

Now, we need:
- create on namespaces
- create on pods in namespace teletest
- impersonate on all users/groups
- get/exec/portforward on pod test-pod in namespace teletest (via teleport-ci-test-group)

Unfortunately, `resourceNames` in RBAC doesn't work with `create` verbs,
so we can't scope down impersonation to just the right users/groups.
2020-10-08 20:59:00 +00:00
Gus Luxton 4edf2355ef
Run k8s integration tests in Drone (#4437) 2020-10-07 18:01:33 -03:00