-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Backport v8] Create a blast radius reduction guide (#9430)
* 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
Showing
3 changed files
with
294 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |