目录
为 TiDB 落盘文件开启加密
当系统变量 tidb_enable_tmp_storage_on_oom 为 ON 时(默认为ON),如果单条 SQL 语句的内存使用超出系统变量 tidb_mem_quota_query 的限制,某些算子可以将执行时的中间结果作为临时文件落盘保存,直到查询执行完成之后将它们删除。
用户可以开启落盘文件加密功能,防止攻击者通过读取临时文件来访问数据。
- 修改tidb配置文件
vim /datalist/tidb-deploy/tidb-4000/conf/tidb.toml
添加如下配置([security]段若已存在,不要重复添加):
[security]
spilled-file-encryption-method = "aes128-ctr"
- spilled-file-encryption-method 的可选值为 aes128-ctr 和 plaintext。默认值为 plaintext,表示不启用加密。
日志脱敏
TiDB 在提供详细的日志信息时,可能会把数据库敏感的数据(例如用户数据)打印出来,造成数据安全方面的风险。因此 TiDB、TiKV、PD 等组件各提供了一个配置项开关,开关打开后,会隐藏日志中包含的用户数据值。
TiDB 组件日志脱敏
- TiDB 侧的日志脱敏需要将 global.tidb_redact_log 的值设为 1。该变量值默认为 0,即关闭脱敏。
set @@global.tidb_redact_log=1;
- 设置后,所有新 session 产生的日志都会脱敏:
create table t (a int, unique key (a));
insert into t values (1),(1);
注:set命令设置脱敏后,测试inset插入语句时应新建一个新的窗口或退出mysql客户端重新链接,以便变更新的session。
- 查看TiDB日志
tail /datalist/tidb-deploy/tidb-4000/log/tidb.log
从以上报错日志可以看到,开启 tidb_redact_log 后,报错信息里的敏感内容被隐藏掉了(目前是用问号替代)。TiDB 日志中会把敏感信息隐藏掉,以此规避数据安全风险。
TiKV 组件日志脱敏
TiKV 侧的日志脱敏需要将 security.redact-info-log 的值设为 true。该配置项值默认为 false,即关闭脱敏。
- 修改tikv配置文件
vim /datalist/tidb-deploy/tikv-20160/conf/tikv.toml
添加如下配置([security]段若已存在,不要重复添加):
[security]
redact-info-log = true
PD 组件日志脱敏
PD 侧的日志脱敏需要将 security.redact-info-log 的值设为 true。该配置项值默认为 false,即关闭脱敏。
- 修改pd配置文件
vim /datalist/tidb-deploy/pd-2379/conf/pd.toml
添加如下配置([security]段若已存在,不要重复添加):
[security]
redact-info-log = true
TiFlash 组件日志脱敏
TiFlash 侧的日志脱敏需要将 tiflash-server 中 security.redact_info_log 配置项的值以及 tiflash-learner 中 security.redact-info-log 配置项的值均设为 true。两配置项默认值均为 false,即关闭脱敏。
- 修改tiflash-server和tiflash-learner配置文件
vim /datalist/tidb-deploy/tiflash-9000/conf/tiflash.toml
vim /datalist/tidb-deploy/tiflash-9000/conf/tiflash-learner.toml
添加如下配置([security]段若已存在,不要重复添加):
[security]
redact-info-log = true
TiDB 密码管理
密码复杂度策略
在 TiDB 中,密码复杂度检查默认未开启。通过配置密码复杂度相关的系统变量,你可以开启密码复杂度检查,并确保为账户设置的密码符合密码复杂度策略。
密码复杂度策略支持以下功能:
- 对采用明文方式设置用户密码的 SQL 语句(包括 CREATE USER、ALTER USER、SET PASSWORD ),系统会根据密码复杂度策略检查该密码,如果该密码不符合要求,则拒绝该密码。
- 可以使用 SQL 函数 VALIDATE_PASSWORD_STRENGTH() 评估给定密码的强度。
- 注意
- 对于 CREATE USER 语句,即使该账户最初被锁定,也必须提供满足密码复杂度策略的密码,否则将账户解锁后,该账户可以使用不符合密码复杂度策略的密码访问 TiDB。
- 对密码复杂度策略的变更不影响已存在的密码,只会对新设置的密码产生影响。
- 通过以下 SQL 语句,你可以查看所有密码复杂度策略相关的系统变量:
SHOW VARIABLES LIKE 'validate_password.%';
- 参数解释:
- validate_password.check_user_name:默认值:ON。当该变量生效且为 ON 时,如果设置账户密码,TiDB 会将密码与当前会话账户的用户名部分(不包含主机名部分)进行比较,如果匹配则拒绝该密码。
- validate_password.dictionary:默认值:""。默认情况下,该变量为空值,不执行字典检查。要进行字典检查,该变量值必须包含待匹配的单词。配置了该变量后,在设置账户密码时,TiDB 会将长度为 4 到 100 的密码的每个子字符串与该变量中配置的单词进行比较。任何匹配都会导致密码被拒绝。比较不区分大小写。
- validate_password.enable:默认值:OFF。该变量是密码复杂度策略检查的开关。该变量设置为 ON 后,当设置账户密码时,TiDB 才会进行密码复杂度的各项检查。
- validate_password.length:该变量是密码复杂度策略检查中的一个检查项,用于限定密码的最小长度,默认最小长度为 8。设置该变量时有最小值要求,最小值由其他几个相关的系统变量控制,即该变量的值不能设置为小于此表达式的值:validate_password.number_count + validate_password.special_char_count + (2 * validate_password.mixed_case_count)。当用户修改 validate_password.number_count、validate_password.special_char_count、validate_password.mixed_case_count 后导致表达式的值大于 validate_password.length 时,validate_password.length 将自动被修改为满足表达式的最小值。
- validate_password.mixed_case_count:默认值:1。该变量是密码复杂度策略检查中的一个检查项,用于限定密码中至少需要包含多少个大写字符和小写字符。只有当 validate_password.enable 开启且 validate_password.policy 大于或等于 1 (MEDIUM) 时,该变量才生效。
- validate_password.number_count:默认值:1。该变量是密码复杂度策略检查中的一个检查项,用于限定密码中至少需要包含多少个数字字符。只有当 validate_password.enable 开启且 validate_password.policy 大于或等于 1 (MEDIUM) 时,该变量才生效
- validate_password.policy:默认值:1。可选值:[0, 1, 2]。该变量是密码复杂度策略检查的强度策略,该变量影响其他密码复杂度系统变量(前缀为 validate_password)在密码检查时是否生效,但是 validate_password.check_user_name 除外。只有 validate_password.enable 开启时,该变量才生效。该变量可以使用数值 0、1、2 或相应的符号值 LOW、MEDIUM、STRONG,密码强度策略对应的检查项如下:
- 0 或者 LOW:检查密码长度。
- 1 或者 MEDIUM:检查密码长度,检查密码中数字、小写字符、大写字符、特殊字符数量。
- 2 或者 STRONG:检查密码长度,检查密码中数字、小写字符、大写字符、特殊字符数量,检查密码字典匹配。
- validate_password.special_char_count:默认值:1。该变量是密码复杂度策略检查中的一个检查项,用于限定密码中至少需要包含多少个特殊字符。只有当 validate_password.enable 开启且 validate_password.policy 大于或等于 1 (MEDIUM) 时,该变量才生效。
配置密码复杂度策略
开启密码复杂度策略检查
SET GLOBAL validate_password.enable = ON;
设置不允许密码与当前用户名相同
SET GLOBAL validate_password.check_user_name = ON;
设置密码复杂度的检查等级
SET GLOBAL validate_password.policy = LOW;
设置密码最小长度
SET GLOBAL validate_password.length = 10;
设置密码字符规则
如:设置密码中至少含有 2 个数字,至少含有 1 个大写和小写字符,至少含有 1 个特殊字符。
SET GLOBAL validate_password.number_count = 2;
SET GLOBAL validate_password.mixed_case_count = 1;
SET GLOBAL validate_password.special_char_count = 1;
设置密码字典功能
如:要求密码中不允许包含 mysql 或 abcd
SET GLOBAL validate_password.dictionary = 'mysql;abcd';
- 注意
- validate_password.dictionary 是一个长字符串,长度不超过 1024,字符串内容可包含一个或多个在密码中不允许出现的单词,每个单词之间采用英文分号(;)分隔。
- 密码字典功能进行单词比较时,不区字符分大小写。
密码重用策略
TiDB 支持限制重复使用以前的密码。密码重用策略可以基于密码更改的次数或经过的时间,也可以同时基于两者。密码重用策略分为全局级别和账户级别。你可以在全局级别建立密码重用策略,也可以使用账户级别密码重用策略覆盖全局策略。
- TiDB 会记录账户的历史密码,并限制从该历史记录中选择新密码:
- 如果密码重用策略基于密码更改次数,则新密码不得与指定数量的历史密码相同。例如,如果密码的最小更改次数设置为 3,则新密码不能与最近 3 个密码中的任何一个相同。
- 如果密码重用策略基于经过的时间,则新密码不得与历史记录中指定天数内使用过的密码相同。例如,如果密码重用间隔设置为 60,则新密码不能与最近 60 天内使用过的密码相同。
- 注意
- 空密码不计入密码历史记录,可以随时重复使用。
全局级别密码重用策略
要在全局范围内建立密码重用策略,请使用 password_history 和 password_reuse_interval 系统变量。
SET GLOBAL password_history = 6;
SET GLOBAL password_reuse_interval = 365;
全局密码重用策略适用于所有未在账户级别设置过密码重用策略的账户。
账户级别密码重用策略
要建立账户级别密码重用策略,请使用 CREATE USER 或 ALTER USER 语句的 PASSWORD HISTORY 和 PASSWORD REUSE INTERVAL 选项。
示例:
- 禁止重复使用最近 5 次使用过的密码:
CREATE USER 'test'@'localhost' PASSWORD HISTORY 5;
ALTER USER 'test'@'localhost' PASSWORD HISTORY 5;
- 禁止重复使用最近 365 天内使用过的密码:
CREATE USER 'test'@'localhost' PASSWORD REUSE INTERVAL 365 DAY;
ALTER USER 'test'@'localhost' PASSWORD REUSE INTERVAL 365 DAY;
- 如需组合两种类型的重用策略,请一起使用 PASSWORD HISTORY 和 PASSWORD REUSE INTERVAL:
CREATE USER 'test'@'localhost' PASSWORD HISTORY 5 PASSWORD REUSE INTERVAL 365 DAY;
ALTER USER 'test'@'localhost' PASSWORD HISTORY 5 PASSWORD REUSE INTERVAL 365 DAY;
- 移除指定账户的账户级别密码重用策略,使其遵循于全局密码重用策略:
CREATE USER 'test'@'localhost' PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT;
ALTER USER 'test'@'localhost' PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT;
- 注意
- 如果多次设置密码重用策略,则最后一次设置的值生效。
- PASSWORD HISTORY 和 PASSWORD REUSE INTERVAL 选项的默认值为 0,表示禁用该项重用策略。
- 在修改用户名时,TiDB 会将 mysql.password_history 系统表中原用户名的历史密码记录迁移到新用户名的记录中。
密码连续错误限制登录策略
TiDB 支持限制账户持续尝试登录,防止用户密码被暴力破解。当账户连续登录失败次数过多时,账户将被临时锁定。
- 注意
- 只支持账户级别的密码连续错误限制登录策略,不支持全局级别的策略。
- 登录失败是指客户端在连接尝试期间未能提供正确的密码,不包括由于未知用户或网络问题等原因而导致的连接失败。
- 对用户启用密码连续错误限制登录策略后,将增加该用户登录时的检查步骤,此时会影响该用户登录相关操作的性能,尤其是高并发登录场景。
配置密码连续错误限制登录策略
每个账户的登录失败次数和锁定时间是可配置的,你可以使用 CREATE USER、ALTER USER 语句的 FAILED_LOGIN_ATTEMPTS 和 PASSWORD_LOCK_TIME 选项。FAILED_LOGIN_ATTEMPTS 和 PASSWORD_LOCK_TIME 选项的可设置值如下:
- FAILED_LOGIN_ATTEMPTS:N。表示连续登录失败 N 次后,账户将被临时锁定。N 取值范围为 0 到 32767。
- PASSWORD_LOCK_TIME:N | UNBOUNDED。N 表示登录失败后,账户将被临时锁定 N 天。UNBOUNDED 表明锁定时间无限期,账户必须被手动解锁。N 取值范围为 0 到 32767。
- 注意
- 允许单条 SQL 语句只设置 FAILED_LOGIN_ATTEMPTS 或 PASSWORD_LOCK_TIME 中的一个选项,这时密码连续错误限制登录策略不会实质生效。
- 只有当账户的 FAILED_LOGIN_ATTEMPTS 和 PASSWORD_LOCK_TIME 都不为 0 时,系统才会跟踪该账户的失败登录次数并执行临时锁定。
- 配置密码连续错误限制登录策略的示例如下:
- 新建一个用户,并配置密码连续错误限制登录策略,当该用户密码连续错误 3 次时,临时锁定 3 天:
CREATE USER 'test1'@'localhost' IDENTIFIED BY 'password' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 3;
- 修改用户的密码连续错误限制登录策略,当该用户密码连续错误 4 次时,无限期锁定,直到账户被手动解锁:
ALTER USER 'test2'@'localhost' FAILED_LOGIN_ATTEMPTS 4 PASSWORD_LOCK_TIME UNBOUNDED;
- 关闭用户的密码连续错误限制登录策略:
ALTER USER 'test3'@'localhost' FAILED_LOGIN_ATTEMPTS 0 PASSWORD_LOCK_TIME 0;
锁定账户解锁
- 在以下场景中,TiDB 将重置用户密码连续错误次数的计数:
- 对该用户执行 ALTER USER ... ACCOUNT UNLOCK 解锁命令时。
- 该用户登录成功时。
- 当用户因密码连续多次错误触发账户锁定后,以下情况下可以解锁账户:
- 该用户锁定时间结束,这种情况下,用户的自动锁定标识将在下次登录尝试时重置。
- 对该用户执行 ALTER USER ... ACCOUNT UNLOCK 解锁命令时。
- 注意
当用户因密码连续失败次数达到设定值而被自动锁定时,如果修改该账户的密码连续错误限制登录策略,需要注意:
- 修改该用户的登录失败次数 FAILED_LOGIN_ATTEMPTS,用户的自动锁定状态不会改变。修改后的连续登录失败次数,将在用户解锁后再次尝试登录时生效。
- 修改该用户的锁定时间 PASSWORD_LOCK_TIME,用户的自动锁定状态不会改变。修改后的用户锁定时间,将在账户再次登录尝试时检查是否满足此时的锁定时间要求,如果锁定时间结束就会解锁该用户。
密码过期策略
TiDB 支持通过设置密码过期策略,要求用户定期修改密码,从而提高密码的安全性。可以手动将指定账户的密码设置为过期,也可以建立密码自动过期策略。自动过期策略分为全局级别和账户级别,管理员可以在全局级别建立密码过期策略,也可以使用账户级别密码过期策略覆盖全局级别策略。设置密码过期策略的权限要求如下:
- 具有 SUPER 或者 CREATE USER 权限的数据库管理员可以手动设置密码过期。
- 具有 SUPER 或者 CREATE USER 权限的数据库管理员可以设置账户级别自动密码过期策略。
- 具有 SUPER 或者 SYSTEM_VARIABLES_ADMIN 权限的数据库管理员可以设置全局级别自动密码过期策略。
手动密码过期
要手动设置账户密码过期,请使用 CREATE USER 或 ALTER USER 语句。
ALTER USER 'test'@'localhost' PASSWORD EXPIRE;
- 当账户密码被管理员手动设置过期后,必须修改该账户密码才能解除密码过期,不支持取消手动过期。
- 对于通过 CREATE ROLE 语句创建的角色,由于角色不需要设置密码,所以该角色对应的密码字段为空,此时对应的 password_expired 属性为 'Y',即该角色的密码处于手动过期状态。如此设计的目的是防止出现角色锁定状态被解除后,该角色以空密码登录到 TiDB,当该角色被 ALTER USER ... ACCOUNT UNLOCK 命令解锁后,此时该角色处于可登录的状态,但是密码为空;因此 TiDB 通过 password_expired 属性,使得角色的密码处于手动过期状态,从而强制要求为该角色设置一个有效的密码。
自动密码过期
- 自动密码过期是基于密码使用期限和密码被允许的生存期来判断的。
- 密码使用期限:从最近一次密码更改日期到当前日期的时间间隔。系统表 mysql.user 中会记录最近一次修改密码的时间。
- 密码被允许的生存期:一个密码被设置后,其可以正常用于登录 TiDB 的天数。
- 如果密码使用期限大于其被允许的生存期,服务器会自动将密码视为已过期。
TiDB 支持在全局级别和账户级别设置自动密码过期:
全局级别自动密码过期
可以设置系统变量 default_password_lifetime 来控制密码生存期。该变量默认值为 0,表示禁用自动密码过期。如果设置该变量的值为正整数 N,则表示允许的密码生存期为 N 天,即必须在 N 天之内更改密码。
全局自动密码过期策略适用于所有未设置账户级别覆盖的账户。
- 以下示例建立全局自动密码过期策略,密码有效期为 180 天:
SET GLOBAL default_password_lifetime = 180;
账户级别自动密码过期
要为个人账户建立自动密码过期策略,请使用 CREATE USER 或 ALTER USER 语句的 PASSWORD EXPIRE 选项。
- 以下示例要求用户密码每 90 天更改一次:
CREATE USER 'test'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;
ALTER USER 'test'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;
- 在账户级别禁用自动密码过期策略:
CREATE USER 'test'@'localhost' PASSWORD EXPIRE NEVER;
ALTER USER 'test'@'localhost' PASSWORD EXPIRE NEVER;
- 移除指定账户的账户级别自动密码过期策略,使其遵循于全局自动密码过期策略:
CREATE USER 'test'@'localhost' PASSWORD EXPIRE DEFAULT;
ALTER USER 'test'@'localhost' PASSWORD EXPIRE DEFAULT;
密码过期策略检查机制
当客户端连接成功后,服务端将按顺序进行以下检查,判断账号密码是否过期:
- 服务器检查密码是否已手动过期。
- 若密码没有手动过期,服务器根据自动密码过期策略检查密码使用期限是否大于其允许的生存期。如果是,服务器认为密码已过期。
密码过期处理机制
TiDB 支持密码过期策略控制。当密码过期后,服务器要么断开客户端的连接,要么将客户端限制为“沙盒模式”。“沙盒模式”下,TiDB 服务端接受密码过期账户的连接,但是连接成功后只允许该用户执行重置密码的操作。
- TiDB 服务端可以控制是否将密码已过期用户的连接限制为“沙盒模式”。你可以在 TiDB 配置文件中的 [security] 部分,配置 disconnect-on-expired-password 选项:
[security]
disconnect-on-expired-password = false
- 默认情况下,disconnect-on-expired-password 为 true,表示当密码过期后,服务器将直接断开客户端的连接。
- 如果配置 disconnect-on-expired-password 为 false,则服务端处于沙盒模式,服务端允许用户建立连接,但只能执行密码重置操作,密码重置后将允许用户正常执行各类 SQL 语句。
- 当 disconnect-on-expired-password 为 true 时,TiDB 将拒绝密码已过期用户的连接,此时可以通过如下方法修改密码:
- 普通用户密码过期,可以由管理员用户通过 SQL 语句修改该用户的密码。
- 管理员密码过期,可以由其他管理员用户通过 SQL 语句修改该用户的密码。
- 如果管理员密码过期,且无法寻求其他管理员帮助修改该用户的密码,此时可以采用 skip-grant-table 机制修改该用户密码,具体可参看忘记密码流程。
开启加密通信传输
TiUP组件开启TLS加密通信传输(推荐)
TiUP组件支持自动创建并使用证书文件和秘钥,可通过一条命令开启集群的TLS。
缩容PD节点
在使用TiUP组件开启TLS前,需要PD节点仅为一个,因此需对PD组件进行缩容处理。若不进行缩容,直接启用TLS,将会报如下错误:
- 缩容PD节点
tiup cluster scale-in tidb -N 10.8.15.36:2379,10.8.15.37:2379
为集群开启TLS
tiup cluster tls tidb enable
注:此处参数中的“tidb”为集群名称,根据实际情况进行修改。
验证已开启TLS
- 查看集群状态,可以看到TLS状态已为enabled,增加了证书和密钥的路径,以及dashboard中显示的不再是 http,而是 https 的访问网址了。
tiup cluster display tidb
- 使用客户端证书等进行etcd命令查询进行验证
tiup ctl:v7.0.0 etcd --endpoint=https://127.0.0.1:2379 --ca-file /root/.tiup/storage/cluster/clusters/tidb/tls/ca.crt --cert-file /root/.tiup/storage/cluster/clusters/tidb/tls/client.crt --key-file /root/.tiup/storage/cluster/clusters/tidb/tls/client.pem member list
注:检查启用 TLS 是否成功,只需要确认 peerURLs 是否为 HTTPS 即可。
扩容PD节点
- 创建并编辑扩容配置文件
vim scale-out.yml
添加如下内容:
pd_servers:
- host: 10.8.15.36
- host: 10.8.15.37
- 注:
- 可以使用 tiup cluster edit-config <cluster-name> 查看当前集群的配置信息,因为其中的 global 和 server_configs 参数配置默认会被 scale-out.yml 继承,因此也会在 scale-out.yml 中生效。
- 若不继承global配置,可为每个节点添加相应的配置内容,如:
pd_servers:
- host: 10.0.1.5
ssh_port: 22
name: pd-1
client_port: 2379
peer_port: 2380
deploy_dir: /tidb-deploy/pd-2379
data_dir: /tidb-data/pd-2379
log_dir: /tidb-deploy/pd-2379/log
- 执行扩容命令
执行 scale-out 命令前,先使用 check 及 check --apply 命令,检查和自动修复集群存在的潜在风险:
检查集群存在的潜在风险:
tiup cluster check <cluster-name> scale-out.yml --cluster --user root [-p] [-i /home/root/.ssh/gcp_rsa]
自动修复集群存在的潜在风险:
tiup cluster check <cluster-name> scale-out.yml --cluster --apply --user root [-p] [-i /home/root/.ssh/gcp_rsa]
执行 scale-out 命令扩容 TiDB 集群:
tiup cluster scale-out <cluster-name> scale-out.yml [-p] [-i /home/root/.ssh/gcp_rsa]
- 以上操作示例中:
- 扩容配置文件为 scale-out.yml。
- --user root 表示通过 root 用户登录到目标主机完成集群部署,该用户需要有 ssh 到目标机器的权限,并且在目标机器有 sudo 权限。也可以用其他有 ssh 和 sudo 权限的用户完成部署。
- [-i] 及 [-p] 为可选项,如果已经配置免密登录目标机,则不需填写。否则选择其一即可,[-i] 为可登录到目标机的 root 用户(或 --user 指定的其他用户)的私钥,也可使用 [-p] 交互式输入该用户的密码。
- 预期日志结尾输出 Scaled cluster `<cluster-name>` out successfully 信息,表示扩容操作成功。
tiup cluster scale-out tidb scale-out.yml
开启TLS后的PD DashBoard使用
- 开启TLS后,DashBoard管理页面将需要修改地址为:https://127.0.0.1:2379/dashboard。但应注意的是,访问此页面的主机需提前安装客户端证书文件。证书文件路径及名称,可通过查看集群状态进行查看:
tiup cluster display tidb-test
- 将该目录下的client.pfx文件拷贝至主机中进行安装即可:
- 具体安装方式不再赘述,以下图片仅供参考:
安装过程中将提示输入密码,该密码一般为“tiup”。