Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: Add design doc for --initialize-secure #28482

Merged
merged 7 commits into from
Oct 20, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions docs/design/2021-09-29-secure-bootstrap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# TiDB Design Documents

- Author(s): [morgo](http://github.com/morgo)
- Discussion PR: https://github.com/pingcap/tidb/pull/28482
- Tracking Issue: https://github.com/pingcap/tidb/issues/28481

## Table of Contents

* [Introduction](#introduction)
* [Motivation or Background](#motivation-or-background)
* [Detailed Design](#detailed-design)
* [Test Design](#test-design)
* [Impacts & Risks](#impacts--risks)
* [Investigation & Alternatives](#investigation--alternatives)
* [Unresolved Questions](#unresolved-questions)

## Introduction

Currently, TiDB will create a root user with no password and bind to `0.0.0.0/::`. This is a potential security issue if users do not have a firewall configured correctly, or if a rogue actor has local access.

This document introduces the `--intialize-secure` and `--initialize-insecure` bootstrap options. The current behavior is equivalent to `--initialize-insecure`, but the intention is to change the default to secure **once** it is determined stable.

## Motivation or Background

The motivation for this change is to improve the default security of TiDB. The current default is insecure, and requires additional steps to be taken by users to secure TiDB.

The design attempts to make the change with the least breakage possible. However, there will be some impact to usability.

## Detailed Design

The current bootstrap (to be referred to as `--initialize-insecure`) creates a root user as follows. This will remain unchanged:

```sql
CREATE USER 'root'@'%' IDENTIFIED WITH 'mysql_native_password' AS '' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK;
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
```

The `--initialize-secure` bootstrap will instead create a user based on the OS user. For example, with an OS user of `ubuntu`:

```sql
CREATE USER 'ubuntu'@'localhost' IDENTIFIED WITH 'auth_socket' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK;
morgo marked this conversation as resolved.
Show resolved Hide resolved
GRANT ALL PRIVILEGES ON *.* TO 'ubuntu'@'localhost' WITH GRANT OPTION;
```

After TiDB has bootstrapped, the user will be able to login and create additional users:

```bash
mysql -S /tmp/tidb.sock
..
mysql> CREATE USER 'root'@'%' IDENTIFIED BY 'securePassword';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
```

### Required Supporting Features
morgo marked this conversation as resolved.
Show resolved Hide resolved

In order to add the `--initialize-secure` bootstrap option, the following supported features are required:

1. Support for Socket Authentication (`auth_socket`) [PR in Review](https://github.com/pingcap/tidb/pull/27561)
2. Stale socket files are automatically cleaned up on server start [PR Merged](https://github.com/pingcap/tidb/pull/27886)
3. TiDB listens on both TCP **and** unix socket by default [PR in Review](https://github.com/pingcap/tidb/pull/28486)
4. Auth plugin can be changed with ALTER/CREATE [PR Draft](https://github.com/pingcap/tidb/pull/28468)

## Test Design
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we use ubuntu instead of root we should verify if there are other things that might break because of this.

Might be good to test br, dumpling, lightning, etc to see if they allow UNIX socket connections (should not be a blocker, and likely already the case for MySQL support)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Although in practice, this won't break if we modify tiup and Operator to use --initialize-insecure and generate a random password before we change the default bootstrap to secure (default change is not in scope yet for this proposal).


Integration tests are required to verify the behavior of the `--initialize-secure` bootstrap option works with other components (such as TiDB Dashboard, Operator, DBaaS, TiUP).

Some components (such as DBaaS) may choose to explicitly use `--initialize-insecure` to bootstrap, and then alter the root password to a secure password. This is similar to how bootstrapping works in MySQL with various installation methods.

There are no risks on upgrade/downgrade testing, because the change will be implemented in the bootstrap process only. This change is not intended to be cherry picked to existing GA versions, as this will cause compatibility issues with TiDB Dashboard (confirmed by TiDB Dashboard team).

## Impacts & Risks

The design choice of `auth_socket` is based on our current requirement of only supporting unix-like operating systems, and not needing to support Windows. This is a reasonable choice, as we do not expect to support Windows in the future. There might be some minor added complexity if we currently do not handle cases well such as the socket file already existing.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about if we consider the Windows OS?


Adding the option `--initialize-secure` itself does not add risk, but enabling it by default will add risk as it is a difference in behavior. This design tries to minimize the risk, but it is a large change. There is a risk if we don't update all the documentation and communicate the change effectively, it will become a support issue for new users.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, my concern is for the deployment of a new version of TiDB by the old version of the deployment tool(TiUP/TiOperator), the users may be surprised by the --initialize-secure mode and very difficult to access by auth socket in a pod(TiOperator).

For now, I prefer to set the default option as --initialize-insecure and change the default option after all old versions of TiUP/TiOperator are deprecated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, and this is is what is intended: The default is --initialize-insecure to give installers time to transition. Once transitioned, the default can change to secure.

By adding both options, it supports the transition correctly because initially --initialize-insecure will be a noop, but will later mean something as the default changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See also the above comment: default change is not in scope yet for this proposal.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, thank you!


## Investigation & Alternatives

The alternative implementation is to generate a random password with `--initialize-secure`. This is the approach that is used by MySQL. This has been discussed, and rejected.

## Unresolved Questions

- Should the `auth_socket` user on the MySQL-side be the OS-user, or `root`. It is possible to do either. We need to discuss what is the less of 2 evils:
- Having 2 "roots" (localhost, and %)
- Having a default user that is different for everyone, with instructions to create a root account.