Skip to content

Commit

Permalink
*: update the recent improvements about tls/security (pingcap#2417) (p…
Browse files Browse the repository at this point in the history
…ingcap#2761)

Co-authored-by: lysu <sulifx@gmail.com>
  • Loading branch information
sre-bot and lysu authored Apr 15, 2020
1 parent c5fcb22 commit e2270be
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 7 deletions.
50 changes: 48 additions & 2 deletions how-to/secure/enable-tls-between-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ category: how-to

本部分介绍 TiDB 集群如何开启 TLS 验证,TLS 验证支持:

- TiDB 组件之间的双向验证,包括 TiDB、TiKV、PD 相互之间,TiKV Control 与 TiKV、PD Control 与 PD 的双向认证,以及 TiKV peer 之间、PD peer 之间。一旦开启,所有组件之间均使用验证,不支持只开启某一部分的验证。
- TiDB 组件之间的双向验证,包括 TiDB、TiKV、PD 相互之间,TiDB Control 与 TiDB、 TiKV Control 与 TiKV、PD Control 与 PD 的双向认证,以及 TiKV peer 之间、PD peer 之间。一旦开启,所有组件之间均使用验证,不支持只开启某一部分的验证。
- MySQL Client 与 TiDB 之间的客户端对服务器身份的单向验证以及双向验证。

MySQL Client 与 TiDB 之间使用一套证书,TiDB 集群组件之间使用另外一套证书。
Expand Down Expand Up @@ -72,10 +72,16 @@ MySQL Client 与 TiDB 之间使用一套证书,TiDB 集群组件之间使用

> **注意:**
>
> 若 TiDB 集群各个组件间已开启 TLS,在使用 tikv-ctl 或 pd-ctl 工具连接集群时,需要指定 client 证书,示例:
> 若 TiDB 集群各个组件间已开启 TLS,在使用 tidb-ctl、tikv-ctl 或 pd-ctl 工具连接集群时,需要指定 client 证书,示例:

{{< copyable "shell-regular" >}}

```bash
./tidb-ctl -u https://127.0.0.1:10080 --ca /path/to/ca.pem --ssl-cert /path/to/client.pem --ssl-key /path/to/client-key.pem
```

{{< copyable "shell-regular" >}}

```bash
./pd-ctl -u https://127.0.0.1:2379 --cacert /path/to/ca.pem --cert /path/to/client.pem --key /path/to/client-key.pem
```
Expand All @@ -86,6 +92,46 @@ MySQL Client 与 TiDB 之间使用一套证书,TiDB 集群组件之间使用
./tikv-ctl --host="127.0.0.1:20160" --ca-path="/path/to/ca.pem" --cert-path="/path/to/client.pem" --key-path="/path/to/clinet-key.pem"
```

3. 配置校验调用者 Common Name。

通常被调用者除了校验调用者提供的密钥、证书和 CA 有效性外,还需要校验调用方身份(例如:TiKV 只能被 TiDB 访问,需阻止拥有合法证书但非 TiDB 的其他访问者访问 TiKV)。推荐在生成证书时通过 `Common Name` 标识证书使用者身份,并在被调用者配置检查证书 `Common Name` 列表来检查调用者身份。

- TiDB

在 `config` 文件或命令行参数中设置:

```toml
[security]
cluster-verify-cn = [
"TiDB-Server",
"TiKV-Control",
]
```

- TiKV

在 `config` 文件或命令行参数中设置:

```toml
[security]
cert-allowed-cn = [
"TiDB-Server", "PD-Server", "TiKV-Control", "RawKvClient1",
]
```

- PD

在 `config` 文件或命令行参数中设置:

```toml
[security]
cert-allowed-cn = ["TiKV-Server", "TiDB-Server", "PD-Control"]
```

4. 重加载证书。

TiDB、PD 和 TiKV 会在每次新建相互通讯的连接时重新读取当前的证书和密钥文件内容,实现证书和密钥的重加载。目前暂不支持 CA 的重加载。

### MySQL 与 TiDB 间开启 TLS

请参考 [使用加密连接](/how-to/secure/enable-tls-clients.md)。
Expand Down
37 changes: 32 additions & 5 deletions how-to/secure/enable-tls-clients.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,32 @@ category: how-to

TiDB 服务端默认采用非加密连接,因而具备监视信道流量能力的第三方可以知悉 TiDB 服务端与客户端之间发送和接受的数据,包括但不限于查询语句内容、查询结果等。若信道是不可信的,例如客户端是通过公网连接到 TiDB 服务端的,则非加密连接容易造成信息泄露,建议使用加密连接确保安全性。

TiDB 服务端支持启用基于 TLS(传输层安全)协议的加密连接,协议与 MySQL 加密连接一致,现有 MySQL 客户端如 MySQL 运维工具和 MySQL 驱动等能直接支持。TLS 的前身是 SSL,因而 TLS 有时也被称为 SSL,但由于 SSL 协议有已知安全漏洞,TiDB 实际上并未支持。TiDB 支持的 TLS/SSL 协议版本为 TLS 1.0、TLS 1.1、TLS 1.2。
TiDB 服务端支持启用基于 TLS(传输层安全)协议的加密连接,协议与 MySQL 加密连接一致,现有 MySQL 客户端如 MySQL 运维工具和 MySQL 驱动等能直接支持。TLS 的前身是 SSL,因而 TLS 有时也被称为 SSL,但由于 SSL 协议有已知安全漏洞,TiDB 实际上并未支持。TiDB 支持的 TLS/SSL 协议版本为 TLS 1.0、TLS 1.1、TLS 1.2、TLS 1.3

使用加密连接后,连接将具有以下安全性质:

- 保密性:流量明文无法被窃听;
- 完整性:流量明文无法被篡改;
- 身份验证(可选):客户端和服务端能验证双方身份,避免中间人攻击。

TiDB 的加密连接支持默认是关闭的,必须在 TiDB 服务端通过配置开启加密连接的支持后,才能在客户端中使用加密连接。另外,与 MySQL 一致,TiDB 加密连接是以单个连接为单位的,并且是可选的,因而对于开启了加密连接支持的 TiDB 服务端,客户端既可以选择通过加密连接安全地连接到该 TiDB 服务端,也可以选择使用普通的非加密连接。大部分 MySQL 客户端默认不采用加密连接,因此一般还要显式地要求客户端使用加密连接。

简单来说,要使用加密连接必须同时满足以下两个条件:
TiDB 的加密连接支持默认是关闭的,必须在 TiDB 服务端通过配置开启加密连接的支持后,才能在客户端中使用加密连接,要使用加密连接必须同时满足以下两个条件:

1. TiDB 服务端配置开启加密连接的支持
2. 客户端指定使用加密连接

另外,与 MySQL 一致,TiDB 加密连接是以单个连接为单位的,默认情况下是可选的。因而对于开启了加密连接支持的 TiDB 服务端,客户端既可以选择通过加密连接安全地连接到该 TiDB 服务端,也可以选择使用普通的非加密连接。如需强制要求客户端使用加密连接可以通过以下两种方式进行配置:

+ 通过在启动参数中配置 `--require-secure-transport` 要求所有用户必须使用加密连接来连接到 TiDB。
+ 通过在创建用户 (`create user`),赋予权限 (`grant`) 或修改已有用户 (`alter user`) 时指定 `require ssl` 要求指定用户必须使用加密连接来连接 TiDB。以创建用户为例:

```sql
create user 'u1'@'%' require ssl;
```

> **注意:**
>
> 如果登录用户已配置使用 [TiDB 证书鉴权功能](/reference/security/cert-based-authentication.md#配置登陆时需要校验的用户证书信息)校验用户证书,也会隐式要求对应用户必须使用加密连接连接 TiDB。

## 配置 TiDB 启用加密连接支持

在启动 TiDB 时,至少需要在配置文件中同时指定 `ssl-cert``ssl-key` 参数,才能使 TiDB 服务端接受加密连接。还可以指定 `ssl-ca` 参数进行客户端身份验证(请参见[配置启用身份验证](#配置启用身份验证)章节)。
Expand Down Expand Up @@ -64,6 +75,12 @@ ssl-key = "certs/server-key.pem"

若证书参数无误,则 TiDB 在启动时将会输出 `secure connection is enabled`,否则 TiDB 会输出 `secure connection is NOT ENABLED`

## 重加载证书密钥和 CA

在需要替换证书、密钥或 CA 时,可以在完成对应文件替换后,对运行中的 TiDB 实例执行 [`ALTER INSTACE RELOAD TLS`](/reference/sql/statements/alter-instance.md) 语句从原配置的证书 ([`ssl-cert`](/reference/configuration/tidb-server/configuration-file.md#ssl-cert))、密钥 ([`ssl-key`](/reference/configuration/tidb-server/configuration-file.md#ssl-key)) 和 CA ([`ssl-ca`](/reference/configuration/tidb-server/configuration-file.md#ssl-ca)) 的路径重新加证书、密钥和 CA 文件,而无需重启 TiDB 实例。

新加载的证书密钥和 CA 将在语句执行成功后对新建立的连接生效,不会影响语句执行前已建立的连接。

## 配置 MySQL 客户端使用加密连接

MySQL 5.7 及以上版本自带的客户端默认尝试使用安全连接,若服务端不支持安全连接则自动退回到使用非安全连接;MySQL 5.7 以下版本自带的客户端默认采用非安全连接。
Expand All @@ -84,9 +101,15 @@ MySQL 5.7 及以上版本自带的客户端默认尝试使用安全连接,若
- 若要使 TiDB 服务端验证 MySQL 客户端身份,TiDB 服务端需配置 `ssl-cert``ssl-key``ssl-ca` 参数,客户端需至少指定 `--ssl-cert``--ssl-key` 参数。必须确保服务端配置的证书和客户端配置的证书都是由服务端配置指定的 `ssl-ca` 签发的。
- 若要进行双向身份验证,请同时满足上述要求。

默认情况,服务端对客户端的身份验证是可选的。若客户端在 TLS 握手时未出示自己的身份证书,也能正常建立 TLS 连接。但也可以通过在创建用户 (`create user`),赋予权限 (`grant`) 或修改已有用户 (`alter user`) 时指定 `require 509` 要求客户端需进行身份验证,以创建用户为例:

```sql
create user 'u1'@'%' require x509;
```

> **注意:**
>
> 目前 TiDB 尚不支持强制验证客户端身份,即服务端对客户端的身份验证是可选的。若客户端在 TLS 握手时未出示自己的身份证书,也能正常建立 TLS 连接
> 如果登录用户已配置使用 [TiDB 证书鉴权功能](/reference/security/cert-based-authentication.md#配置登陆时需要校验的用户证书信息)校验用户证书,也会隐式要求对应用户需进行身份验证
## 检查当前连接是否是加密连接

Expand Down Expand Up @@ -131,6 +154,7 @@ TiDB 支持的 TLS 版本及密钥交换协议和加密算法由 Golang 官方
- TLS 1.0
- TLS 1.1
- TLS 1.2
- TLS 1.3

### 支持的密钥交换协议及加密算法

Expand All @@ -156,3 +180,6 @@ TiDB 支持的 TLS 版本及密钥交换协议和加密算法由 Golang 官方
- TLS\_ECDHE\_ECDSA\_WITH\_AES\_256\_GCM\_SHA384
- TLS\_ECDHE\_RSA\_WITH\_CHACHA20\_POLY1305
- TLS\_ECDHE\_ECDSA\_WITH\_CHACHA20\_POLY1305
- TLS\_AES\_128\_GCM\_SHA256
- TLS\_AES\_256\_GCM\_SHA384
- TLS\_CHACHA20\_POLY1305\_SHA256
Binary file added media/sqlgram/AlterInstanceStmt.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions reference/sql/statements/alter-instance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
title: ALTER INSTANCE
summary: TiDB 数据库中 ALTER INSTANCE 的使用概况。
category: reference
---

# ALTER INSTANCE

`ALTER INSTANCE` 语句用于对单个 TiDB 实例进行变更操作。目前 TiDB 仅支持 `RELOAD TLS` 子句。

## RELOAD TLS

`ALTER INSTACE RELOAD TLS` 语句用于从原配置的证书 ([`ssl-cert`](/reference/configuration/tidb-server/configuration-file.md#ssl-cert))、密钥 ([`ssl-key`](/reference/configuration/tidb-server/configuration-file.md#ssl-key)) 和 CA ([`ssl-ca`](/reference/configuration/tidb-server/configuration-file.md#ssl-ca)) 的路径重新加证书、密钥和 CA。

新加载的证书密钥和 CA 将在语句执行成功后对新建立的连接生效,不会影响语句执行前已建立的连接。

在重加载遇到错误时默认会报错返回且继续使用变更前的密钥和证书,但在添加可选的 `NO ROLLBACK ON ERROR` 后遇到错误将不报错并以关闭 TLS 安全连接功能的方式处理后续请求。

## 语法图

![AlterInstanceStmt](/media/sqlgram/AlterInstanceStmt.png)

## 示例

{{< copyable "sql" >}}

```sql
ALTER INSTANCE RELOAD TLS;
```

## MySQL 兼容性

仅支持从原配置路径重加载,不支持动态修改加载路径,也不支持动态启用启动 TiDB 时未开启的 TLS 加密连接功能。

## 另请参阅

* [Enable Client TLS](/how-to/secure/enable-tls-clients.md)
3 changes: 3 additions & 0 deletions reference/tools/tidb-control.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ TiDB Controller 是 TiDB 的命令行工具,用于获取 TiDB 状态信息,
- `--port` TiDB 服务端口
- `--pdhost` PD 服务地址
- `--pdport` PD 服务端口
- `--ca` 连接使用的 TLS CA 文件路径
- `--ssl-key` 连接使用的 TLS 密钥文件路径
- `--ssl-cert` 连接使用的 TLS 证书文件路径

其中 `--pdhost``--pdport` 主要是用于 `etcd` 子命令,例如:`tidb-ctl etcd ddlinfo`。如不添加地址和端口将使用默认值,TiDB/PD 服务默认的地址是 127.0.0.1 (服务地址只能使用 IP 地址),TiDB 服务端口默认的端口是 10080,PD 服务端口默认的端口是 2379 **连接选项是全局选项,适用于以下所有命令。**

Expand Down

0 comments on commit e2270be

Please sign in to comment.