Skip to content

Commit

Permalink
[Backport v8] Create a blast radius reduction guide (#9430)
Browse files Browse the repository at this point in the history
* Create a blast radius reduction guide

This is the first guide within the "Security" subsection within
the "Setup" section of the docs site.

Closes #9055

* Respond to PR feedback
  • Loading branch information
ptgott authored Dec 16, 2021
1 parent 63fcd50 commit 45c4540
Show file tree
Hide file tree
Showing 3 changed files with 294 additions and 0 deletions.
7 changes: 7 additions & 0 deletions docs/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@
{ "title": "TLS Routing Migration", "slug": "/setup/operations/tls-routing/" }
]
},
{
"title": "Security",
"slug": "/setup/security/",
"entries":[
{"title": "Reducing the Blast Radius of Attacks", "slug": "/setup/security/reduce-blast-radius/"}
]
},
{
"title": "Integrations",
"slug": "/setup/guides/",
Expand Down
11 changes: 11 additions & 0 deletions docs/pages/setup/security.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
title: Security
description: Hardening the security of your Teleport deployment
layout: tocless-doc
---

<ul>
<li>
[Reducing the blast radius of attacks](./security/reduce-blast-radius.mdx). Prevent attackers from accessing your infrastructure even if they manage to obtain passwords or certificates.
</li>
</ul>
276 changes: 276 additions & 0 deletions docs/pages/setup/security/reduce-blast-radius.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
---
title: Reducing the Blast Radius of Attacks
description: How to configure Teleport to minimize the scope of security breaches
---

Teleport encourages users to practice defense in depth so that every component of their infrastructure is safe against attacks, even if an attacker is partially successful. You can configure Teleport to add layers of protection to your cluster when users authenticate or request elevated privileges. In this guide, we will show you how to:

- [Make MFA mandatory for `tsh` logins](#make-mfa-mandatory-for-tsh-login)
- [Present an MFA challenge for every attempt to access a resource](#present-an-mfa-challenge-for-every-attempt-to-access-a-resource)
- [Require dual authorization for role requests](#require-dual-authorization-for-role-requests)
- [Automatically prevent some roles from requesting others](#automatically-prevent-some-roles-from-requesting-others)
- [Restrict role requests based on user traits](#restrict-role-requests-based-on-user-traits)
- [Set up your RBAC without admin roles](#set-up-your-rbac-without-admin-roles)

## Make MFA mandatory for `tsh login`
If a user sets up an account to authenticate to their Teleport cluster with only a password, an adversary can gain access to the password using brute-force attacks, person-in-the-middle attacks, or phishing. But even if a user's password is compromised, you can stop an attacker from authenticating with it when they run `tsh login`.

Teleport lets you make it mandatory for a user to enroll an MFA device when they create an account, and to authenticate using that device when they begin a new Teleport session.

To do so, make the following changes depending on your environment:

<Tabs>
<TabItem label="Self-hosted" scope={["oss","enterprise"]}>
Add the following to your Teleport configuration file:

```yaml
auth_service:
authentication:
second_factor: otp|u2f|webauthn|on
```
</TabItem>
<TabItem label="Teleport Cloud" scope={["cloud"]}>
Create the following `cluster_auth_preference` dynamic resource:

```yaml
kind: cluster_auth_preference
version: v2
metadata:
name: cluster-auth-preference
spec:
second_factor: otp|u2f|webauthn|on
```

Create your dynamic resource using `tctl create -f <path to your YAML file>`.
</TabItem>
</Tabs>

To make MFA mandatory for all users, `second_factor` must be set to one of the following values:

- `otp`
- `u2f`
- `webauthn`
- `on`

Choose `on` if you would like to require MFA for all users while letting them choose an OTP, U2F, or WebAuthn device. The other options restrict users to a single type of MFA device, which is useful for enforcing a particular standard of security. Once you start the Teleport Proxy Service with the `second_factor` configuration option set to one of these values, Teleport will mandate MFA by:

- Adjusting the Teleport signup page so a user must enroll an MFA device of the kind you have selected. If the value of `second_factor` is `on`, users will have the option to select from multiple device types.
- Presenting the user with an MFA challenge when they run `tsh login`.

If you have enabled SSO in your Teleport environment, Teleport will conduct its own MFA challenge before sending a request to the identity provider. This means that, even if an attacker has managed to compromise your organization's SSO provider (e.g., by impersonating an administrator), a malicious user will still need to authenticate using valid credentials.

<Admonition type="warning">
If your `second_factor` configuration is set to `off` and a user creates an account without a second factor, changing `second_factor` to a value that requires MFA will force that user to authenticate with a credential they have not registered. This will lock them out of their account. You have two ways to avoid this scenario:
- Set `second_factor` to `optional` until you have confirmed that existing users have enrolled their MFA devices.
- Run the `tctl users reset <account>` command to force a user to enter new credentials, including any required MFA device.
</Admonition>


## Present an MFA challenge for every attempt to access a resource
After a user logs into a Teleport cluster, they can request access to a particular resource, e.g., a node, database, application, or Kubernetes cluster. In this case, the Teleport Auth Service issues a single-use certificate for accessing that resource. You can prevent attackers from doing damage with a compromised certificate by enabling per-session MFA. With this setting, whenever a user requests a one-time certificate to access a resource, the Teleport Auth Service will issue an MFA challenge, even if the user has already begun a Teleport session via `tsh login`.

To enable per-session MFA for all users, do the following depending on your Teleport environment:

<Tabs>
<TabItem label="Self-hosted" scope={["oss","enterprise"]}>
Make the following changes to your Teleport configuration file:

```yaml
auth_service:
authentication:
require_session_mfa: yes
```
</TabItem>
<TabItem label="Teleport Cloud" scope={["cloud"]}>
Create the following `cluster_auth_preference` dynamic resource:

```yaml
kind: cluster_auth_preference
version: v2
metadata:
name: cluster-auth-preference
spec:
require_session_mfa: yes
```

Create your dynamic resource using `tctl create -f <path to your YAML file>`.
</TabItem>
</Tabs>

## Require dual authorization for role requests
Even if an attacker gains access to a user's credentials and successfully signs into your Teleport cluster, you can still prevent the user from escalating their privileges. If you enable dual authorization, users who request to assume a particular role must obtain permission to do so from two or more reviewers. This way, if a malicous user manages to impersonate a legitimate one, reviewers can contact the real user before granting the new role.

Dual authorization uses Teleport's access plugins—e.g., Slack, JIRA, and PagerDuty—to notify reviewers that a user has requested a role. For access plugins that require a SAML or OIDC connector, you must enable the Cloud or Enterprise versions of Teleport.

You can set up dual authorization by applying two dynamic resources:

- [The reviewer](#the-reviewer)
- [The reviewee](#the-reviewee)

### The reviewer
You can enable some users to review other users' role escalation requests by applying a dynamic resource similar to the following:

```yaml
kind: role
version: v4
metadata:
name: reviewer
spec:
allow:
review_requests:
roles: ["role-one", "role-two", "role-three"]
```

Assign `spec.allow.review_requests.roles` to a list of role names. When a user requests access to one of the roles listed in `spec.allow.review_requests.roles`, your Teleport access plugins notify users with the `reviewer` role of the request and relay the responses to your Teleport cluster.

### The reviewee
You can require a user to request access from reviewers by applying a dynamic resource similar to the following:

```yaml
kind: role
version: v4
metadata:
name: reviewee
spec:
allow:
request:
roles: ["role-one", "role-two", "role-three"]
thresholds:
- approve: 2
deny: 1
```

The `spec.allow.request.roles` field lists the names of other roles that a user with the `reviewee` role can request. When a reviewee requests access to one of these roles, Teleport notifies reviewers via your access plugins. The `spec.allow.requests.roles.thresholds` field indicates how many reviews are required to approve or deny the request.


## Automatically prevent some roles from requesting others
A malicious Teleport user could request a more privileged role and trick a reviewer into granting access. You can prevent such a scenario by defining roles that prohibit users from even requesting access to particular roles.

The `spec.deny` field has the same possible properties as the `spec.allow` field we described [earlier](#require-dual-authorization-for-role-requests) except, rather than enabling actions, this field disables them. For example, the `spec.deny.requests.roles` field is a list of roles that a user is prohibited from requesting. Teleport gives `deny` rules precedence over `allow` rules when executing access requests.

As an illustration, we have assigned user `myuser` to the `user` role, which we defined using the following template:

```yaml
kind: role
version: v4
metadata:
name: user
spec:
deny:
request:
roles: ['admin']
```

Next, `myuser` attempts to request the `admin` role.

```code
$ tsh request create --roles=admin
```

However, the Auth Service denies the request.

```code
Creating request...
ERROR: user "myuser" can not request role "admin"
```


## Restrict role requests based on user traits
Teleport's `role` resource lets you take precautions against accidental privilege escalation by ensuring that any user with particular attributes will have restricted access to certain roles. You can assign a list of `traits` to a user, then define a `role` resource that prevents any user whose traits match a regular expression from requesting elevated privileges.

A user has the same traits regardless of the roles they acquire. As a result, if a user happens to obtain another role because of an RBAC oversight, you can use trait-based restrictions to stop them from requesting a role with even more privileges.

Let's say that you have defined the following role for a contractor you have hired to analyze financial data.

```yaml
kind: user
version: v2
metadata:
name: myuser
spec:
roles:
- analyst # An unprivileged role
traits:
logins:
- myuser
groups:
- contractors
```

Analysts sometimes need write access to your organization's database in order to create stored procedures, and can request access to the `db-writer` role. Only trusted analysts can request this access, and belong to a special `admins` group. Using `deny` rules, you can prevent analysts who are _not_ in the `admins` group from requesting access to the `db-writer` role:

```yaml
kind: role
version: v4
metadata:
name: analyst
spec:
deny:
request:
claims_to_roles:
- claim: groups
value: "{{regexp.not_match(\"admin\")}}"
roles: ["db-writer"]
allow:
request:
roles: ["db-writer"]
thresholds:
- approve: 2
deny: 1
```

The `claims_to_roles` field within an `allow` or `deny` rule maps a user's `traits` to `roles` that they are either permitted or forbidden to request. In this case, we use the `{{regexp.not_match(\"admin\")}}` template function to prevent any user from requesting the `db-writer` role unless they have a `groups` trait with a value like `administrator` or `admins`. Users who _do_ have such a trait can request the role with two approvals.


## Set up your RBAC without admin roles
You can design your Teleport RBAC so that there is no all-powerful administrator in the system, or even a `reviewer` role with elevated privileges. This way, you can reduce the blast radius if an attacker successfully impersonates a Teleport user and requests a more privileged role.

First, define a role with privileged but limited access. In the following example, the `editor` role can log in as `editor` on hosts in our infrastructure in addition to the logins defined when creating the user. To prevent abuse, certificates issued to the user will be valid for only half a working day.

```yaml
kind: role
version: v4
metadata:
name: editor
spec:
options:
max_session_ttl: 4h
allow:
logins: [editor, "{{internal.logins}}"]
```

Next, we define the general `user` role. Users with this role can review other users' requests to become an `editor`, and can request the `editor` role themselves with two approvals. However, this user cannot log in as `editor` within our infrastructure.

```yaml
kind: role
version: v4
metadata:
name: user
spec:
allow:
logins: ["{{internal.logins}}"]
review_requests:
roles: ['editor']
request:
roles: ["editor"]
thresholds:
- approve: 2
deny: 1
deny:
logins: ["editor"]
```

Two `user`s can grant elevated privileges to another `user` temporarily without the need for a separate `reviewer` role that can become a target for attacks.

## Next steps

### Guides
- [Per-session MFA](../../access-controls/guides/per-session-mfa.mdx)
- [Dual authorization](../../access-controls/guides/dual-authz.mdx)
- [Role templates, allow/deny rules, and traits](../../access-controls/guides/role-templates.mdx)
- [Access requests and plugins](../../enterprise/workflow.mdx)

### Background reading
- [Authentication connectors](../reference/authentication.mdx)
- [Proxy Service](../../architecture/proxy.mdx)
- [Auth Service](../../architecture/authentication.mdx)

0 comments on commit 45c4540

Please sign in to comment.