目录
在考虑MySQL安装中的安全性时,您应该考虑各种可能的主题以及它们如何影响MySQL服务器和相关应用程序的安全性:
影响安全性的一般因素。 这些包括选择好的密码,不向用户授予不必要的权限,通过防止SQL注入和数据损坏来确保应用程序安全性等。 请参见 第6.1节“一般安全问题” 。
安装本身的安全性。 应保护数据文件,日志文件和安装的所有应用程序文件,以确保未经授权方无法读取或写入这些文件。 有关更多信息,请参见 第2.10节“安装后设置和测试” 。
数据库系统本身内的访问控制和安全性,包括允许访问数据库中使用的数据库,视图和存储程序的用户和数据库。 有关更多信息,请参见 第6.2节“访问控制和帐户管理” 。
安全相关插件提供的功能。 请参见 第6.4节“安全组件和插件” 。
MySQL和您的系统的网络安全性。 安全性与单个用户的授权有关,但您可能还希望限制MySQL,以便它仅在MySQL服务器主机上本地可用,或者在一组有限的其他主机上可用。
确保您有足够和适当的数据库文件,配置和日志文件备份。 还要确保您已准备好恢复解决方案,并测试您是否能够成功从备份中恢复信息。 请参见 第7章, 备份和恢复 。
本节介绍了要注意的一般安全问题,以及如何使MySQL安装更安全,防止攻击或滥用。 有关MySQL用于设置用户帐户和检查数据库访问权限的访问控制系统的信息,请参见 第2.10节“安装后设置和测试” 。
有关经常被问及有关MySQL服务器安全性问题的一些问题的答案,请参见 第A.9节“MySQL 8.0 FAQ:安全性” 。
在连接到Internet的计算机上使用MySQL的任何人都应该阅读本节以避免最常见的安全错误。
在讨论安全性时,有必要考虑完全保护整个服务器主机(不仅仅是MySQL服务器)免受所有类型的适用攻击:窃听,更改,回放和拒绝服务。 我们没有涵盖可用性和容错的所有方面。
MySQL使用基于访问控制列表(ACL)的安全性来处理用户可以尝试执行的所有连接,查询和其他操作。 MySQL客户端和服务器之间也支持SSL加密连接。 这里讨论的许多概念都不是特定于MySQL的; 相同的一般想法适用于几乎所有应用程序。
运行MySQL时,请遵循以下准则:
不要让任何人(MySQL
root
帐户
除外
)访问
系统数据库中
的
user
表
mysql
!
这很关键。
了解MySQL访问权限系统的工作原理(请参见
第6.2节“访问控制和帐户管理”
)。
使用
GRANT
和
REVOKE
语句来控制对MySQL的访问。
不要授予超出必要的权限。
永远不会授予所有主机权限。
清单:
试试
mysql -u root
。
如果您能够在不被要求输入密码的情况下成功连接到服务器,则任何人都可以以
root
具有完全权限
的MySQL
用户
身份连接到MySQL服务器
!
查看MySQL安装说明,特别注意有关设置
root
密码
的信息
。
请参见
第2.10.4节“保护初始MySQL帐户”
。
使用该
SHOW
GRANTS
语句检查哪些帐户可以访问哪些帐户。
然后使用该
REVOKE
语句删除那些不必要的权限。
不要在数据库中存储明文密码。
如果您的计算机遭到入侵,入侵者可以获取完整的密码列表并使用它们。
相反,使用
SHA2()
或一些其他单向散列函数并存储散列值。
要防止使用彩虹表恢复密码,请不要在普通密码上使用这些功能; 相反,选择一些字符串用作salt,并使用hash(hash(密码)+ salt)值。
不要从词典中选择密码。 存在破坏密码的特殊程序。 甚至像 “ xfish98 ” 这样的密码 都非常糟糕。 更好的是 “ duag98 ” ,它包含相同的单词 “ fish ”, 但在标准的QWERTY键盘上键入了左键。 另一种方法是使用从句子中每个单词的第一个字符中获取的密码(例如, “ 四分和七年前 ” 导致密码为 “ Fsasya ” )。 密码易于记忆和输入,但对于不知道该句子的人来说很难猜到。 在这种情况下,你可以另外用数字代替数字来获得短语 “ 4分和7年前 ” ,产生密码 “ 4sa7ya ” ,这更难以猜测。
投资防火墙。 这可以保护您免受任何软件中至少50%的漏洞攻击。 将MySQL放在防火墙后面或非军事区(DMZ)。
清单:
尝试使用诸如此类的工具从Internet扫描您的端口
nmap
。
MySQL默认使用端口3306。
不应从不受信任的主机访问此端口。
作为检查MySQL端口是否打开的简单方法,请从某个远程计算机尝试以下命令,其中
server_host
运行MySQL服务器的主机的主机名或IP地址:
外壳> telnet server_host
3306
如果 telnet 挂起或连接被拒绝,则端口被阻塞,这就是你想要的。 如果你得到一个连接和一些垃圾字符,端口是打开的,应该在防火墙或路由器上关闭,除非你真的有充分的理由保持它打开。
访问MySQL的应用程序不应信任用户输入的任何数据,应使用适当的防御性编程技术编写。 请参见 第6.1.7节“客户端编程安全指南” 。
不要通过Internet传输普通(未加密)数据。 每个有时间和能力拦截并将其用于自己目的的人都可以访问此信息。 而是使用加密协议,如SSL或SSH。 MySQL支持内部SSL连接。 另一种技术是使用SSH端口转发为通信创建加密(和压缩)隧道。
学习使用 tcpdump 和 字符串 实用程序。 在大多数情况下,您可以通过发出如下命令来检查MySQL数据流是否未加密:
外壳> tcpdump -l -i eth0 -w - src or dst port 3306 | strings
这适用于Linux,并且应该在其他系统下进行小的修改。
如果您没有看到明文数据,这并不总是意味着信息实际上是加密的。 如果您需要高安全性,请咨询安全专家。
密码出现在MySQL中的几个上下文中。
以下各节提供了一些指导原则,使最终用户和管理员能够确保这些密码的安全并避免泄露这些密码。
此外,该
validate_password
插件可用于对可接受的密码实施策略。
请参见
第6.4.3节“密码验证组件”
。
MySQL用户应使用以下准则来保证密码安全。
当您运行客户端程序以连接到MySQL服务器时,不建议以将其公开给其他用户发现的方式指定您的密码。 此处列出了运行客户端程序时可用于指定密码的方法,以及每种方法的风险评估。 简而言之,最安全的方法是让客户端程序提示输入密码或在受适当保护的选项文件中指定密码。
使用
mysql_config_editor
实用程序,该实用程序使您可以将身份验证凭据存储在名为的加密登录路径文件中
.mylogin.cnf
。
MySQL客户端程序稍后可以读取该文件以获取用于连接到MySQL服务器的身份验证凭据。
请参见
第4.6.7节“
mysql_config_editor
- MySQL配置实用程序”
。
在命令行上
使用
或
选项。
例如:
-p
your_pass
--password=
your_pass
外壳> mysql -u francis -pfrank db_name
这很方便 但不安全 。 在某些系统上,您的密码对系统状态程序(例如 ps) 可见 ,其他用户可以调用它来显示命令行。 MySQL客户端通常在初始化序列期间用零覆盖命令行密码参数。 但是,仍然存在一个短暂的间隔,在该间隔期间值是可见的。 此外,在某些系统上,此覆盖策略无效,并且 ps 仍然可以看到密码 。 (SystemV Unix系统和其他人可能遇到这个问题。)
如果您的操作环境设置为在终端窗口的标题栏中显示当前命令,则只要命令正在运行,密码仍然可见,即使该命令已在窗口内容区域中滚动出视图。
在命令行上
使用
-p
或
--password
选项,但未指定密码值。
在这种情况下,客户端程序以交互方式请求密码:
外壳> mysql -u francis -p db_name
输入密码: ********
该
*
字符显示在您输入密码。
输入密码时不会显示密码。
以这种方式输入密码比在命令行中指定密码更安全,因为其他用户看不到密码。 但是,这种输入密码的方法仅适用于以交互方式运行的程序。 如果要从非交互式运行的脚本调用客户端,则无法从键盘输入密码。 在某些系统上,您甚至可能会发现脚本的第一行被读取并被解释(错误地)作为您的密码。
将密码存储在选项文件中。
例如,在Unix上,您可以
在主目录
[client]
中的
.my.cnf
文件
部分
列出您的密码
:
[客户] 密码= your_pass的
为了确保密码安全,除了您自己之外,任何人都无法访问该文件。
要确保这一点,请将文件访问模式设置为
400
或
600
。
例如:
外壳> chmod 600 .my.cnf
要从命令行命名包含密码的特定选项文件,请使用
选项,其中
是文件的完整路径名。
例如:
--defaults-file=
file_name
file_name
外壳> mysql --defaults-file=/home/francis/mysql-opts
第4.2.2.2节“使用选项文件” 更详细地讨论了选项文件。
将密码存储在
MYSQL_PWD
环境变量中。
请参见
第4.9节“MySQL程序环境变量”
。
这种指定MySQL密码的方法必须被认为是
非常不安全的
,不应该使用。
某些版本的
ps
包含显示正在运行的进程环境的选项。
在某些系统上,如果设置
MYSQL_PWD
,则密码将暴露给运行
ps的
任何其他用户
。
即使在没有这种版本的
ps的系统上
,假设用户没有其他方法可以检查过程环境也是不明智的。
在Unix上,
mysql
客户端将执行语句的记录写入历史文件(参见
第4.5.1.3节“mysql客户端日志记录”
)。
默认情况下,此文件已命名
.mysql_history
并在主目录中创建。
密码可以在诸如
CREATE
USER
和的
SQL语句中以纯文本形式写入
ALTER
USER
,因此如果使用这些语句,它们将记录在历史文件中。
要保证此文件的安全,请使用限制访问模式,方法与前面对
.my.cnf
文件
所述的方式相同
。
如果命令解释程序配置为维护历史记录,则保存命令的任何文件都将包含在命令行中输入的MySQL密码。
例如,
bash
使用
~/.bash_history
。
任何此类文件都应具有限制性访问模式。
数据库管理员应使用以下准则来确保密码安全。
MySQL在
mysql.user
系统表中
存储用户帐户的密码
。
永远不应该向任何非管理帐户授予对此表的访问权限。
帐户密码可以过期,以便用户必须重置它们。 请参见 第6.2.15节“密码管理” 和 第6.2.16节“过期密码的服务器处理” 。
该
validate_password
插件可用于对可接受的密码强制实施策略。
请参见
第6.4.3节“密码验证组件”
。
有权修改插件目录(
plugin_dir
系统变量
的值
)或
my.cnf
指定插件目录位置
的
文件的用户可以替换插件并修改插件提供的功能,包括身份验证插件。
应该保护可能写入密码的日志文件等文件。 请参见 第6.1.2.3节“密码和日志记录” 。
口令可以写在SQL语句,如纯文本
CREATE
USER
,
GRANT
和
SET
PASSWORD
。
如果MySQL服务器将此类语句记录为已写入,则访问日志的任何人都可以看到其中的密码。
语句记录避免将密码写为以下语句的明文:
创建用户...通过...识别 ALTER USER ...由......识别 设置密码 ... 从头开始......密码= ...... 创建服务器...选项(...密码...) ALTER SERVER ...选项(...密码...)
这些语句中的密码被重写为不会出现在写入常规查询日志,慢查询日志和二进制日志的语句文本中。
重写不适用于其他声明。
具体而言,
INSERT
或
UPDATE
对语句
mysql.user
引用文字密码系统表中记录为是,那么你应该避免这样的语句。
(无论如何,不鼓励直接修改授权表。)
对于常规查询日志,可以通过使用该
--log-raw
选项
启动服务器来抑制密码重写
。
出于安全原因,建议不要将此选项用于生产用途。
出于诊断目的,查看服务器收到的语句的确切文本可能很有用。
默认情况下,审计日志插件生成的审计日志文件的内容未加密,可能包含敏感信息,例如SQL语句的文本。 出于安全原因,审计日志文件应写入只能由MySQL服务器访问的目录以及具有查看日志的合法理由的用户。 请参见 第6.4.5.3节“MySQL Enterprise Audit安全注意事项” 。
如果安装了查询重写插件,则可以重写服务器收到的语句(请参阅
查询重写插件
)。
在这种情况下,该
--log-raw
选项会影响语句记录,如下所示:
密码重写的含义是无法解析的语句(例如,由于语法错误)不会写入通用查询日志,因为无法知道它们是无密码的。
需要记录所有语句(包括有错误的语句)的用例应使用该
--log-raw
选项,请记住这也会绕过密码重写。
只有在需要纯文本密码时才会进行密码重写。 对于具有期望密码哈希值的语法的语句,不会发生重写。 如果为此类语法错误地提供了纯文本密码,则会将密码记录为给定,而不进行重写。
要保护日志文件免受不必要的暴露,请将它们放在限制访问服务器和数据库管理员的目录中。
如果服务器记录到
mysql
数据库中的表,则仅将这些表的访问权限授予数据库管理员。
复制从属服务器将复制主服务器的密码存储在主信息存储库中,默认情况下,该信息存储库是
mysql
名为数据库
的表
slave_master_info
。
现在不推荐在主数据存储库的数据目录中使用文件,但仍然可以使用(请参见
第17.2.4节“复制中继和状态日志”
)。
确保只能由数据库管理员访问主信息存储库。
将密码存储在主信息存储库中的替代方法是使用该
START
SLAVE
语句指定用于连接到主服务器的凭据。
使用受限访问模式来保护包含日志表或包含密码的日志文件的数据库备份。
连接到MySQL服务器时,应使用密码。 密码不会通过连接以明文形式传输。
所有其他信息都以文本形式传输,任何能够观看连接的人都可以阅读。 如果客户端和服务器之间的连接通过不受信任的网络,并且您担心这一点,则可以使用压缩协议使流量更难以解密。 您还可以使用MySQL的内部SSL支持来使连接更加安全。 请参见 第6.3节“使用加密连接” 。 或者,使用SSH在MySQL服务器和MySQL客户端之间获得加密的TCP / IP连接。 您可以在 http://www.openssh.org/ 找到一个开源SSH客户端 ,并 在那里 比较开源和商业SSH客户端 http://en.wikipedia.org/wiki/Comparison_of_SSH_clients 。
要使MySQL系统安全,您应该强烈考虑以下建议:
要求所有MySQL帐户都有密码。
客户端程序不一定知道运行它的人的身份。
客户端/服务器应用程序通常可以为客户端程序指定任何用户名。
例如,任何人都可以使用
MySQL的
程序为任何其他人简单地调用它作为连接
,如果
没有密码。
如果所有帐户都有密码,则使用其他用户的帐户进行连接会变得更加困难。
mysql -u
other_user
db_name
other_user
有关设置密码的方法的讨论,请参见 第6.2.14节“分配帐户密码” 。
确保在数据库目录中具有读或写权限的唯一Unix用户帐户是用于运行 mysqld 的帐户 。
永远不要以Unix
root
用户
身份运行MySQL服务器
。
这是非常危险的,因为具有该
FILE
权限的
任何用户
都能够使服务器创建文件
root
(例如,
~root/.bashrc
)。
为了防止这种情况,
除非使用该
选项
明确指定
,
否则
mysqld
拒绝运行
。
root
--user=root
mysqld
可以(而且应该)作为普通的非特权用户运行。
您可以创建一个单独的Unix帐户,以
mysql
使一切更加安全。
仅将此帐户用于管理MySQL。
要
以不同的Unix用户身份
启动
mysqld
,请添加一个
user
选项,
[mysqld]
该
my.cnf
选项指定用于指定服务器选项
的
选项文件
组中的
用户名
。
例如:
的[mysqld] 用户= MySQL的
这会导致服务器以指定用户身份启动,无论是手动启动还是使用 mysqld_safe 或 mysql.server 启动它 。 有关更多详细信息,请参见 第6.1.5节“如何以普通用户身份运行MySQL” 。
将
mysqld
作为Unix用户
运行
root
并不意味着您需要更改
表中
的
root
用户名
user
。
MySQL帐户的用户名与Unix帐户的用户名无关
。
不要将
FILE
权限
授予
非管理用户。
具有此权限的任何用户都可以使用
mysqld
守护程序
的权限在文件系统中的任何位置编写文件
。
这包括服务器的数据目录,其中包含实现权限表的文件。
为了使
FILE
-privilege操作更安全一些,生成的文件
SELECT
... INTO
OUTFILE
不会覆盖现有文件,并且每个人都可以写入。
该
FILE
特权还可用于读取服务器运行的Unix用户可以访问或访问的任何文件。
使用此权限,您可以将任何文件读入数据库表。
这可能会被滥用,例如,通过使用
LOAD
DATA
加载
/etc/passwd
到表中,然后可以显示
SELECT
。
要限制可以读取和写入文件的位置,请将
secure_file_priv
系统设置为特定目录。
请参见
第5.1.8节“服务器系统变量”
。
加密二进制日志文件和中继日志文件。
加密有助于保护这些文件及其中包含的潜在敏感数据免受外部攻击者的滥用,以及存储它们的操作系统用户的未授权查看。
通过将
binlog_encryption
系统变量
设置为,可以在MySQL服务器上启用加密
ON
。
有关更多信息,请参见
第17.3.10节“加密二进制日志文件和中继日志文件”
。
不要
向非管理用户
授予
PROCESS
或
SUPER
特权。
mysqladmin processlist
的输出
并
SHOW
PROCESSLIST
显示当前正在执行的任何语句的文本,因此任何被允许查看服务器进程列表的用户都可以看到其他用户发出的语句。
mysqld
为拥有
CONNECTION_ADMIN
或
SUPER
特权的
用户保留额外的连接
,这样
root
即使所有正常连接都在使用
,MySQL
用户也可以登录并检查服务器活动。
该
SUPER
权限可用于终止客户端连接,通过更改系统变量的值来更改服务器操作,以及控制复制服务器。
不允许对表使用符号链接。
(此功能可通过禁用
--skip-symbolic-links
选项。)如果您运行,这一点尤其重要
的mysqld
为
root
,因为有写访问到服务器的数据目录,然后任何人都可以在系统中删除任何文件!
请参见
第8.12.2.2节“在Unix上使用MyISAM表的符号链接”
。
应使用 第24.6节“存储对象访问控制”中 讨论的安全准则编写存储的程序和视图 。
如果您不信任您的DNS,则应在授权表中使用IP地址而不是主机名。 在任何情况下,您都应该非常小心地使用包含通配符的主机名值创建授权表条目。
如果要限制允许连接到单个帐户的连接数,可以通过
max_user_connections
在
mysqld中
设置
变量来实现
。
该
CREATE
USER
和
ALTER
USER
语句也支持资源控制选项来限制允许帐户服务器使用的程度。
请参见
第13.7.1.3节“创建用户语法”
和
第13.7.1.1节“更改用户语法”
。
如果服务器可以写入插件目录,则用户可以使用可执行代码将可执行代码写入目录中的文件
SELECT
... INTO DUMPFILE
。
这可以通过
plugin_dir
对服务器
进行
只读或通过设置
--secure-file-priv
到
SELECT
可以安全地
进行
写入
的目录
来防止
。
下表显示 了影响安全性的 mysqld 选项和系统变量。 有关其中每个的说明,请参见 第5.1.7节“服务器命令选项” 和 第5.1.8节“服务器系统变量” 。
表6.1安全选项和变量摘要
名称 | CMD线 | 选项文件 | 系统变量 | 状态变量 | Var范围 | 动态 |
---|---|---|---|---|---|---|
允许可疑-UDF的 | 是 | 是 | ||||
automatic_sp_privileges | 是 | 是 | 是 | 全球 | 是 | |
chroot环境 | 是 | 是 | ||||
DES密钥文件 | 是 | 是 | ||||
local_infile | 是 | 是 | 是 | 全球 | 是 | |
old_passwords | 是 | 是 | 是 | 都 | 是 | |
安全用户创建 | 是 | 是 | ||||
安全-AUTH | 是 | 是 | 全球 | 是 | ||
- 变量 : secure_auth | 是 | 全球 | 是 | |||
安全文件私法 | 是 | 是 | 全球 | 没有 | ||
- 变量 : secure_file_priv | 是 | 全球 | 没有 | |||
跳过赠款表 | 是 | 是 | ||||
跳过名称解析 | 是 | 是 | 全球 | 没有 | ||
- 变量 : skip_name_resolve | 是 | 全球 | 没有 | |||
跳过网络 | 是 | 是 | 全球 | 没有 | ||
- 变量 : skip_networking | 是 | 全球 | 没有 | |||
跳过出现数据库 | 是 | 是 | 全球 | 没有 | ||
- 变量 : skip_show_database | 是 | 全球 | 没有 |
在Windows上,您可以使用普通用户帐户将服务器作为Windows服务运行。
在Linux上,对于使用MySQL存储库或RPM软件包执行的安装,MySQL服务器
mysqld
应由本地
mysql
操作系统用户启动。
从另一个操作系统用户开始,作为MySQL存储库的一部分包含的init脚本不支持该用户。
在Unix(或用于使用
tar.gz
软件包
执行的安装的Linux
)上,MySQL服务器
mysqld
可以由任何用户启动和运行。
但是,
root
出于安全原因
,应避免以Unix
用户
身份运行服务器
。
要将
mysqld
更改
为以普通的非特权Unix用户身份运行
user_name
,您必须执行以下操作:
如果服务器正在运行,请停止服务器(使用 mysqladmin shutdown )。
更改数据库目录和文件,以便
user_name
具有读取和写入文件的权限(您可能需要以Unix
root
用户
身份执行此
操作):
外壳> chown -R user_name
/path/to/mysql/datadir
如果不这样做,服务器在运行时将无法访问数据库或表
user_name
。
如果MySQL数据目录中的目录或文件是符号链接,则
chown -R
可能不会跟随符号链接。
如果没有,您还需要关注这些链接并更改它们指向的目录和文件。
以用户身份启动服务器
user_name
。
另一种方法是启动
mysqld
作为Unix
root
用户并使用该
选项。
mysqld
启动,然后
在接受任何连接之前
切换为以Unix用户身份运行
。
--user=
user_name
user_name
要在系统启动时自动以给定用户身份启动服务器,请通过向
选项文件
组
或
服务器数据目录
中的
选项文件
添加
user
选项来
指定用户名
。
例如:
[mysqld]
/etc/my.cnf
my.cnf
的[mysqld]
用户=user_name
如果你的Unix机器本身不安全,你应该
root
在授权表中
为MySQL
帐户
分配密码
。
否则,在该计算机上具有登录帐户的任何用户都可以
使用
选项
运行
mysql
客户端
--user=root
并执行任何操作。
(在任何情况下,最好将密码分配给MySQL帐户,但在服务器主机上存在其他登录帐户时尤其如此。)请参见
第2.10.4节“保护初始MySQL帐户”
。
该
LOAD
DATA
语句可以加载位于服务器主机上的文件,或者,如果
LOCAL
指定
了
关键字
,则加载
在客户端主机上。
有与两个潜在的安全问题
LOCAL
的版本
LOAD
DATA
:
从客户端主机到服务器主机的文件传输由MySQL服务器启动。
理论上,可以构建修补的服务器,该服务器将告诉客户端程序传输服务器选择的文件而不是
LOAD
DATA
语句中
客户端指定的文件
。
这样的服务器可以访问客户端用户具有读访问权限的客户端主机上的任何文件。
(补丁服务器实际上可以回复任何语句的文件传输请求,而不仅仅是
LOAD
DATA
LOCAL
,因此更基本的问题是客户端不应该连接到不受信任的服务器。)
在客户端从Web服务器连接的Web环境中,用户可以使用
LOAD
DATA
LOCAL
读取Web服务器进程具有读访问权限的任何文件(假设用户可以对SQL服务器运行任何语句)。
在此环境中,与MySQL服务器相关的客户端实际上是Web服务器,而不是由连接到Web服务器的用户运行的远程程序。
为避免出现
LOAD
DATA
问题,客户应避免使用
LOCAL
。
为避免连接到不受信任的服务器,客户端可以通过使用
--ssl-mode=VERIFY_IDENTITY
选项和相应的CA证书
进行连接来建立安全连接并验证服务器标识
。
要使管理员和应用程序能够管理本地数据加载功能,
LOCAL
配置的工作方式如下:
在服务器端:
所述
local_infile
系统变量控制服务器端
LOCAL
的能力。
根据
local_infile
设置,服务器拒绝或允许客户端
LOCAL
启用的客户端
加载本地数据
。
默认情况下,
local_infile
已禁用。
要显式地使服务器拒绝或允许
LOAD
DATA
LOCAL
语句(无论在构建时或运行时如何配置客户端程序和库)
,分别启用
具有
禁用或启用的
mysqld
local_infile
。
local_infile
也可以在运行时设置。
在客户端:
该
CMake的
选项控制编译默认
的MySQL客户端库的能力。
因此,没有明确安排的客户端会
根据
MySQL构建时指定
的
设置
禁用或启用功能
。
ENABLED_LOCAL_INFILE
LOCAL
LOCAL
ENABLED_LOCAL_INFILE
默认情况下,MySQL二进制发行版中的客户端库是使用
ENABLED_LOCAL_INFILE
disabled
编译的
。
如果从源代码编译MySQL,则
ENABLED_LOCAL_INFILE
根据未进行显式排列的客户端是否应
LOCAL
分别禁用或启用功能,将其配置为禁用或启用。
使用C API的客户端程序可以通过调用
mysql_options()
禁用或启用该
MYSQL_OPT_LOCAL_INFILE
选项
来
显式控制加载数据加载
。
请参见
第28.7.7.50节“mysql_options()”
。
对于
mysql
客户端,默认情况下禁用本地数据加载。
要显式禁用或启用它,请使用
--local-infile=0
或
--local-infile[=1]
选项。
对于
mysqlimport
客户端,默认情况下禁用本地数据加载。
要显式禁用或启用它,请使用
--local=0
或
--local[=1]
选项。
如果您
LOAD
DATA LOCAL
在Perl脚本或
[client]
从选项文件
中读取
组的
其他程序中使用,则可以向该
组添加
local-infile
选项设置。
要防止不理解此选项的程序出现问题,请使用
loose-
前缀
指定它
:
[客户] 松和本地的infile = 0
要么:
[客户] 松和本地的infile = 1
在所有情况下,
LOCAL
客户端
成功使用
加载操作也需要服务器允许它。
如果
LOCAL
禁用功能,则在服务器或客户端上,尝试发出
LOAD
DATA
LOCAL
语句
的客户端会
收到以下错误消息:
错误1148:此MySQL版本不允许使用used命令
访问MySQL的应用程序不应该信任用户输入的任何数据,用户可以通过在Web表单,URL或您构建的任何应用程序中输入特殊或转义的字符序列来欺骗您的代码。
如果用户输入类似内容,请确保您的应用程序保持安全
; DROP DATABASE
mysql;
。
这是一个极端的例子,但是如果你没有为它们做准备,黑客可能会使用类似的技术来发生大量的安全漏洞和数据丢失。
常见的错误是仅保护字符串数据值。
记得也要检查数字数据。
如果应用程序生成查询(例如,
SELECT * FROM table WHERE ID=234
当用户输入值时)
234
,则用户可以输入该值
234 OR 1=1
以使应用程序生成查询
SELECT * FROM table WHERE ID=234 OR
1=1
。
结果,服务器检索表中的每一行。
这会暴露每一行并导致过多的服务器负载。
防止此类攻击的最简单方法是在数字常量周围使用单引号:
SELECT * FROM table WHERE ID='234'
。
如果用户输入额外信息,则它们都成为字符串的一部分。
在数字上下文中,MySQL会自动将此字符串转换为数字,并从中删除任何尾随的非数字字符。
有时人们会认为,如果数据库只包含公开可用的数据,则无需受到保护。 这是不正确的。 即使允许在数据库中显示任何行,您仍应该防止拒绝服务攻击(例如,那些基于前一段中导致服务器浪费资源的技术的攻击)。 否则,您的服务器将无法响应合法用户。
清单:
启用严格SQL模式以告知服务器对其接受的数据值有更多限制。 请参见 第5.1.11节“服务器SQL模式” 。
尝试
在所有Web表单中
输入单引号和双引号(
'
和
"
)。
如果您遇到任何类型的MySQL错误,请立即调查此问题。
尝试通过向它们添加
%22
(
"
),
%23
(
#
)和
%27
(
'
)来
修改动态URL
。
尝试使用前面示例中显示的字符将动态URL中的数据类型从数字类型修改为字符类型。 您的应用程序应该可以安全抵御这些和类似的攻击
尝试输入字符,空格和特殊符号,而不是数字字段中的数字。 您的应用程序应该在将它们传递给MySQL之前删除它们,否则会生成错误。 将未经检查的值传递给MySQL非常危险!
在将数据传递给MySQL之前检查数据的大小。
使用与用于管理目的的用户名不同的用户名将应用程序连接到数据库。 不要为您的应用程序提供他们不需要的任何访问权限。
许多应用程序编程接口提供了一种在数据值中转义特殊字符的方法。 正确使用,这可以防止应用程序用户输入导致应用程序生成具有与您想要的效果不同的语句的值:
MySQL C API:使用
mysql_real_escape_string_quote()
API调用。
MySQL ++:
对查询流
使用
escape
和
quote
修饰符。
PHP:使用
mysqli
或
pdo_mysql
扩展名,而不是旧的
ext/mysql
扩展名。
首选API支持改进的MySQL身份验证协议和密码,以及带有占位符的预处理语句。
另请参阅
选择API
。
如果
ext/mysql
必须使用
较旧的
扩展名,那么为了转义使用该
mysql_real_escape_string_quote()
函数而不是
mysql_escape_string()
或
addslashes()
因为只有
mysql_real_escape_string_quote()
字符集感知;
使用(无效)多字节字符集时,
可以
“
绕过
”
其他功能
。
Perl DBI:使用占位符或
quote()
方法。
Ruby DBI:使用占位符或
quote()
方法。
Java JDBC:使用
PreparedStatement
对象和占位符。
其他编程接口可能具有类似的功能。
MySQL允许创建允许客户端用户连接到服务器并访问服务器管理的数据的帐户。
MySQL权限系统的主要功能是验证谁从给定主机连接用户,并与特权用户数据库如联想
SELECT
,
INSERT
,
UPDATE
,和
DELETE
。
其他功能包括为管理操作授予权限的功能。
要控制哪些用户可以连接,可以为每个帐户分配身份验证凭据,例如密码。
用户界面MySQL账户由SQL语句如
CREATE
USER
,
GRANT
和
REVOKE
。
请参见
第13.7.1节“帐户管理语句”
。
MySQL权限系统确保所有用户只能执行允许的操作。 作为用户,当您连接到MySQL服务器时,您的身份由 您连接的主机 和 您指定的用户名决定 。 在连接后发出请求时,系统会根据您的身份和 您要执行的操作 授予权限 。
MySQL会同时识别您的主机名和用户名,因为没有理由认为给定的用户名属于所有主机上的同一个人。
例如,
joe
连接
的用户
office.example.com
不必是与
joe
连接
的用户相同的人
home.example.com
。
MySQL的,使您能够区分上碰巧有相同的名称不同的主机用户来处理它:你可以通过授予一组的连接权限
joe
从
office.example.com
,并通过连接一组不同的权限
joe
从
home.example.com
。
要查看给定帐户具有的权限,请使用该
SHOW
GRANTS
语句。
例如:
为'joe'@'office.example.com'显示资助'; 为'joe'@'home.example.com'显示资助';
在内部,服务器将特权信息存储在
mysql
系统数据库
的授权表中
。
MySQL服务器在启动时将这些表的内容读入内存,并根据授权表的内存中副本建立访问控制决策。
当您运行连接到服务器的客户端程序时,MySQL访问控制涉及两个阶段:
阶段1: 服务器根据您的身份接受或拒绝连接,以及您是否可以通过提供正确的密码来验证您的身份。
阶段2:
假设您可以连接,服务器会检查您发出的每个语句,以确定您是否具有足够的权限来执行它。
例如,如果尝试从数据库中的表中选择行或从数据库中删除表,则服务器会验证您是否具有
SELECT
该表的
DROP
权限
或
数据库
的
权限。
有关每个阶段所发生情况的更详细说明,请参见 第6.2.6节“访问控制,第1阶段:连接验证” 和 第6.2.7节“访问控制,第2阶段:请求验证” 。 有关诊断与权限相关的问题的帮助,请参见 第6.2.21节“连接到MySQL的问题疑难解答” 。
如果在连接时更改了您的权限(由您自己或其他人),则这些更改不一定会立即生效,以用于您发出的下一个语句。 有关服务器重新加载授权表的条件的详细信息,请参见 第6.2.13节“特权更改生效时” 。
有些事情你不能用MySQL特权系统做:
您无法明确指定应拒绝给定用户访问。 也就是说,您无法明确匹配用户,然后拒绝连接。
您不能指定用户具有在数据库中创建或删除表的权限,但不能指定创建或删除数据库本身的权限。
密码全局适用于帐户。 您无法将密码与特定对象(如数据库,表或例程)相关联。
MySQL将帐户存储在
系统数据库
的
user
表中
mysql
。
帐户是根据用户名和用户可以从中连接到服务器的客户端主机定义的。
有关
user
表中
帐户表示的信息
,请参见
第6.2.3节“授予表”
。
帐户还可能具有身份验证凭据,例如密码。 凭据由帐户身份验证插件处理。 MySQL支持多种身份验证插件。 其中一些使用内置身份验证方法,而其他人则使用外部身份验证方法启用身份验证。 请参见 第6.2.17节“可插入验证” 。
MySQL和您的操作系统使用用户名和密码的方式有几点不同:
MySQL用于身份验证的用户名与Windows或Unix使用的用户名(登录名)无关。
在Unix上,大多数MySQL客户端默认尝试使用当前的Unix用户名作为MySQL用户名登录,但这只是为了方便起见。
可以轻松覆盖默认值,因为客户端程序允许使用
-u
或
--user
选项
指定任何用户名
。
这意味着任何人都可以尝试使用任何用户名连接到服务器,因此除非所有MySQL帐户都有密码,否则无法以任何方式使数据库安全。
为没有密码的帐户指定用户名的任何人都可以成功连接到服务器。
MySQL用户名最长为32个字符。 操作系统用户名可能具有不同的最大长度。
MySQL用户名长度限制在MySQL服务器和客户端中是硬编码的,并且试图通过修改
mysql
数据库
中表的定义来绕过它是
行不通的
。
mysql
除非通过
第2.11节“升级MySQL”中
描述的过程,否则
不应
以任何方式
更改
数据库
中表的结构
。
尝试以任何其他方式重新定义MySQL的系统表会导致未定义和不受支持的行为。
服务器可以自由忽略由于此类修改而变得格式错误的行。
要对使用内置身份验证方法的帐户的客户端连接进行身份验证,服务器将使用存储在
user
表中的
密码
。
这些密码与登录操作系统的密码不同。
用于登录Windows或Unix计算机
的
“
外部
”
密码与用于访问该计算机上的MySQL服务器的密码
之间没有必要的连接
。
如果服务器使用其他插件对客户端进行身份验证,则插件实现的身份验证方法可能会也可能不会使用存储在
user
表中
的密码
。
在这种情况下,外部密码也可能用于向MySQL服务器进行身份验证。
存储在
user
表中的密码使用特定
于
插件的算法进行加密。
如果用户名和密码仅包含ASCII字符,则无论字符集设置如何,都可以连接到服务器。
要在用户名或密码包含非ASCII字符时启用连接,客户端应用程序应
mysql_options()
使用
MYSQL_SET_CHARSET_NAME
选项和相应的字符集名称作为参数
调用
C API函数
。
这会导致使用指定的字符集进行身份验证。
否则,除非服务器默认字符集与身份验证默认值中的编码相同,否则身份验证将失败。
标准MySQL客户端程序支持一个
--default-character-set
导致如上所述
mysql_options()
调用
的
选项
。
此外,还支持字符集自动检测,如
第10.4节“连接字符集和排序”中所述
。
对于使用不基于C API的连接器的程序,连接器可以提供与
mysql_options()
可以使用
的连接器等效的连接器
。
检查连接器文档。
前面的注释不适用于
ucs2
,
utf16
和
utf32
,不允许作为客户端字符集。
MySQL安装过程使用初始
root
帐户
填充授权表
,如
第2.10.4节“保护初始MySQL帐户”中所述
,其中还讨论了如何为其分配密码。
此后,你通常建立,修改和删除MySQL账户使用语句,例如
CREATE
USER
,
DROP
USER
,
GRANT
,和
REVOKE
。
请参见
第6.2.8节“添加帐户,分配权限和删除帐户”
和
第13.7.1节“帐户管理语句”
。
要使用命令行客户端连接到MySQL服务器,请根据需要为要使用的帐户指定用户名和密码选项:
外壳> mysql --user=finley --password db_name
如果您更喜欢短选项,则命令如下所示:
外壳> mysql -u finley -p db_name
如果省略
命令行上
的
--password
或
-p
选项
后面的密码值
(如刚才所示),则客户端会提示
输入密码值
。
或者,可以在命令行上指定密码:
shell> shell>mysql --user=finley --password=
password
db_name
mysql -u finley -p
password
db_name
如果使用该
-p
选项,则
密码值和以下密码值
之间
必须
没有空格
-p
。
在命令行上指定密码应该被认为是不安全的。 请参见 第6.1.2.1节“密码安全的最终用户指南” 。 要避免在命令行上输入密码,请使用选项文件或登录路径文件。 请参见 第4.2.2.2节“使用选项文件” 和 第4.6.7节“ mysql_config_editor - MySQL配置实用程序” 。
有关指定用户名,密码和其他连接参数的其他信息,请参见 第4.2.3节“连接到MySQL服务器” 。
授予MySQL帐户的权限决定了帐户可以执行的操作。 MySQL权限在它们适用的上下文和不同操作级别上有所不同:
管理权限使用户能够管理MySQL服务器的操作。 这些权限是全局的,因为它们不是特定于特定数据库的。
数据库权限适用于数据库及其中的所有对象。 可以为特定数据库或全局授予这些权限,以便它们适用于所有数据库。
可以为数据库中的特定对象,数据库中给定类型的所有对象(例如,数据库中的所有表)或全局的所有对象授予数据库对象(如表,索引,视图和存储例程)的权限。所有数据库中给定类型的对象。
权限在静态(内置到服务器)或动态(在运行时定义)方面也有所不同。 权限是静态还是动态会影响其授予用户帐户和角色的可用性。 有关静态和动态权限之间差异的信息,请参阅 静态与动态权限 。)
有关帐户权限的信息存储在
mysql
系统数据库
的授权表中
。
有关这些表的结构和内容的说明,请参见
第6.2.3节“授权表”
。
MySQL服务器在启动时将内容读取到内存中,并在
第6.2.13节“权限更改生效时”中
指示的情况下重新加载它们
。
服务器基于授权表的内存中副本建立访问控制决策。
一些MySQL版本引入了对授权表的更改以添加新的特权或功能。 要确保您可以利用任何新功能,请在升级MySQL时将授权表更新为当前结构。 请参见 第2.11节“升级MySQL” 。
以下部分总结了可用权限,提供了有关每个权限的更详细说明以及提供使用指南。
下表显示了
GRANT
和
REVOKE
语句中
使用的静态特权名称
,以及与授权表中的每个特权关联的列名以及特权适用的上下文。
表6.2 GRANT和REVOKE的允许静态权限
特权 | 授予表格列 | 上下文 |
---|---|---|
ALL [PRIVILEGES] |
“ all privileges ”的 同义词 | 服务器管理 |
ALTER |
Alter_priv |
表 |
ALTER ROUTINE |
Alter_routine_priv |
存储例程 |
CREATE |
Create_priv |
数据库,表或索引 |
CREATE ROLE |
Create_role_priv |
服务器管理 |
CREATE
ROUTINE |
Create_routine_priv |
存储例程 |
CREATE
TABLESPACE |
Create_tablespace_priv |
服务器管理 |
CREATE
TEMPORARY TABLES |
Create_tmp_table_priv |
表 |
CREATE USER |
Create_user_priv |
服务器管理 |
CREATE VIEW |
Create_view_priv |
查看 |
DELETE |
Delete_priv |
表 |
DROP |
Drop_priv |
数据库,表或视图 |
DROP ROLE |
Drop_role_priv |
服务器管理 |
EVENT |
Event_priv |
数据库 |
EXECUTE |
Execute_priv |
存储例程 |
FILE |
File_priv |
服务器主机上的文件访问 |
GRANT OPTION |
Grant_priv |
数据库,表或存储例程 |
INDEX |
Index_priv |
表 |
INSERT |
Insert_priv |
表或列 |
LOCK TABLES |
Lock_tables_priv |
数据库 |
PROCESS |
Process_priv |
服务器管理 |
PROXY |
请参阅
proxies_priv
表
|
服务器管理 |
REFERENCES |
References_priv |
数据库或表 |
RELOAD |
Reload_priv |
服务器管理 |
REPLICATION
CLIENT |
Repl_client_priv |
服务器管理 |
REPLICATION
SLAVE |
Repl_slave_priv |
服务器管理 |
SELECT |
Select_priv |
表或列 |
SHOW
DATABASES |
Show_db_priv |
服务器管理 |
SHOW VIEW |
Show_view_priv |
查看 |
SHUTDOWN |
Shutdown_priv |
服务器管理 |
SUPER |
Super_priv |
服务器管理 |
TRIGGER |
Trigger_priv |
表 |
UPDATE |
Update_priv |
表或列 |
USAGE |
“ no privileges ”的 同义词 | 服务器管理 |
下表显示了
GRANT
和
REVOKE
语句中
使用的动态权限名称
,以及权限适用的上下文。
表6.3 GRANT和REVOKE的允许动态权限
特权 | 上下文 |
---|---|
APPLICATION_PASSWORD_ADMIN |
双密码管理 |
AUDIT_ADMIN |
审核日志管理 |
BACKUP_ADMIN |
备份管理 |
BINLOG_ADMIN |
备份和复制管理 |
BINLOG_ENCRYPTION_ADMIN |
备份和复制管理 |
CONNECTION_ADMIN |
服务器管理 |
ENCRYPTION_KEY_ADMIN |
服务器管理 |
FIREWALL_ADMIN |
防火墙管理 |
FIREWALL_USER |
防火墙管理 |
GROUP_REPLICATION_ADMIN |
复制管理 |
PERSIST_RO_VARIABLES_ADMIN |
服务器管理 |
REPLICATION_SLAVE_ADMIN |
复制管理 |
RESOURCE_GROUP_ADMIN |
资源组管理 |
RESOURCE_GROUP_USER |
资源组管理 |
ROLE_ADMIN |
服务器管理 |
SESSION_VARIABLES_ADMIN |
服务器管理 |
SET_USER_ID |
服务器管理 |
SYSTEM_USER |
服务器管理 |
SYSTEM_VARIABLES_ADMIN |
服务器管理 |
TABLE_ENCRYPTION_ADMIN |
服务器管理 |
VERSION_TOKEN_ADMIN |
服务器管理 |
XA_RECOVER_ADMIN |
服务器管理 |
与在运行时定义的动态权限相比,静态权限内置于服务器中。 以下列表描述了MySQL中可用的每个静态特权。
特定的SQL语句可能具有比此处指示的更具体的权限要求。 如果是,则有关语句的描述提供了详细信息。
这些权限说明符的简写
“
可在给定的权限级别的所有权限
”
(除
GRANT OPTION
)。
例如,
ALL
在全局或表级别授予分别授予所有全局特权或所有表级特权。
允许使用该
ALTER
TABLE
语句来更改表的结构。
ALTER
TABLE
还需要
CREATE
和
INSERT
特权。
重命名表需要
ALTER
和
DROP
对旧表,
CREATE
以及
INSERT
对新表。
允许使用更改或删除存储例程(存储过程和函数)的语句。
允许使用创建新数据库和表的语句。
允许使用该
CREATE
ROLE
语句。
(该
CREATE
USER
权限还允许使用该
CREATE
ROLE
语句。)请参见
第6.2.10节“使用角色”
。
在
CREATE ROLE
和
DROP ROLE
特权的不那么强大
CREATE USER
,因为它们只能用于创建和删除帐户。
它们不能用作
CREATE
USER
修改帐户属性或重命名帐户。
请参阅
用户和角色互换性
。
允许使用创建存储例程(存储过程和函数)的语句。
允许使用创建,更改或删除表空间和日志文件组的语句。
允许使用该
CREATE TEMPORARY TABLE
语句
创建临时表
。
会话创建临时表后,服务器不会对表执行进一步的权限检查。
所述创建会话可以在桌子上进行任何操作,例如
DROP
TABLE
,
INSERT
,
UPDATE
,或
SELECT
。
有关更多信息,请参见
第13.1.20.3节“CREATE TEMPORARY TABLE语法”
。
允许使用的
ALTER
USER
,
CREATE
ROLE
,
CREATE
USER
,
DROP
ROLE
,
DROP
USER
,
RENAME
USER
,和
REVOKE
ALL
PRIVILEGES
语句。
允许使用该
CREATE
VIEW
语句。
允许从数据库中的表中删除行。
允许使用删除(删除)现有数据库,表和视图的语句。
在分区表上
DROP
使用该
ALTER TABLE ... DROP PARTITION
语句
需要
该
特权
。
该
DROP
也需要特权
TRUNCATE
TABLE
。
允许使用该
DROP
ROLE
语句。
(该
CREATE USER
权限还允许使用该
DROP
ROLE
语句。)请参见
第6.2.10节“使用角色”
。
在
CREATE ROLE
和
DROP ROLE
特权的不那么强大
CREATE USER
,因为它们只能用于创建和删除帐户。
它们不能用作
CREATE
USER
修改帐户属性或重命名帐户。
请参阅
用户和角色互换性
。
允许使用为事件调度程序创建,更改,删除或显示事件的语句。
允许使用执行存储例程(存储过程和函数)的语句。
影响以下操作和服务器行为:
使用
LOAD
DATA
和
SELECT
...
INTO OUTFILE
语句和
LOAD_FILE()
函数
启用在服务器主机上读取和写入文件
。
拥有该
FILE
权限的
用户
可以读取服务器主机上的任何文件,该文件是世界可读的或MySQL服务器可读的。
(这意味着用户可以读取任何数据库目录中的任何文件,因为服务器可以访问任何这些文件。)
允许在MySQL服务器具有写访问权限的任何目录中创建新文件。 这包括服务器的数据目录,其中包含实现权限表的文件。
允许
对
语句
使用
DATA DIRECTORY
or
INDEX DIRECTORY
table选项
CREATE
TABLE
。
作为安全措施,服务器不会覆盖现有文件。
要限制可以读取和写入文件的位置,请将
secure_file_priv
系统变量设置为特定目录。
请参见
第5.1.8节“服务器系统变量”
。
允许您向其他用户授予或撤消您自己拥有的权限。
允许使用创建或删除(删除)索引的语句。
INDEX
适用于现有表格。
如果您拥有
CREATE
表
的
权限,则可以在
CREATE
TABLE
语句中
包含索引定义
。
允许将行插入数据库中的表。
INSERT
还需要对
ANALYZE
TABLE
,
OPTIMIZE
TABLE
和
REPAIR
TABLE
表维护语句。
允许使用显式
LOCK
TABLES
语句来锁定您具有该
SELECT
权限的表。
这包括使用写锁定,这可以防止其他会话读取锁定的表。
允许显示有关服务器内执行的线程的信息(即有关会话正在执行的语句的信息)。
该权限允许使用
SHOW PROCESSLIST
或
mysqladmin进程列表
来查看属于其他帐户的线程;
你总能看到自己的主题。
该
PROCESS
权限还可以使用
SHOW
ENGINE
。
允许一个用户模拟或被称为另一个用户。 请参见 第6.2.18节“代理用户” 。
创建外键约束需要
REFERENCES
父表
的
权限。
允许使用该
FLUSH
语句。
这也使
中mysqladmin
等效于命令
FLUSH
操作:
flush-hosts
,
flush-logs
,
flush-privileges
,
flush-status
,
flush-tables
,
flush-threads
,
refresh
,和
reload
。
该
reload
命令告诉服务器将授权表重新加载到内存中。
flush-privileges
是...的同义词
reload
。
该
refresh
命令将关闭并重新打开日志文件并刷新所有表。
其他
命令执行类似
但更具体的
功能
,并且在某些情况下可能是优选的。
例如,如果要仅刷新日志文件,
则是比较好的选择
。
flush-
xxx
refresh
flush-logs
refresh
该
RELOAD
权限还允许使用
RESET
MASTER
和
RESET
SLAVE
语句。
允许使用的
SHOW MASTER
STATUS
,
SHOW SLAVE
STATUS
和
SHOW BINARY
LOGS
语句。
将此权限授予从服务器用于连接到当前服务器作为其主服务器的帐户。
启用请求已作出对数据库的主服务器上的更新,使用的帐户
SHOW SLAVE HOSTS
,
SHOW RELAYLOG EVENTS
和
SHOW
BINLOG EVENTS
语句。
使用
mysqlbinlog
选项
--read-from-remote-server
(
-R
)和时,
也需要此权限
--read-from-remote-master
。
将此权限授予从服务器用于连接到当前服务器作为其主服务器的帐户。
允许从数据库中的表中选择行。
只有在实际访问表时,
SELECT
语句才需要该
SELECT
权限。
某些
SELECT
语句不访问表,并且可以在没有任何数据库许可的情况下执行。
例如,您可以使用
SELECT
简单的计算器来计算不引用表的表达式:
SELECT 1 + 1; SELECT PI()* 2;
SELECT
读取列值的其他语句也需要
该
特权。
例如,
SELECT
需要用于上的右侧引用列
col_name
=
expr
赋值
UPDATE
语句或用于在指定的列
WHERE
的条款
DELETE
或
UPDATE
语句。
通过发出
SHOW DATABASE
语句
使帐户能够查看数据库名称
。
没有此权限的帐户只能看到具有某些权限的数据库,如果使用该
--skip-show-database
选项
启动服务器,则根本无法使用该语句
。
因为任何静态全局特权被认为是所有数据库的特权,任何静态全局特权使用户能够看到所有的数据库名称
SHOW
DATABASES
或通过检查
SCHEMATA
表
INFORMATION_SCHEMA
,除了已经在通过局部撤销数据库级别被限制的数据库。
允许使用该
SHOW CREATE
VIEW
语句。
使用的视图也需要此权限
EXPLAIN
。
允许使用
SHUTDOWN
和
RESTART
语句,
mysqladmin shutdown
命令和
mysql_shutdown()
C API函数。
SUPER
是一种强大而深远的特权,不应轻视。
如果帐户只需要执行一部分
SUPER
操作,则可以通过授予一个或多个动态特权来实现所需的特权集,每个动态特权赋予更多有限的能力。
请参阅
动态权限说明
。
SUPER
已弃用,将在未来的MySQL版本中删除。
请参阅将
帐户从SUPER迁移到动态权限
。
SUPER
影响以下操作和服务器行为:
在运行时启用系统变量:
启用服务器的配置变化与全球系统变量
SET
GLOBAL
和
SET
PERSIST
。
相应的动态权限是
SYSTEM_VARIABLES_ADMIN
。
允许设置需要特殊权限的受限会话系统变量。
相应的动态权限是
SESSION_VARIABLES_ADMIN
。
另请参见 第5.1.9.1节“系统变量权限” 。
允许更改全局事务特征(请参见 第13.3.7节“SET TRANSACTION语法” )。
相应的动态权限是
SYSTEM_VARIABLES_ADMIN
。
使该帐户能够启动和停止复制,包括组复制。
对于组
REPLICATION_SLAVE_ADMIN
复制,
相应的动态权限
用于常规复制
GROUP_REPLICATION_ADMIN
。
允许使用
CHANGE
MASTER
TO
和
CHANGE REPLICATION
FILTER
语句。
相应的动态权限是
REPLICATION_SLAVE_ADMIN
。
通过
PURGE BINARY LOGS
和
BINLOG
语句
启用二进制日志控制
。
相应的动态权限是
BINLOG_ADMIN
。
允许在执行视图或存储程序时设置有效的授权ID。
具有此权限的用户可以在
DEFINER
视图或存储程序
的
属性中
指定任何帐户
。
相应的动态权限是
SET_USER_ID
。
允许使用的
CREATE
SERVER
,
ALTER
SERVER
和
DROP
SERVER
语句。
允许使用 mysqladmin debug 命令。
启用
InnoDB
加密密钥轮换。
相应的动态权限是
ENCRYPTION_KEY_ADMIN
。
允许执行版本标记用户定义的函数。
相应的动态权限是
VERSION_TOKEN_ADMIN
。
允许授予和撤消角色,使用
语句
的
WITH ADMIN OPTION
子句
GRANT
以及
函数
<graphml>
结果中的
非空
元素内容
ROLES_GRAPHML()
。
相应的动态权限是
ROLE_ADMIN
。
允许控制不允许非
SUPER
帐户的
客户端连接
:
允许使用
KILL
statement或
mysqladmin kill
命令来终止属于其他帐户的线程。
(帐户总是可以杀死自己的线程。)
客户端连接
init_connect
时
,服务器不执行
系统变量内容
SUPER
。
SUPER
即使
max_connections
达到系统变量
配置的连接限制
,服务器
也会
接受来自
客户端的
一个连接
。
处于脱机模式(已
offline_mode
启用)的服务器不会
SUPER
在下一个客户端请求时
终止
客户端连接,并接受来自
SUPER
客户端的
新连接
。
即使
read_only
启用
了
系统变量,
也可以执行更新
。
这适用于明确的表的更新,并使用账户管理语句如
GRANT
与
REVOKE
该更新的表隐。
前面的连接控制操作的相应动态特权是
CONNECTION_ADMIN
。
SUPER
如果启用了二进制日志记录,则
可能还需要
创建或更改存储函数
的
权限,如
第24.7节“存储程序二进制日志记录”中所述
。
启用触发器操作。 您必须拥有此表的权限才能创建,删除,执行或显示该表的触发器。
当触发器被激活(由谁拥有特权执行用户
INSERT
,
UPDATE
或
DELETE
与触发器关联的表的语句),触发器执行要求谁定义触发器的用户仍然有
TRIGGER
对表的特权。
允许在数据库中的表中更新行。
这个特权说明符代表
“
没有特权。
“
它在全局级别
GRANT
用于指定子句,例如
WITH GRANT OPTION
不在特权列表中命名特定帐户特权。
SHOW
GRANTS
显示
USAGE
以指示帐户在特权级别没有特权。
动态特权是在运行时定义的,与内置于服务器的静态特权形成对比。 以下列表描述了MySQL中可用的每个动态权限。
大多数动态权限在服务器启动时定义。 其他由特定服务器组件或插件定义,如权限说明中所示。 在这种情况下,除非启用了定义它的组件或插件,否则该特权不可用。
特定的SQL语句可能具有比此处指示的更具体的权限要求。 如果是,则有关语句的描述提供了详细信息。
APPLICATION_PASSWORD_ADMIN
(在MySQL 8.0.14中添加)
对于双密码功能,此权限允许使用
适用于您自己帐户
的
RETAIN CURRENT PASSWORD
和
DISCARD OLD PASSWORD
子句
ALTER
USER
以及
SET
PASSWORD
语句。
需要此权限才能操作您自己的二级密码,因为大多数用户只需要一个密码。
如果允许某个帐户操作所有帐户的辅助密码,则应授予其
CREATE USER
权限,而不是
APPLICATION_PASSWORD_ADMIN
。
有关使用双密码的更多信息,请参见 第6.2.15节“密码管理” 。
启用审核日志配置。
此权限由
audit_log
插件
定义
;
请参见
第6.4.5节“MySQL Enterprise Audit”
。
允许执行
LOCK INSTANCE
FOR BACKUP
语句并访问Performance Schema
log_status
表。
从早期版本执行就地升级到MySQL 8.0时,
该
BACKUP_ADMIN
权限会自动授予具有该
RELOAD
权限的
用户
。
通过
PURGE BINARY LOGS
和
BINLOG
语句
启用二进制日志控制
。
启用设置系统变量
binlog_encryption
,该
变量
可激活或取消激活二进制日志文件和中继日志文件的加密。
这种能力不是由提供
BINLOG_ADMIN
,
SYSTEM_VARIABLES_ADMIN
或
SESSION_VARIABLES_ADMIN
特权。
binlog_rotate_encryption_master_key_at_startup
重新启动服务器时自动旋转二进制日志主密钥
的相关系统变量
不需要此权限。
允许使用
KILL
statement或
mysqladmin kill
命令来终止属于其他帐户的线程。
(帐户总是可以杀死自己的线程。)
允许设置与客户端连接相关的系统变量,或绕过与客户端连接相关的限制。
CONNECTION_ADMIN
适用于这些系统变量的影响:
init_connect
:
客户端连接
init_connect
时
,服务器不执行
系统变量内容
CONNECTION_ADMIN
。
max_connections
:
CONNECTION_ADMIN
即使
max_connections
达到系统变量
配置的连接限制
,服务器
也会
接受来自
客户端的
一个连接
。
offline_mode
:处于脱机模式(已
offline_mode
启用)的服务器不会
CONNECTION_ADMIN
在下一个客户端请求时
终止
客户端连接,并接受来自
CONNECTION_ADMIN
客户端的
新连接
。
read_only
:即使
read_only
启用
了
系统变量,
也可以执行更新
。
这适用于明确的表的更新,并使用账户管理语句如
GRANT
与
REVOKE
该更新的表隐。
启用
InnoDB
加密密钥轮换。
允许用户管理任何用户的防火墙规则。
此权限由
MYSQL_FIREWALL
插件
定义
;
请参见
第6.4.7节“MySQL Enterprise Firewall”
。
使用户能够更新自己的防火墙规则。
此权限由
MYSQL_FIREWALL
插件
定义
;
请参见
第6.4.7节“MySQL Enterprise Firewall”
。
允许帐户使用
START GROUP
REPLICATION
和
STOP GROUP
REPLICATION
语句
启动和停止组复制
,更改
group_replication_consistency
系统变量
的全局设置
以及使用
group_replication_set_write_concurrency()
和
group_replication_set_communication_protocol()
UDF。
将此权限授予用于管理作为复制组成员的服务器的帐户。
对于也拥有的用户
SYSTEM_VARIABLES_ADMIN
,
PERSIST_RO_VARIABLES_ADMIN
可以使用
SET
PERSIST_ONLY
将全局系统变量持久保存到
mysqld-auto.cnf
数据目录中
的
选项文件。
此语句类似于
SET
PERSIST
但不修改运行时全局系统变量值。
这
SET
PERSIST_ONLY
适用于配置只能在服务器启动时设置的只读系统变量。
另请参见 第5.1.9.1节“系统变量权限” 。
允许帐户连接到主服务器,使用
START
SLAVE
和
STOP
SLAVE
语句
启动和停止复制
,并使用
CHANGE
MASTER TO
和
CHANGE
REPLICATION FILTER
语句。
将此权限授予从服务器用于连接到当前服务器作为其主服务器的帐户。
此权限不适用于组复制;
使用
GROUP_REPLICATION_ADMIN
了点。
启用资源组管理,包括创建,更改和删除资源组,以及将线程和语句分配给资源组。 具有此权限的用户可以执行与资源组相关的任何操作。
允许将线程和语句分配给资源组。
具有此权限的用户可以使用该
SET RESOURCE GROUP
语句和
RESOURCE_GROUP
优化程序提示。
允许授予和撤消角色,使用
语句
的
WITH ADMIN OPTION
子句
GRANT
以及
函数
<graphml>
结果中的
非空
元素内容
ROLES_GRAPHML()
。
需要设置
mandatory_roles
系统变量
的值
。
启用与仅允许管理连接的网络接口的连接(请参见 第8.12.4.1节“MySQL如何处理客户端连接” )。
SESSION_VARIABLES_ADMIN
(在MySQL 8.0.14中添加)
对于大多数系统变量,设置会话值不需要特殊权限,任何用户都可以使用它来影响当前会话。
对于某些系统变量,设置会话值可能会在当前会话之外产生影响,因此是受限制的操作。
对于这些,该
SESSION_VARIABLES_ADMIN
权限使用户能够设置会话值。
如果系统变量受限制并且需要特殊权限来设置会话值,则变量说明指示该限制。
实例包括
binlog_format
,
sql_log_bin
,和
sql_log_off
。
在添加MySQL 8.0.14之前,
SESSION_VARIABLES_ADMIN
只有具有
SYSTEM_VARIABLES_ADMIN
或
SUPER
特权的
用户才能设置受限制的会话系统变量
。
该
SESSION_VARIABLES_ADMIN
特权的一个子集
SYSTEM_VARIABLES_ADMIN
和
SUPER
特权。
具有这些特权之一的用户也被允许设置受限制的会话变量,并且有效地
SESSION_VARIABLES_ADMIN
暗示并且不需要
SESSION_VARIABLES_ADMIN
明确
授予
。
另请参见 第5.1.9.1节“系统变量权限” 。
允许在执行视图或存储程序时设置有效的授权ID。
具有此权限的用户可以在
DEFINER
视图或存储程序
的
属性中
指定任何帐户
。
SYSTEM_USER
(在MySQL 8.0.16中添加)
该
SYSTEM_USER
权限将系统用户与普通用户区分开来:
具有该
SYSTEM_USER
权限的用户是系统用户。
没有
SYSTEM_USER
权限的用户是普通用户。
该
SYSTEM_USER
权限对给定用户可以应用其他权限的帐户有影响,以及用户是否受到其他帐户的保护:
系统用户可以修改系统和常规帐户。
也就是说,拥有对常规帐户执行给定操作的适当权限的用户通过拥有
SYSTEM_USER
也可以对系统帐户执行操作来
启用
。
系统帐户只能由具有适当权限的系统用户修改,而不能由常规用户修改。
具有适当权限的常规用户可以修改常规帐户,但不能修改系统帐户。 具有适当权限的系统和常规用户都可以修改常规帐户。
有关更多信息,请参见 第6.2.11节“帐户类别” 。
通过
SYSTEM_USER
特权
提供给系统帐户的常规帐户的修改保护
不适用于具有
mysql
系统模式
特权的常规帐户,
因此可以直接修改该模式中的授权表。
要获得完全保护,请不要
mysql
向常规帐户
授予
架构权限。
请参阅
通过常规帐户保护系统帐户免受操纵
。
影响以下操作和服务器行为:
在运行时启用系统变量:
启用服务器的配置变化与全球系统变量
SET
GLOBAL
和
SET
PERSIST
。
SET
PERSIST_ONLY
如果用户也具有,则
允许将服务器配置更改为全局系统变量
PERSIST_RO_VARIABLES_ADMIN
。
允许设置需要特殊权限的受限会话系统变量。
实际上,
SYSTEM_VARIABLES_ADMIN
暗示
SESSION_VARIABLES_ADMIN
没有明确授予
SESSION_VARIABLES_ADMIN
。
另请参见 第5.1.9.1节“系统变量权限” 。
允许更改全局事务特征(请参见 第13.3.7节“SET TRANSACTION语法” )。
TABLE_ENCRYPTION_ADMIN
(在MySQL 8.0.16中添加)
启用后,允许用户覆盖默认加密设置
table_encryption_privilege_check
;
请参阅
为架构和常规表空间定义加密默认值
。
允许执行版本标记用户定义的函数。
此权限由
version_tokens
插件
定义
;
请参见
第5.6.6节“版本标记”
。
允许执行
XA
RECOVER
语句;
请参见
第13.3.8.1节“XA事务SQL语法”
。
在MySQL 8.0之前,任何用户都可以执行该
XA
RECOVER
语句来发现未完成的准备好的XA事务的XID值,这可能导致由启动它的用户以外的用户提交或回滚XA事务。
在MySQL 8.0中,
XA
RECOVER
只允许拥有该用户的用户使用
XA_RECOVER_ADMIN
特权,预计仅授予需要它的管理用户。
例如,如果XA应用程序的管理员崩溃并且有必要查找应用程序启动的未完成事务以便可以回滚它们,则可能就是这种情况。
此权限要求可防止用户发现除自己以外的未完成的准备XA事务的XID值。
它不会影响XA事务的正常提交或回滚,因为启动它的用户知道它的XID。
最好只向帐户授予它所需的权限。
在授予
FILE
和管理权限
时应特别小心
:
FILE
可以滥用MySQL服务器可以在服务器主机上读取的任何文件来读入数据库表。
这包括服务器数据目录中的所有世界可读文件和文件。
然后可以使用该表
SELECT
将其内容传输到客户端主机
来访问该表
。
GRANT OPTION
使用户能够将其权限授予其他用户。
具有不同权限和权限的两个用户
GRANT
OPTION
可以组合权限。
ALTER
可用于通过重命名表来破坏权限系统。
SHUTDOWN
可以滥用通过终止服务器完全拒绝向其他用户提供服务。
PROCESS
可用于查看当前正在执行的语句的纯文本,包括设置或更改密码的语句。
SUPER
可用于终止其他会话或更改服务器的运行方式。
为
mysql
系统数据库本身
授予的权限
可用于更改密码和其他访问权限信息:
MySQL支持静态和动态权限:
静态特权内置于服务器中。 它们始终可以授予用户帐户,并且无法取消注册。
动态特权可以在运行时注册和取消注册。 这会影响其可用性:无法授予尚未注册的动态权限。
例如,
SELECT
和
INSERT
权限是静态的并且始终可用,而动态权限仅在已启用实现它的服务器组件时才可用。
本节的其余部分将介绍动态权限在MySQL中的工作原理。 讨论使用术语 “ 组件 ”, 但同样适用于插件。
服务器管理员应该知道哪些服务器组件定义了动态权限。 对于MySQL发行版,定义动态权限的组件文档描述了这些权限。
第三方组件也可以定义动态权限; 管理员应该了解这些权限,而不是安装可能与服务器操作冲突或危害的组件。 例如,如果两个组件都定义了具有相同名称的权限,则一个组件与另一个组件冲突。 组件开发人员可以通过选择具有基于组件名称的前缀的权限名称来降低发生这种情况的可能性。
服务器在内存中维护已注册的动态权限集。 服务器关闭时发生取消注册。
通常,定义动态权限的服务器组件在其初始化序列期间在安装时注册它们。 卸载时,服务器组件不会取消注册其已注册的动态权限。 (这是当前的做法,而不是要求。也就是说,组件可以,但不能在任何时候取消注册它们注册的权限。)
尝试注册已注册的动态权限时不会出现警告或错误。 请考虑以下语句序列:
安装组件'my_component'; UNINSTALL COMPONENT'my_component'; 安装组件'my_component';
第一个
INSTALL
COMPONENT
语句注册服务器组件定义的任何权限
my_component
,但
UNINSTALL COMPONENT
不注销它们。
对于第二个
INSTALL
COMPONENT
语句,发现已注册的组件权限已经注册,但不会发生警告或错误。
动态权限仅适用于全局级别。
服务器将有关当前动态权限分配的信息存储到
mysql.global_grants
系统表
中的用户帐户
:
服务器自动注册
global_grants
在服务器启动期间
命名的权限
(除非
--skip-grant-tables
给出选项)。
列出的动态权限分配
global_grants
是持久的。
服务器关闭时不会删除它们。
示例:以下语句向用户授予
u1
控制从属服务器上的复制(包括组复制)以及修改系统变量所需的权限:
GRANT REPLICATION_SLAVE_ADMIN,GROUP_REPLICATION_ADMIN,BINLOG_ADMIN ON *。* TO'u1'@'localhost';
授权动态特权出现在
SHOW GRANTS
语句和
INFORMATION_SCHEMA
USER_PRIVILEGES
表
的输出
中。
对于
GRANT
并
REVOKE
在全球范围内,静态是针对当前的一组登记的动态权限检查,如果发现不授予任何公认的命名特权。
否则,将发生错误以指示未知的权限标识符。
对于
GRANT
和
REVOKE
意义
ALL [PRIVILEGES]
在全球范围包括所有静态全局权限,以及所有目前已登记的动态权限:
GRANT ALL
在全局级别授予所有静态全局特权和所有当前注册的动态特权。
在执行该
GRANT
语句
之后注册的动态权限
不会追溯授予任何帐户。
REVOKE ALL
在全局级别撤消所有授予的静态全局特权和所有授予的动态特权。
该
FLUSH PRIVILEGES
语句读取
global_grants
表以获取动态权限分配,并注册在那里找到的任何未注册权限。
有关MySQL发行版中包含的MySQL服务器和服务器组件提供的动态权限的说明,请参见 第6.2.2节“MySQL提供的权限” 。
在MySQL 8.0中,许多以前需要该
SUPER
权限的操作也与更有限范围的动态权限相关联。
(有关这些权限的说明,请参见
第6.2.2节“MySQL提供的权限”
。)通过授予关联的动态权限而不是,可以允许每个此类操作进入帐户
SUPER
。
此更改通过使DBA能够避免
SUPER
更
准确地授予
和定制用户权限
来提高安全性
。
SUPER
现已弃用,将在未来版本的MySQL中删除。
SUPER
发生
删除
时,
SUPER
除非已授予
SUPER
的
帐户
迁移到适当的动态权限,
否则
以前需要的操作
将失败
。
使用以下说明完成该目标,以便在
SUPER
删除
之前准备好帐户
:
执行此查询以标识已授予的帐户
SUPER
:
从INFORMATION_SCHEMA.USER_PRIVILEGES中选择GRANTEE WHERE PRIVILEGE_TYPE ='超级';
对于前面的查询标识的每个帐户,确定它需要的操作
SUPER
。
然后授予与这些操作对应的动态权限,并撤消
SUPER
。
例如,如果
'u1'@'localhost'
需要
SUPER
二进制日志清除和系统变量修改,则这些语句会对帐户进行必要的更改:
GRANT BINLOG_ADMIN,SYSTEM_VARIABLES_ADMIN ON *。* TO'u1'@'localhost'; REVOKE SUPER ON *。* FROM'u1'@'localhost';
修改完所有适用的帐户后,
INFORMATION_SCHEMA
第一步中
的
查询应生成一个空结果集。
该
mysql
系统数据库包括包含关于用户帐户和他们持有的特权信息的几个授权表。
本节介绍这些表。
有关系统数据库中其他表的信息,请参见
第5.3节“mysql系统模式”
。
此处的讨论描述了授权表的基础结构以及服务器在与客户端交互时如何使用其内容。
但是,通常不直接修改授权表。
当您使用帐户管理语句(例如
CREATE
USER
,
GRANT
)和
REVOKE
设置帐户并控制每个帐户可用的权限
时,间接会发生修改
。
请参见
第13.7.1节“帐户管理语句”
。
当您使用此类语句执行帐户操作时,服务器会代表您修改授权表。
使用诸如
,或者
不鼓励的
语句直接修改授权表
INSERT
,
并且风险自负。
服务器可以自由忽略由于此类修改而变得格式错误的行。
UPDATE
DELETE
对于修改授权表的任何操作,服务器检查该表是否具有预期结构,否则生成错误。 要将表更新为预期结构,请执行MySQL升级过程。 请参见 第2.11节“升级MySQL” 。
这些
mysql
数据库表包含授权信息:
user
:用户帐户,静态全局权限和其他非特权列。
global_grants
:动态全局权限。
db
:数据库级权限。
tables_priv
:表级权限。
columns_priv
:列级权限。
procs_priv
:存储过程和功能权限。
proxies_priv
:代理用户权限。
default_roles
:默认用户角色。
role_edges
:角色子图的边缘。
password_history
:密码更改历史记录。
有关静态和动态全局权限之间差异的信息,请参阅 静态与动态权限 。)
在MySQL 8.0中,授权表使用
InnoDB
存储引擎并且是事务性的。
在MySQL 8.0之前,授权表使用了
MyISAM
存储引擎并且是非事务性的。
授权表存储引擎的这种更改使得对帐户管理语句(例如
CREATE
USER
或)
的行为的伴随更改成为
可能
GRANT
。
以前,为多个用户命名的帐户管理语句可能会对某些用户成功,而对其他用户则失败。
现在,每个语句都是事务性的,并且对所有命名用户都成功或回滚,如果发生任何错误则无效。
每个授权表都包含范围列和特权列:
范围列确定表中每行的范围;
也就是说,行适用的上下文。
例如,一个
user
表行,其中包含
Host
和
User
值,
'h1.example.net'
并且
'bob'
适用于
h1.example.net
由指定用户名的客户端
从主机对服务器进行的身份验证的连接
bob
。
类似地,
db
表行包含
Host
,
User
和
Db
列值
'h1.example.net'
,
'bob'
并
'reports'
在
bob
从主机连接
h1.example.net
到访问
reports
数据库时应用。
该
tables_priv
和
columns_priv
表包含范围列,指示每行适用的表或表/列组合。
该
procs_priv
范围列表示存储程序到各行适用。
权限列指示表行授予的权限; 也就是说,它允许执行哪些操作。 服务器将各种授权表中的信息组合在一起,形成用户权限的完整描述。 第6.2.7节“访问控制,第2阶段:请求验证” ,描述了相关规则。
此外,授权表可能包含用于范围或特权评估之外的目的的列。
服务器以下列方式使用授权表:
的
user
表范围列确定是否拒绝或允许传入连接。
对于允许的连接,
user
表中
授予的任何权限都
表示用户的静态全局权限。
此表中授予的任何权限
都
适用于
服务器上的
所有
数据库。
因为任何静态全局特权被认为是所有数据库的特权,任何静态全局特权使用户能够看到所有的数据库名称
SHOW
DATABASES
或通过检查
SCHEMATA
表
INFORMATION_SCHEMA
,除了已经在通过局部撤销数据库级别被限制的数据库。
该
global_grants
表列出了当前对用户帐户的动态全局权限的分配。
对于每一行,作用域列确定哪个用户具有在权限列中指定的权限。
该
db
表范围列决定哪些用户可以访问哪些数据库从哪个主机。
权限列确定允许的操作。
在数据库级别授予的权限适用于数据库和数据库中的所有对象,例如表和存储的程序。
在
tables_priv
与
columns_priv
表类似于
db
表,但是更精致:他们在申请表和列级应用而非在数据库级。
表级别授予的权限适用于表及其所有列。
在列级别授予的权限仅适用于特定列。
该
procs_priv
表适用于存储的例程(存储过程和函数)。
在例程级别授予的权限仅适用于单个过程或函数。
该
proxies_priv
表指示哪些用户可以充当其他用户的代理以及用户是否可以将该
PROXY
特权
授予
其他用户。
在
default_roles
与
role_edges
表包含角色关系的信息。
该
password_history
表保留以前选择的密码以启用密码重用限制。
请参见
第6.2.15节“密码管理”
。
服务器在启动时将授权表的内容读入内存。
您可以通过发出
FLUSH PRIVILEGES
语句或执行
mysqladmin flush-privileges
来告诉它重新加载表
或
mysqladmin reload
命令
。
对授权表的更改将在
第6.2.13节“特权更改
生效时”中指示生效
。
修改帐户时,最好验证您的更改是否具有预期效果。
要检查给定帐户的权限,请使用该
SHOW
GRANTS
语句。
例如,要确定与用户名和主机名值授予一个帐户的权限
bob
和
pc84.example.com
使用下面的语句:
为'bob'@'pc84.example.com'展示奖学金;
要显示帐户的非特权属性,请使用
SHOW
CREATE USER
:
SHOW CREATE USER'bob'@'pc84.example.com';
服务器
在
访问控制的第一和第二阶段
使用
数据库中
的
user
和
db
表
mysql
(请参见
第6.2节“访问控制和帐户管理”
)。
这里显示
了
user
和
db
表中的列。
表6.4 user和db Table列
表名 | user |
db |
---|---|---|
范围列 | Host |
Host |
User |
Db |
|
User |
||
权限列 | Select_priv |
Select_priv |
Insert_priv |
Insert_priv |
|
Update_priv |
Update_priv |
|
Delete_priv |
Delete_priv |
|
Index_priv |
Index_priv |
|
Alter_priv |
Alter_priv |
|
Create_priv |
Create_priv |
|
Drop_priv |
Drop_priv |
|
Grant_priv |
Grant_priv |
|
Create_view_priv |
Create_view_priv |
|
Show_view_priv |
Show_view_priv |
|
Create_routine_priv |
Create_routine_priv |
|
Alter_routine_priv |
Alter_routine_priv |
|
Execute_priv |
Execute_priv |
|
Trigger_priv |
Trigger_priv |
|
Event_priv |
Event_priv |
|
Create_tmp_table_priv |
Create_tmp_table_priv |
|
Lock_tables_priv |
Lock_tables_priv |
|
References_priv |
References_priv |
|
Reload_priv |
||
Shutdown_priv |
||
Process_priv |
||
File_priv |
||
Show_db_priv |
||
Super_priv |
||
Repl_slave_priv |
||
Repl_client_priv |
||
Create_user_priv |
||
Create_tablespace_priv |
||
Create_role_priv |
||
Drop_role_priv |
||
安全专栏 | ssl_type |
|
ssl_cipher |
||
x509_issuer |
||
x509_subject |
||
plugin |
||
authentication_string |
||
password_expired |
||
password_last_changed |
||
password_lifetime |
||
account_locked |
||
Password_reuse_history |
||
Password_reuse_time |
||
Password_require_current |
||
User_attributes |
||
资源控制列 | max_questions |
|
max_updates |
||
max_connections |
||
max_user_connections |
该
user
表
plugin
和
authentication_string
列存储身份验证插件和证书信息。
服务器使用
plugin
帐户行列中
指定的插件
来验证帐户的连接尝试。
该
plugin
列必须是非空的。
在启动时,在运行时
FLUSH
PRIVILEGES
执行时,服务器会检查
user
表行。
对于具有空
plugin
列的
任何行
,服务器会向此表单的错误日志写入警告:
[警告]用户输入'user_name
'@'host_name
'有一个空的插件 值。用户将被忽略,没有人可以使用此用户登录 了。
要将插件分配给缺少一个的帐户,请使用
ALTER
USER
语句。
该
password_expired
列允许DBA使帐户密码到期,并要求用户重置其密码。
默认
password_expired
值为
'N'
,但可以
'Y'
使用
ALTER
USER
语句
设置
。
帐户密码过期后,帐户在后续服务器连接中执行的所有操作都会导致错误,直到用户发出
ALTER
USER
声明以建立新帐户密码。
密码过期后可以 通过将密码设置为当前值 来 “ 重置 ” 密码。 作为一个好的政策问题,最好选择不同的密码。 DBA可以通过建立适当的密码重用策略来强制执行非重用。 请参阅 密码重用策略 。
password_last_changed
是一个
TIMESTAMP
列,指示上次更改密码的时间。
该值为非
NULL
仅适用于使用MySQL内置的身份验证插件账户(
mysql_native_password
,
sha256_password
,或
caching_sha2_password
)。
该值适用
NULL
于其他帐户,例如使用外部身份验证系统进行身份验证的帐户。
password_last_changed
通过更新
CREATE
USER
,
ALTER
USER
和
SET
PASSWORD
报表,并通过
GRANT
创造一个帐户或更改帐户密码的语句。
password_lifetime
表示帐户密码生存期,以天为单位。
如果密码超过其生命周期(使用
password_last_changed
列
评估
),则服务器会在客户端使用该帐户连接时认为密码已过期。
值
N
大于零意味着必须每天更改密码
N
。
值为0将禁用自动密码到期。
如果值为
NULL
(缺省值),则应用全局过期策略,如
default_password_lifetime
系统变量
所定义
。
account_locked
指示帐户是否已锁定(请参见
第6.2.19节“帐户锁定”
)。
Password_reuse_history
是
PASSWORD HISTORY
帐户选项
的值
,或
NULL
默认历史记录的值。
Password_reuse_time
是
PASSWORD REUSE INTERVAL
帐户选项
的值
,或
NULL
默认间隔的值。
Password_require_current
(在MySQL 8.0.13中添加)对应于
PASSWORD
REQUIRE
帐户选项
的值,
如下表所示。
表6.5允许的Password_require_current值
Password_require_current值 | 相应的密码请求选项 |
---|---|
'Y' |
PASSWORD REQUIRE CURRENT |
'N' |
PASSWORD REQUIRE CURRENT OPTIONAL |
NULL |
PASSWORD REQUIRE CURRENT DEFAULT |
User_attributes
(在MySQL 8.0.14中添加)存储未存储在其他列中的帐户属性:
additional_password
:辅助密码,如果有的话。
请参阅
双密码支持
。
Restrictions
:限制列表,如果有的话。
部分撤销操作会增加限制。
属性值是一个元素数组,每个元素都有
Database
和
Restrictions
键,指示受限数据库的名称及其适用的限制(请参见
第6.2.12节“使用部分撤消的权限限制”
)。
如果没有适用的属性,那
User_attributes
就是
NULL
。
例如:具有二级密码和部分撤销数据库特权拥有帐户
additional_password
和
Restrictions
在该列的值属性:
MySQL的>SELECT User_attributes FROM mysql.User WHERE User = 'u'\G
*************************** 1。排******************** ******* User_attributes:{“限制”: [{“Database”:“mysql”,“Privileges”:[“SELECT”]}], “additional_password”:“hashed_credentials
”}
要确定存在哪些属性,请使用以下
JSON_KEYS()
函数:
SELECT User,Host,JSON_KEYS(User_attributes) FROM mysql.user WHERE User_attributes IS NOT NULL;
要提取特定属性,例如
Restrictions
,请执行以下操作:
SELECT User,Host,User_attributes - >>'$。Restrictions' FROM mysql.user WHERE User_attributes - >>'$。Restrictions'<>'';
在访问控制的第二阶段,服务器执行请求验证以确保每个客户端对其发出的每个请求具有足够的权限。
除了
user
和
db
grant表之外,服务器还可以查询
表
tables_priv
和
columns_priv
涉及表的请求。
后面的表在表级和列级提供更精细的权限控制。
它们具有下表中显示的列。
表6.6 tables_priv和columns_priv表列
表名 | tables_priv |
columns_priv |
---|---|---|
范围列 | Host |
Host |
Db |
Db |
|
User |
User |
|
Table_name |
Table_name |
|
Column_name |
||
权限列 | Table_priv |
Column_priv |
Column_priv |
||
其他专栏 | Timestamp |
Timestamp |
Grantor |
的
Timestamp
和
Grantor
列被设置为当前时间戳和
CURRENT_USER
值,分别,但其他未使用的。
为了验证涉及存储例程的请求,服务器可以查询该
procs_priv
表,该表具有下表中显示的列。
表6.7 procs_priv表列
表名 | procs_priv |
---|---|
范围列 | Host |
Db |
|
User |
|
Routine_name |
|
Routine_type |
|
权限列 | Proc_priv |
其他专栏 | Timestamp |
Grantor |
该
Routine_type
列是一个
ENUM
值为
'FUNCTION'
或
的
列,
'PROCEDURE'
表示行引用的例程类型。
此列允许为具有相同名称的函数和过程单独授予权限。
在
Timestamp
与
Grantor
列未使用。
该
proxies_priv
表记录有关代理帐户的信息。
它有以下列:
对于能够将
PROXY
权限
授予
其他帐户的帐户,它必须在
proxies_priv
表中具有
With_grant
设置为1的行,
Proxied_host
并
Proxied_user
设置为指示可以为其授予权限的帐户。
例如,
'root'@'localhost'
在MySQL安装期间创建
的
帐户在
proxies_priv
表中
有一行,该行
允许
为所有用户和所有主机
授予
PROXY
权限
''@''
。
这样可以
root
设置代理用户,以及委托其他帐户设置代理用户的权限。
请参见
第6.2.18节“代理用户”
。
该
global_grants
表列出了当前对用户帐户的动态全局权限的分配。
该表包含以下列:
USER
,
HOST
:授予权限的帐户的用户名和主机名。
PRIV
:权限名称。
WITH_GRANT_OPTION
:帐户是否可以将权限授予其他帐户。
该
default_roles
表列出了默认用户角色。
它有以下列:
HOST
,
USER
:默认角色适用的帐户或角色。
DEFAULT_ROLE_HOST
,
DEFAULT_ROLE_USER
:默认角色。
该
role_edges
表列出了角色子图的边缘。
它有以下列:
FROM_HOST
,
FROM_USER
:被授予角色的帐户。
TO_HOST
,
TO_USER
:授予帐户的角色。
WITH_ADMIN_OPTION
:帐户是否可以通过使用授予角色和从其他帐户撤消角色
WITH ADMIN OPTION
。
该
password_history
表包含有关密码更改的信息。
它有以下列:
Host
,
User
:发生密码更改的帐户。
Password_timestamp
:密码更改发生的时间。
Password
:新密码哈希值。
该
password_history
表为每个帐户累积足够数量的非空密码,以使MySQL能够对帐户密码历史记录长度和重用间隔执行检查。
当发生密码更改尝试时,会自动修剪超出两个限制的条目。
空密码不会计入密码历史记录中,并且可以随时重复使用。
如果重命名帐户,则会重命名其条目以匹配。 如果删除帐户或更改其身份验证插件,则会删除其条目。
授权表中的范围列包含字符串。 每个的默认值是空字符串。 下表显示了每列中允许的字符数。
表6.8授权表范围列长度
列名称 | 允许的最大字符数 |
---|---|
Host
,
Proxied_host
|
255(MySQL 8.0.17之前的60) |
User
,
Proxied_user
|
32 |
Db |
64 |
Table_name |
64 |
Column_name |
64 |
Routine_name |
64 |
对于访问检查的目的,进行比较
User
,
Proxied_user
,
authentication_string
,
Db
,和
Table_name
的值是大小写敏感的。
的比较
Host
,
Proxied_host
,
Column_name
,和
Routine_name
的值是不区分大小写。
在
user
和
db
表列出了被声明为一个单独的列每个特权
ENUM('N','Y') DEFAULT 'N'
。
换句话说,可以禁用或启用每个权限,默认为禁用。
的
tables_priv
,
columns_priv
和
procs_priv
表申报权限列的
SET
列。
这些列中的值可以包含表控制的权限的任意组合。
仅启用列值中列出的那些权限。
表6.9 Set-Type特权列值
表名 | 列名称 | 可能的集合元素 |
---|---|---|
tables_priv |
Table_priv |
'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop',
'Grant', 'References', 'Index', 'Alter', 'Create View',
'Show view', 'Trigger' |
tables_priv |
Column_priv |
'Select', 'Insert', 'Update', 'References' |
columns_priv |
Column_priv |
'Select', 'Insert', 'Update', 'References' |
procs_priv |
Proc_priv |
'Execute', 'Alter Routine', 'Grant' |
只有
user
和
global_grants
表指定管理权限,如
RELOAD
,
SHUTDOWN
和
SYSTEM_VARIABLES_ADMIN
。
管理操作是服务器本身的操作,并不是特定于数据库的,因此没有理由在其他授权表中列出这些特权。
因此,服务器只需要查询
user
和
global_grants
表来确定用户是否可以执行管理操作。
该
FILE
权限也仅在
user
表中
指定
。
它本身不是管理权限,但用户在服务器主机上读取或写入文件的能力与所访问的数据库无关。
MySQL帐户名由用户名和主机名组成。 这样可以为具有相同名称且可以从不同主机连接的用户创建帐户。 本节介绍如何编写帐户名,包括特殊值和通配符规则。
MySQL角色名称与帐户名称类似,但 第6.2.5节“指定角色名称”中 描述了一些差异 。
在诸如
,和
等帐户名的
SQL语句中
CREATE
USER
,
遵循以下规则:
GRANT
SET PASSWORD
帐户名称语法是
。
'
user_name
'@'host_name
'
仅包含用户名的帐户名称相当于
。
例如,
相当于
。
'
user_name
'@'%''me'
'me'@'%'
如果用户名和主机名是合法的,则不需要引用它们作为不带引号的标识符。
需要引号来指定
user_name
包含特殊字符(如空格或
-
)的
host_name
字符串
,或
包含特殊字符或通配符(例如,
.
或
%
)
的
字符串
(例如
'test-user'@'%.com'
)。
使用反引号(
`
),单引号(
'
)或双引号(
"
)
引用用户名和主机名作为标识符或字符串
。
有关字符串引用和标识符引用指南,请参见
第9.1.1节“字符串文字”
和
第9.2节“模式对象名称”
。
如果引用,用户名和主机名部分必须单独引用。
也就是说,写
'me'@'localhost'
,不
'me@localhost'
;
后者实际上相当于
'me@localhost'@'%'
。
对
CURRENT_USER
or
CURRENT_USER()
函数的
引用
等同于从字面上指定当前客户端的用户名和主机名。
MySQL
mysql
使用单独的用户名和主机名部分列
将帐户名存储在
系统数据库的
授权表中
:
有关授权表的结构更多细节,请参见 第6.2.3节“授权表” 。
用户名和主机名具有某些特殊值或通配符约定,如下所述。
帐户名的用户名部分是非空白值,与字面上与传入连接尝试的用户名匹配,或者是与任何用户名匹配的空值(空字符串)。
具有空白用户名的帐户是匿名用户。
要在SQL语句中指定匿名用户,请使用带引号的空用户名部分,例如
''@'localhost'
。
帐户名称的主机名部分可以采用多种形式,并允许使用通配符:
主机值可以是主机名或IP地址(IPv4或IPv6)。
该名称
'localhost'
表示本地主机。
IP地址
'127.0.0.1'
表示IPv4环回接口。
IP地址
'::1'
表示IPv6环回接口。
在
%
和
_
通配符允许在主机名或IP地址的值。
这些与操作员执行的模式匹配操作具有相同的含义
LIKE
。
例如,主机值
'%'
匹配任何主机名,而值
'%.mysql.com'
匹配
mysql.com
域中的
任何主机
。
'198.51.100.%'
匹配198.51.100 C类网络中的任何主机。
由于主机值中允许使用IP通配符值(例如,
'198.51.100.%'
为了匹配子网上的每个主机),因此有人可能会尝试通过命名主机来利用此功能
198.51.100.somewhere.com
。
为了阻止这种尝试,MySQL不会对以数字和点开头的主机名执行匹配。
例如,如果命名了主机
1.2.example.com
,则其名称永远不会与帐户名称的主机部分匹配。
IP通配符值只能匹配IP地址,而不能匹配主机名。
对于指定为IPv4地址的主机值,可以给出网络掩码以指示用于网络号的地址位数。 网络掩码表示法不能用于IPv6地址。
语法是
。
例如:
host_ip
/netmask
创建用户'david'@'198.51.100.0/255.255.255.0';
这使得
david
能够从具有
client_ip
以下条件为真的
IP地址的任何客户端主机进行连接
:
client_ip
&netmask
=host_ip
也就是说,对于
CREATE
USER
刚才显示
的
声明:
client_ip
&255.255.255.0 = 198.51.100.0
满足此条件范围的IP地址
198.51.100.0
来
198.51.100.255
。
网络掩码通常以设置为1的位开头,然后将位设置为0.示例:
198.0.0.0/255.0.0.0
:198 A类网络上的任何主机
198.51.100.0/255.255.0.0
:198.51 B类网络上的任何主机
198.51.100.0/255.255.255.0
:198.51.100 C类网络上的任何主机
198.51.100.1
:仅具有此特定IP地址的主机
服务器使用系统DNS解析程序为客户端主机名或IP地址返回的值,针对客户端主机执行帐户名中的主机值匹配。 除了使用网络掩码表示法指定帐户主机值的情况之外,服务器将此比较作为字符串匹配执行,即使对于作为IP地址给出的帐户主机值也是如此。 这意味着您应该使用DNS使用的相同格式指定帐户主机值。 以下是需要注意的问题示例:
假设本地网络上的主机具有完全限定名称
host1.example.com
。
如果DNS返回此主机的名称查找,请
host1.example.com
在帐户主机值中使用该名称。
如果DNS返回
host1
,请
host1
改用。
如果DNS返回给定主机的IP地址
198.51.100.2
,那将匹配帐户主机值
198.51.100.2
但不
匹配
198.051.100.2
。
同样,它会匹配帐户主机模式,
198.51.100.%
但不
匹配
198.051.100.%
。
为避免这些问题,建议您检查DNS返回主机名和地址的格式。 在MySQL帐户名中使用相同格式的值。
MySQL角色名称指的是角色,它们被命名为特权集合。 有关角色使用示例,请参见 第6.2.10节“使用角色” 。
角色名的语法和语义相似的账户名( 第6.2.4节“指定帐户名” )。 角色名称在这些方面与帐户名称不同:
角色名称的用户部分不能为空。 因此,没有 “ 匿名角色 ” 类似于 “ 匿名用户 ” 的概念 。 ”
作为一个帐户名,省略了在主机部分角色名称结果主机部分
'%'
。
但是,与
'%'
在一个帐户名,主机部分
'%'
的角色名称没有通配符性能。
例如,对于一个名称
'me'@'%'
用作角色名,主机部分(
'%'
)仅仅是一个文字值;
它没有
“
任何主机
”
匹配属性。
角色名称的主机部分中的网络掩码表示法没有意义。
帐户名称允许
CURRENT_USER()
在多个上下文中。
角色名称不是。
mysql.user
系统表中
的一行
可以同时用作帐户和角色。
在这种情况下,任何特殊用户或主机名匹配属性都不适用于将该名称用作角色名称的上下文。
例如,您不能执行以下语句,期望它将使用具有用户部分
myrole
和任何主机名的
所有角色设置当前会话角色
:
SET ROLE'myrole'@'%';
相反,该语句将会话的活动角色设置为具有完全名称的角色
'myrole'@'%'
。
因此,通常仅使用用户名部分指定角色名称,并隐式使用主机名部分
'%'
。
'%'
如果您打算创建一个既可用作角色又可用作允许从给定主机连接的用户帐户的名称,则
指定具有非
主机部件
的角色
非常有用。
当您尝试连接到MySQL服务器时,服务器会根据以下条件接受或拒绝连接:
您的身份以及是否可以通过提供正确的密码来验证您的身份
您的帐户是锁定还是解锁
服务器首先检查凭据,然后检查帐户锁定状态。 任一步骤失败都会导致服务器完全拒绝您的访问权限。 否则,服务器接受连接,然后进入阶段2并等待请求。
使用三个执行凭证检查
user
表范围列(
Host
,
User
,和
authentication_string
)。
锁定状态记录在
user
表格
account_locked
列中。
仅当
某些
表行中
的
Host
和
User
列
user
与客户端主机名和用户名匹配时,
服务器才接受连接
,客户端提供该行中指定的密码,
account_locked
值为
'N'
。
允许
值
Host
和
User
值
的规则
在
第6.2.4节“指定帐户名称”中给出
。
可以使用
ALTER
USER
语句
更改帐户锁定
。
您的身份基于两条信息:
您连接的客户端主机
您的MySQL用户名
如果
User
列值为非空,则传入连接中的用户名必须完全匹配。
如果
User
值为空,则它匹配任何用户名。
如果
user
与传入连接匹配
的
表行具有空白用户名,则该用户被视为没有名称的匿名用户,而不是具有客户端实际指定名称的用户。
这意味着空白用户名用于连接持续时间内的所有进一步访问检查(即,在阶段2期间)。
该
authentication_string
列可以为空白。
这不是通配符,并不表示任何密码匹配。
这意味着用户必须在不指定密码的情况下进行连接。
如果服务器使用插件对客户端进行身份验证,则插件实现的身份验证方法可能会也可能不会使用
authentication_string
列中
的密码
。
在这种情况下,外部密码也可能用于向MySQL服务器进行身份验证。
表中的非
空
authentication_string
值
user
表示加密密码。
MySQL不会将密码存储为任何人都可以看到的明文。
而是,尝试连接的用户提供的密码是加密的(使用由帐户认证插件实现的密码散列方法)。
然后在检查密码是否正确时,在连接过程中使用加密密码。
这是在没有经过连接的加密密码的情况下完成的。
请参见
第6.2.1节“帐户用户名和密码”
。
从MySQL的角度来看,加密密码是
真正的
密码,所以你永远不应该让任何人访问它。
特别是,
不要给非管理用户读取对
mysql
系统数据库
中表的访问权限
。
下表显示了表中各种组合
User
和
Host
值
如何
user
应用于传入连接。
User
值
|
Host
值
|
允许的连接 |
---|---|---|
'fred' |
'h1.example.net' |
fred
,连接
h1.example.net
|
'' |
'h1.example.net' |
任何用户,从中连接
h1.example.net
|
'fred' |
'%' |
fred
,从任何主机连接
|
'' |
'%' |
任何用户,从任何主机连接 |
'fred' |
'%.example.net' |
fred
,从
example.net
域中的
任何主机连接
|
'fred' |
'x.example.%' |
fred
,从连接
x.example.net
,
x.example.com
,
x.example.edu
,等;
这可能没用
|
'fred' |
'198.51.100.177' |
fred
,从主机与IP地址连接
198.51.100.177
|
'fred' |
'198.51.100.%' |
fred
,从
198.51.100
C类子网
中的任何主机连接
|
'fred' |
'198.51.100.0/255.255.255.0' |
与前面的示例相同 |
传入连接的客户端主机名和用户名可以匹配
user
表
中的多个行
。
前述组实例证明这一点:若干条目的匹配示出从连接
h1.example.net
的
fred
。
当可能存在多个匹配项时,服务器必须确定要使用哪些匹配项。 它解决了这个问题如下:
只要服务器将
user
表
读
入内存,它就会对行进行排序。
当客户端尝试连接时,服务器按排序顺序查看行。
服务器使用与客户端主机名和用户名匹配的第一行。
服务器使用排序规则,
Host
首先
对具有最具特定
值的
行进行排序
。
文字主机名和IP地址是最具体的。
(文字IP地址的特异性不受其是否具有网络掩码,因此
198.51.100.13
和
198.51.100.0/255.255.255.0
被认为是同样特异性的。)该模式
'%'
是指
“
任何主机
”
并且是最不特定。
空字符串
''
也表示
“
任何主机
”,
但后面排序
'%'
。
具有相同
Host
值的
行首先以
最具特定的
User
值
排序
(空白
User
值表示
“
任何用户
”
并且最不具体)。
对于具有相同特定
值
Host
和
User
值的行,顺序是不确定的。
要查看其工作原理,请假设该
user
表如下所示:
+ ----------- + ---------- + - | 主持人| 用户| ... + ----------- + ---------- + - | %| 根| ... | %| 杰弗里| ... | localhost | 根| ... | localhost | | ... + ----------- + ---------- + -
当服务器将表读入内存时,它使用刚才描述的规则对行进行排序。 排序后的结果如下所示:
+ ----------- + ---------- + - | 主持人| 用户| ... + ----------- + ---------- + - | localhost | 根| ... | localhost | | ... | %| 杰弗里| ... | %| 根| ... + ----------- + ---------- + -
当客户端尝试连接时,服务器会查看已排序的行并使用找到的第一个匹配项。
对于从连接
localhost
由
jeffrey
两个从表匹配的行的:一个具有
Host
和
User
的值
'localhost'
和
''
,和一个具有值
'%'
和
'jeffrey'
。
该
'localhost'
行首先按排序顺序出现,因此这是服务器使用的行。
这是另一个例子。
假设
user
表格如下所示:
+ ---------------- + ---------- + - | 主持人| 用户| ... + ---------------- + ---------- + - | %| 杰弗里| ... | h1.example.net | | ... + ---------------- + ---------- + -
排序表如下所示:
+ ---------------- + ---------- + - | 主持人| 用户| ... + ---------------- + ---------- + - | h1.example.net | | ... | %| 杰弗里| ... + ---------------- + ---------- + -
通过连接
jeffrey
从
h1.example.net
由第一行匹配,而通过连接
jeffrey
来自任何主机通过第二匹配。
认为对于给定的用户名,当服务器尝试查找连接匹配时,首先使用显式命名该用户的所有行,这是一种常见的误解。
这不是真的。
前面的例子中示出了这一点,其中从连接
h1.example.net
通过
jeffrey
首先由包含行匹配不
'jeffrey'
作为
User
列值,而是由没有用户名的行。
因此
jeffrey
,即使他在连接时指定了用户名,也会作为匿名用户进行身份验证。
如果您能够连接到服务器,但您的权限不是您所期望的,那么您可能正在进行其他帐户的身份验证。
要了解服务器用于验证您的帐户,请使用该
CURRENT_USER()
功能。
(请参见
第12.15节“信息函数”
。)它返回一个
格式
值
,表示
匹配
表行的
值
和
值
。
假设
连接并发出以下查询:
user_name
@host_name
User
Host
user
jeffrey
MySQL的> SELECT CURRENT_USER();
+ ---------------- +
| CURRENT_USER()|
+ ---------------- +
| @localhost |
+ ---------------- +
此处显示的结果表明匹配的
user
表行具有空白
User
列值。
换句话说,服务器将被
jeffrey
视为匿名用户。
诊断身份验证问题的另一种方法是打印出
user
表格并手动对其进行排序,以查看第一次匹配的位置。
建立连接后,服务器进入访问控制的第2阶段。
对于通过该连接发出的每个请求,服务器确定您要执行的操作,然后检查您是否具有足够的权限来执行此操作。
这是授权表中的特权列发挥作用的地方。
这些权限可以来自任何的
user
,
global_grants
,
db
,
tables_priv
,
columns_priv
,或
procs_priv
表。
(您可能会发现参考
第6.2.3节“授权表”
很有帮助
,它列出了每个授权表中的列。)
在
user
和
global_grants
表授予全局权限。
这些表中给定帐户的行表示无论默认数据库是什么,都在全局范围内应用的帐户权限。
例如,如果
user
表授予您
DELETE
特权,则可以从服务器主机上任何数据库的任何表中删除行。
将
user
表中的
权限
仅
授予
需要它们的人(例如数据库管理员)
是明智的
。
对于其他用户,请将
user
表中的
所有权限保留
为
'N'
并且仅在更具体的级别授予权限(对于特定的数据库,表,列或例程)。
也可以在全局范围内授予数据库权限,但使用部分撤销来限制它们在特定数据库上执行(请参见
第6.2.12节“使用部分撤消的权限限制”
)。
该
db
表授予特定于数据库的权限。
此表的范围列中的值可以采用以下形式:
服务器将
db
表
读
入内存并在读取
user
表
的同时对其进行排序
。
服务器排序
db
基于表
Host
,
Db
和
User
范围列。
与
user
表一样,排序将最具体的值放在最前面,将最不具体的值放在最后,当服务器查找匹配的行时,它使用它找到的第一个匹配。
的
tables_priv
,
columns_priv
和
procs_priv
表授予特定表,特定列,日常特定权限。
这些表的范围列中的值可以采用以下形式:
通配符
%
和
_
可在使用
Host
的列。
这些与操作员执行的模式匹配操作具有相同的含义
LIKE
。
A
'%'
或空白
Host
值表示
“
任何主机。
”
在
Db
,
Table_name
,
Column_name
,和
Routine_name
列不能包含通配符或空白。
服务器排序
tables_priv
,
columns_priv
以及
procs_priv
基于表
Host
,
Db
和
User
列。
这与
db
表排序
类似
,但更简单,因为只有
Host
列可以包含通配符。
服务器使用已排序的表来验证它收到的每个请求。
对于需要管理权限(例如
SHUTDOWN
或
RELOAD
)的
请求,
服务器仅检查
user
和
global_privilege
表,因为这些是唯一指定管理权限的表。
如果这些表中的帐户行允许所请求的操作,则服务器授予访问权限,否则拒绝访问。
例如,如果要执行
mysqladmin shutdown
但是您的
user
表行不授予
SHUTDOWN
您权限,则服务器会在不检查
db
表的
情况下拒绝访问
。
(后一个表中没有
Shutdown_priv
列,所以没有必要检查它。)
对于与数据库相关的请求(
INSERT
,
UPDATE
等等),服务器首先检查用户在
user
表行中
的全局特权
(减少部分撤销所施加的任何特权限制)。
如果该行允许所请求的操作,则授予访问权限。
如果
user
表中
的全局特权
不足,则服务器
从
表中确定用户的特定于数据库的特权
db
:
该服务器会在
db
表上的匹配
Host
,
Db
以及
User
列。
在
Host
与
User
列对应连接用户的主机名和MySQL用户名。
该
Db
列与用户想要访问的数据库匹配。
如果没有排为
Host
和
User
,访问被拒绝。
确定
db
表行
授予的特定于数据库的权限后
,服务器会将它们添加到
user
表
授予的全局权限
中。
如果结果允许所请求的操作,则授予访问权限。
否则,服务器会依次检查用户在
tables_priv
和
columns_priv
表中
的表和列权限
,将这些权限添加到用户的权限,并根据结果允许或拒绝访问。
对于存储例程操作,服务器使用
procs_priv
表而不是
tables_priv
和
columns_priv
。
以布尔术语表示,前面关于如何计算用户权限的描述可以总结如下:
全球特权 OR(数据库权限和主机权限) 或表权限 OR列权限 或例行特权
可能不明显的是,如果最初发现全局特权不足以满足所请求的操作,则服务器稍后会将这些特权添加到数据库,表和列特权。
原因是请求可能需要多种类型的权限。
例如,如果执行
INSERT
INTO ...
SELECT
语句,则需要
INSERT
和
SELECT
权限。
您的权限可能是这样的,
user
表行授予一个全局权限和
db
table row专门为相关数据库授予另一个。
在这种情况下,您具有执行请求所需的权限,但服务器无法单独使用全局或数据库权限。
它必须根据组合的权限做出访问控制决策。
要管理MySQL帐户,请使用用于此目的的SQL语句:
CREATE
USER
并
DROP
USER
创建和删除帐户。
SHOW
GRANTS
显示帐户权限分配。
帐户管理语句使服务器对基础授权表进行适当的修改,这将在 第6.2.3节“授权表” 中讨论 。
使用诸如
,或者
不鼓励的
语句直接修改授权表
INSERT
,
并且风险自负。
服务器可以自由忽略由于此类修改而变得格式错误的行。
UPDATE
DELETE
对于修改授权表的任何操作,服务器检查该表是否具有预期结构,否则生成错误。 要将表更新为预期结构,请执行MySQL升级过程。 请参见 第2.11节“升级MySQL” 。
创建帐户的另一个选择是使用GUI工具MySQL Workbench。
此外,一些第三方程序提供MySQL帐户管理功能。
phpMyAdmin
是一个这样的计划。
本节讨论以下主题:
有关此处讨论的语句的其他信息,请参见 第13.7.1节“帐户管理语句” 。
以下示例显示如何使用
mysql
客户端程序设置新帐户。
这些示例假定MySQL
root
帐户具有
CREATE USER
其授予其他帐户
的
权限和所有权限。
在命令行,以MySQL
root
用户
身份连接到服务器
,在密码提示符下提供相应的密码:
shell>mysql -u root -p
输入密码:(enter root password here)
连接到服务器后,您可以添加新帐户。
以下示例使用
CREATE
USER
和
GRANT
语句设置四个帐户(您可以看到
,替换适当的密码):
'
password
'
创建用户'finley'@'localhost' 识别'password
'; 全部授予 上 *。* 去'finley'@'localhost' WITH GRANT OPTION; 创建用户'finley'@'%.example.com' 识别'password
'; 全部授予 上 *。* 去'finley'@'%.example.com' WITH GRANT OPTION; 创建用户'admin'@'localhost' 识别'password
'; GRANT RELOAD,PROCESS 上 *。* TO'admin'@'localhost'; 创建用户'dummy'@'localhost';
这些语句创建的帐户具有以下属性:
两个帐户的用户名为
finley
。
两者都是具有完全全局权限的超级用户帐户,可以执行任
'finley'@'localhost'
只有从本地主机连接时才能使用
该
帐户。
该
'finley'@'%.example.com'
帐户
'%'
在主机部分中
使用
通配符,因此可用于从
example.com
域中的
任何主机进行连接
。
'finley'@'localhost'
如果有匿名用户帐户,则
该
帐户是必需的
localhost
。
如果没有该
'finley'@'localhost'
帐户,
finley
则从本地主机连接
时该匿名用户帐户优先
,
finley
并被视为匿名用户。
这样做的原因是匿名用户帐户具有
Host
比
'finley'@'%'
帐户
更具体的
列值
,因此在
user
表格排序顺序中
更早出现
。
(有关
user
表排序的
信息
,请参见
第6.2.6节“访问控制,第1阶段:连接验证”
。)
该
'admin'@'localhost'
帐户只能用于
admin
从本地主机进行连接。
它被授予全局
RELOAD
和
PROCESS
管理权限。
这些特权使
admin
用户能够执行
mysqladmin reload
,
mysqladmin refresh
和
mysqladmin flush-
xxx
命令,以及
mysqladmin processlist
。
没有授予访问任何数据库的权限。
您可以使用
GRANT
语句
添加此类权限
。
该
'dummy'@'localhost'
帐户没有密码(这是不安全的,不推荐)。
此帐户只能用于从本地主机进行连接。
没有授予任何权限。
假设您将使用
GRANT
语句
向帐户授予特定权限
。
前面的示例在全局级别授予权限。
下一个示例创建三个帐户并授予他们较低级别的访问权限;
也就是说,对于数据库中的特定数据库或对象。
每个帐户的用户名都是
custom
,但主机名部分不同:
创建用户'自定义'@'localhost' 识别'password
'; 全部授予 在银行帐户。* ''custom'@'localhost'; 创建用户'custom'@'host47.example.com' 识别'password
'; GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP 开支。* 到'custom'@'host47.example.com'; 创建用户'custom'@'%.example.com' 识别'password
'; GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP 在customer.addresses上 去'custom'@'%.example.com';
这三个帐户可以使用如下:
该
'custom'@'localhost'
帐户具有访问
bankaccount
数据库的
所有数据库级权限
。
该帐户可用于仅从本地主机连接到服务器。
该
'custom'@'host47.example.com'
帐户具有访问
expenses
数据库的
特定数据库级权限
。
该帐户可用于仅从主机连接到服务器
host47.example.com
。
该
'custom'@'%.example.com'
帐户具有特定的表级权限,可以
从
域中的
任何主机
访问
数据库中
的
addresses
表
。
由于
在帐户名称的主机部分中
使用
通配符,
该帐户可用于从域中的所有计算机连接到服务器
。
customer
example.com
%
要查看帐户的权限,请使用
SHOW
GRANTS
:
MySQL的> SHOW GRANTS FOR 'admin'@'localhost';
+ ------------------------------------------------- ---- +
| admin @ localhost的补助金
+ ------------------------------------------------- ---- +
| GRANT RELOAD,PROCESS ON *。* TO'admin'@'localhost'|
+ ------------------------------------------------- ---- +
要查看帐户的非特权属性,请使用
SHOW
CREATE USER
:
mysql>SET print_identified_with_as_hex = ON;
mysql>SHOW CREATE USER 'admin'@'localhost'\G
*************************** 1。排******************** ******* admin @ localhost的CREATE USER:CREATE USER'admin'@'localhost' 通过'caching_sha2_password'识别 AS 0x24412430303524301D0E17054E2241362B1419313C3E44326F294133734B30792F436E77764270373039612E32445250786D43594F45354532324B6169794F47457852796E32 要求无密码存款违约帐户解锁 密码历史默认 密码重复使用间隔默认值 密码要求当前默认值
启用
print_identified_with_as_hex
系统变量(从MySQL 8.0.17开始提供)会导致
SHOW
CREATE USER
显示包含不可打印字符的哈希值作为十六进制字符串而不是常规字符串文字。
要撤消帐户权限,请使用该
REVOKE
语句。
权限可以在不同级别撤销,就像可以在不同级别授予权限一样。
撤销全球特权:
全力以赴 上 *。* 来自'finley'@'%.example.com'; REVOKE RELOAD 上 *。* 来自'admin'@'localhost';
撤消数据库级权限:
REVOKE CREATE,DROP 开支。* 来自'custom'@'host47.example.com';
撤消表级权限:
REVOKE INSERT,UPDATE,DELETE 在customer.addresses上 来自'custom'@'%.example.com';
要检查权限撤销的效果,请使用
SHOW
GRANTS
:
MySQL的> SHOW GRANTS FOR 'admin'@'localhost';
+ --------------------------------------------- +
| admin @ localhost的补助金
+ --------------------------------------------- +
| GRANT PROCESS ON *。* TO'admin'@'localhost'|
+ --------------------------------------------- +
要删除帐户,请使用该
DROP
USER
语句。
例如,要删除之前创建的一些帐户:
DROP USER'finley'@'localhost'; DROP USER'finley'@'%.example.com'; DROP USER'admin'@'localhost'; DROP USER'dummy'@'localhost';
MySQL安装过程的一部分是数据目录初始化(请参见 第2.10.1节“初始化数据目录” )。 在数据目录初始化期间,MySQL会创建应被视为保留的用户帐户:
'root'@'localhost
:用于管理目的。
此帐户具有所有权限,是系统帐户,可以执行任何操作。
严格地说,此帐户名称不是保留的,因为某些安装会将
root
帐户
重命名为
其他名称,以避免使用众所周知的名称公开具有高权限的帐户。
'mysql.sys'@'localhost'
:作为
DEFINER
对
sys
架构对象。
使用该
mysql.sys
帐户可避免DBA重命名或删除
root
帐户时
出现的问题
。
此帐户已锁定,因此无法用于客户端连接。
'mysql.session'@'localhost'
:由插件内部使用以访问服务器。
此帐户已锁定,因此无法用于客户端连接。
该帐户是系统帐户。
'mysql.infoschema'@'localhost'
:作为
DEFINER
对
INFORMATION_SCHEMA
意见。
使用该
mysql.infoschema
帐户可避免DBA重命名或删除root帐户时出现的问题。
此帐户已锁定,因此无法用于客户端连接。
MySQL角色是一组命名的特权。 与用户帐户一样,角色可以拥有授予和撤消的权限。
可以为用户帐户授予角色,该角色向帐户授予与每个角色关联的权限。 这样可以为帐户分配权限集,并为授予个人权限提供了一种方便的替代方法,既可以概念化所需的权限分配,也可以实现它们。
以下列表总结了MySQL提供的角色管理功能:
CREATE
ROLE
并
DROP
ROLE
创建和删除角色。
SHOW
GRANTS
显示用户帐户和角色的权限和角色分配。
SET
DEFAULT ROLE
指定默认情况下哪些帐户角色处于活动状
SET ROLE
更改当前会话中的活动角色。
该
CURRENT_ROLE()
函数显示当前会话中的活动角色。
该
mandatory_roles
和
activate_all_roles_on_login
系统变量定义启用强制角色和授予的角色的自动激活,当用户登录到服务器。
有关各个角色操作语句(包括使用它们所需的权限)的描述,请参见
第13.7.1节“帐户管理语句”
。
以下讨论提供了角色使用的示例。
除非另有说明,否则此处显示的SQL语句应使用具有足够管理权限的MySQL帐户执行,例如
root
帐户。
考虑这种情况:
应用程序使用名为的数据库
app_db
。
与应用程序相关联,可以为创建和维护应用程序的开发人员以及与之交互的用户提供帐户。
开发人员需要对数据库的完全访问权限。 有些用户只需要读访问权限,有些用户需要读/写访问权限。
要避免单独为可能的许多用户帐户授予权限,请将角色创建为所需权限集的名称。 这样,通过授予适当的角色,可以轻松地向用户帐户授予所需的权限。
要创建角色,请使用以下
CREATE
ROLE
语句:
CREATE ROLE'app_developer','app_read','app_write';
角色名称与用户帐户名称非常相似,并且由
格式
的用户部分和主机部分组成
。
主机部分(如果省略)默认为
。
用户和主机部件可以不加引号,除非它们包含特殊字符,如
或
。
与帐户名称不同,角色名称的用户部分不能为空。
有关其他信息,请参见
第6.2.5节“指定角色名称”
。
'
user_name
'@'host_name
''%'
-
%
要为角色分配权限,请
GRANT
使用与为用户帐户分配权限相同的语法
执行
语句:
全部授予app_db。* TO'app_developer'; GRANT SELECT ON app_db。* TO'app_read'; GRANT INSERT,UPDATE,DELETE ON app_db。* TO'app_write';
现在假设您最初需要一个开发人员帐户,两个需要只读访问权限的用户帐户,以及一个需要读/写访问权限的用户帐户。
使用
CREATE
USER
创建帐户:
创建用户'dev1'@'localhost'IDENTIFIED BY'dev1pass'; CREATE USER'read_user1'@'localhost'IDENTIFIED BY'read_user1pass'; CREATE USER'read_user2'@'localhost'IDENTIFIED BY'read_user2pass'; 创建用户'rw_user1'@'localhost'IDENTIFIED BY'rw_user1pass';
要为每个用户帐户分配所需的权限,您可以使用
GRANT
与刚才显示的相同表单的语句,但这需要枚举每个用户的个人权限。
相反,使用
GRANT
允许授予角色而不是特权
的替代
语法:
GRANT'app_developer'TO'dev1'@'localhost'; GRANT'app_read'TO'read_user1'@'localhost','read_user2'@'localhost'; GRANT'app_read','app_write'TO'rw_user1'@'localhost';
该
帐户
的
GRANT
语句
rw_user1
授予读取和写入角色,这些角色组合在一起以提供所需的读写权限。
在
GRANT
授予角色的帐户语法不同的语法授予权限:有一个
ON
分配的特权条款,而没有
ON
子句来分配角色。
由于语法是不同的,因此您不能在同一语句中混合使用赋予权限和角色。
(允许为帐户分配权限和角色,但必须使用单独的
GRANT
语句,每个语句的语法都与要授予的语句相适应。)从MySQL 8.0.16开始,不能将角色授予匿名用户。
创建时的角色已锁定,没有密码,并被分配了默认的身份验证插件。
(
ALTER
USER
具有全局
CREATE USER
权限
的用户
可以稍后使用该
语句
更改这些角色属性
。)
锁定时,不能使用角色对服务器进行身份验证。 如果解锁,则可以使用角色进行身份验证。 这是因为角色和用户都是授权标识符,它们有很多共同之处,很难区分它们。 另请参见 用户和角色互换性 。
通过在
mandatory_roles
系统变量
的值中命名角色,可以将角色指定为必需角色
。
服务器将强制角色视为授予所有用户,因此不需要将其明确授予任何帐户。
要在服务器启动时指定强制角色,请
mandatory_roles
在服务器
my.cnf
文件中
定义
:
的[mysqld] mandatory_roles = '基于role1,基于role2 @本地,R3 @%。example.com'
要
mandatory_roles
在运行时
设置和保持
,请使用如下语句:
SET PERSIST mandatory_roles ='role1,role2 @ localhost,r3 @%。example.com';
SET
PERSIST
设置正在运行的MySQL实例的值。
它还会保存该值,使其用于后续服务器重新启动。
要更改正在运行的MySQL实例的值而不保存它以便后续重新启动,请使用
GLOBAL
关键字而不是
PERSIST
。
请参见
第13.7.5.1节“变量赋值的SET语法”
。
除了
通常设置全局系统变量所需的权限
或
权限
之外,
设置还
mandatory_roles
需要
ROLE_ADMIN
权限
。
SYSTEM_VARIABLES_ADMIN
SUPER
强制角色(如明确授予的角色)在激活之前不会生效(请参阅
激活角色
)。
在登录时,如果
activate_all_roles_on_login
启用
了
系统变量,则
对所有授予的角色
进行角色激活,否则对于设置为默认角色的角色进行角色激活。
在运行时,
SET
ROLE
激活角色。
在值命名的角色
mandatory_roles
不能被撤销
REVOKE
或下降
DROP
ROLE
或
DROP
USER
。
要防止会话默认为系统会话,具有该
SYSTEM_USER
权限
的角色
不能列在
mandatory_roles
系统变量
的值中
:
如果
mandatory_roles
在启动时为具有该
SYSTEM_USER
特权
的角色分配了一个角色
,则服务器会将消息写入错误日志并退出。
如果
mandatory_roles
在运行时为具有该
SYSTEM_USER
特权
的角色分配了一个角色,
则会发生错误并且该
mandatory_roles
值保持不变。
如果
系统表中
mandatory_roles
不存在
名为in的角色,
则不会
mysql.user
将该角色授予用户。
当服务器尝试为用户激活角色时,它不会将不存在的角色视为必需角色,并会向错误日志写入警告。
如果角色稍后创建并因此变为有效,则
FLUSH
PRIVILEGES
可能需要使服务器将其视为必需
角色
。
SHOW
GRANTS
根据
第13.7.6.21节“SHOW GRANTS语法”中
描述的规则显示强制角色
。
要验证分配给帐户的权限,请使用
SHOW
GRANTS
。
例如:
MySQL的> SHOW GRANTS FOR 'dev1'@'localhost';
+ ------------------------------------------------- +
| dev1 @ localhost的补助金
+ ------------------------------------------------- +
| 授予*。*给'dev1` @`localhost` |
| GRANT`app_developer` @`%`to`dev1` @`localhost` |
+ ------------------------------------------------- +
但是,这会显示每个已授予的角色,而不
会将其
“
扩展
”
为角色所代表的权限。
要显示角色权限,请添加一个
USING
子句,命名要为其显示权限的已授予角色:
MySQL的> SHOW GRANTS FOR 'dev1'@'localhost' USING 'app_developer';
+ ------------------------------------------------- --------- +
| dev1 @ localhost的补助金
+ ------------------------------------------------- --------- +
| 授予*。*给'dev1` @`localhost` |
| 在`app_db`上授予所有特权。*到`dev1` @`localhost` |
| GRANT`app_developer` @`%`to`dev1` @`localhost` |
+ ------------------------------------------------- --------- +
同样验证每个其他类型的用户:
MySQL的>SHOW GRANTS FOR 'read_user1'@'localhost' USING 'app_read';
+ ------------------------------------------------- ------- + | 资助read_user1 @ localhost | + ------------------------------------------------- ------- + | 授予使用*。*给`read_user1` @`localhost` | | GRANT SELECT ON`app_db`。* to`read_user1` @`localhost` | | GRANT`app_read` @`%`to`read_user1` @`localhost` | + ------------------------------------------------- ------- + MySQL的>SHOW GRANTS FOR 'rw_user1'@'localhost' USING 'app_read', 'app_write';
+ ------------------------------------------------- ----------------------------- + | 为rw_user1 @ localhost |授予补助金 + ------------------------------------------------- ----------------------------- + | 授予使用*。*给`rw_user1` @`localhost` | | GRANT SELECT,INSERT,UPDATE,DELETE ON` app_db`。* to`rw_user1` @`localhost` | | GRANT`app_read` @`%`,`app_write` @`%`to`rw_user1` @`localhost` | + ------------------------------------------------- ----------------------------- +
SHOW
GRANTS
根据
第13.7.6.21节“SHOW GRANTS语法”中
描述的规则显示强制角色
。
授予用户帐户的角色可以在帐户会话中处于活动状态或非活动状态。
如果授予的角色在会话中处于活动状态,则其权限适用;
否则,他们没有。
要确定当前会话中哪些角色处于活动状态,请使用该
CURRENT_ROLE()
功能。
默认情况下,向帐户授予角色或在
mandatory_roles
系统变量值中
命名
角色不会自动导致角色在帐户会话中变为活动状态。
例如,因为在前面的讨论中到目前为止
rw_user1
还没有激活
任何
角色,如果您连接到服务器
rw_user1
并调用该
CURRENT_ROLE()
函数,结果是
NONE
(没有活动角色):
MySQL的> SELECT CURRENT_ROLE();
+ ---------------- +
| CURRENT_ROLE()|
+ ---------------- +
| 没有|
+ ---------------- +
要指定每次用户连接到服务器并进行身份验证时哪些角色应处于活动状态,请使用
SET
DEFAULT ROLE
。
要将默认设置为先前创建的每个帐户的所有已分配角色,请使用以下语句:
将DEFAULT ROLE ALL设置为 'DEV1' @ 'localhost' 的, 'read_user1' @ 'localhost' 的, 'read_user2' @ 'localhost' 的, 'rw_user1' @ '本地主机';
现在,如果您连接为
rw_user1
,则初始值
CURRENT_ROLE()
反映新的默认角色分配:
MySQL的> SELECT CURRENT_ROLE();
+ -------------------------------- +
| CURRENT_ROLE()|
+ -------------------------------- +
| `app_read` @`%`,`app_write` @`%`|
+ -------------------------------- +
要在用户连接到服务器时自动激活所有显式授权和强制角色,请启用
activate_all_roles_on_login
系统变量。
默认情况下,禁用自动角色激活。
在会话中,用户可以执行
SET
ROLE
以更改活动角色集。
例如,对于
rw_user1
:
MySQL的>SET ROLE NONE; SELECT CURRENT_ROLE();
+ ---------------- + | CURRENT_ROLE()| + ---------------- + | 没有| + ---------------- + MySQL的>SET ROLE ALL EXCEPT 'app_write'; SELECT CURRENT_ROLE();
+ ---------------- + | CURRENT_ROLE()| + ---------------- + | `app_read` @`%`| + ---------------- + MySQL的>SET ROLE DEFAULT; SELECT CURRENT_ROLE();
+ -------------------------------- + | CURRENT_ROLE()| + -------------------------------- + | `app_read` @`%`,`app_write` @`%`| + -------------------------------- +
第一个
SET
ROLE
语句停用所有角色。
第二个
rw_user1
有效地只读。
第三个恢复默认角色。
存储的程序和视图对象的有效用户受到
DEFINER
和
SQL
SECURITY
属性的
约束,这些
属性确定执行是在调用者或定义者上下文中发生的(参见
第24.6节“存储对象访问控制”
):
在调用程序上下文中执行的存储程序和视图对象使用当前会话中处于活动状态的角色执行。
在定义上下文中执行的存储程序和视图对象使用其
DEFINER
属性中
命名的用户的默认角色执行
。
如果
activate_all_roles_on_login
启用,则此类对象将执行授予
DEFINER
用户的
所有角色
,包括强制角色。
对于存储的程序,如果执行的角色与默认角色不同,则应执行程序体
SET
ROLE
以激活所需的角色。
正如角色可以授予帐户一样,可以从帐户中撤消它们:
REVOKErole
FROMuser
;
mandatory_roles
系统变量值中
命名的角色
无法撤消。
REVOKE
也可以应用于角色以修改授予它的权限。
这不仅会影响角色本身,还会影响授予该角色的任何帐户。
假设您要暂时使所有应用程序用户只读。
为此,请使用
REVOKE
以撤消
app_write
角色
的修改权限
:
REVOKE INSERT,UPDATE,DELETE ON app_db。* FROM'app_write';
实际上,这使得角色完全没有特权,正如可以看到的那样
SHOW
GRANTS
(这表明该语句可以与角色一起使用,而不仅仅是用户):
MySQL的> SHOW GRANTS FOR 'app_write';
+ --------------------------------------- +
| 为app_write @%|授予补助金
+ --------------------------------------- +
| 使用*。*来'app_write` @`%`|
+ --------------------------------------- +
因为从角色中撤销特权会影响谁被分配了修改角色的任何用户的权限,
rw_user1
现在已经没有表修改权限(
INSERT
,
UPDATE
,和
DELETE
不再存在):
MySQL的>SHOW GRANTS FOR 'rw_user1'@'localhost'
USING 'app_read', 'app_write';
+ ------------------------------------------------- --------------- + | 为rw_user1 @ localhost |授予补助金 + ------------------------------------------------- --------------- + | 授予使用*。*给`rw_user1` @`localhost` | | GRANT SELECT ON`app_db`。* to`rw_user1` @`localhost` | | GRANT`app_read` @`%`,`app_write` @`%`to`rw_user1` @`localhost` | + ------------------------------------------------- --------------- +
实际上,
rw_user1
读/写用户已成为只读用户。
对于授予该
app_write
角色的
任何其他帐户也会发生这种情况
,说明如何使用角色使得不必修改个人帐户的权限。
要恢复角色的修改权限,只需重新授予它们:
GRANT INSERT,UPDATE,DELETE ON app_db。* TO'app_write';
现在
rw_user1
再次具有修改权限,授予该
app_write
角色的
任何其他帐户也是如此
。
要删除角色,请使用
DROP
ROLE
:
DROP ROLE'app_read','app_write';
删除角色会从授予它的每个帐户撤消该角色。
mandatory_roles
无法删除
在
系统变量值中
命名的角色
。
正如之前所暗示的那样
SHOW
GRANTS
,它显示了用户帐户或角色的授权,帐户和角色可以互换使用。
角色和用户之间的一个区别是
CREATE
ROLE
创建默认锁定
CREATE
USER
的授权标识符
,而
创建默认情况下解锁的授权标识符。
但是,区别不是不可变的,因为具有适当权限的用户可以在创建角色或用户后锁定或解锁它们。
如果数据库管理员具有特定授权标识符必须是角色的首选项,则可以使用名称方案来传达此意图。
例如,您可以
r_
为您打算成为角色的所有授权标识符
使用
前缀
,而不使用
任何其他内容。
角色和用户之间的另一个区别在于可用于管理它们的权限:
该
CREATE ROLE
和
DROP ROLE
特权只允许使用的
CREATE
ROLE
,并
DROP
ROLE
分别发言。
该
CREATE USER
权限允许使用的
ALTER
USER
,
CREATE
ROLE
,
CREATE
USER
,
DROP
ROLE
,
DROP
USER
,
RENAME
USER
,和
REVOKE
ALL
PRIVILEGES
语句。
因此,
CREATE ROLE
和
DROP ROLE
权限不会像
CREATE USER
只允许创建和删除角色的用户
那样强大
并且可能被授予权限,并且不会执行更一般的帐户操作。
关于用户和角色的权限和可互换性,您可以将用户帐户视为角色,并将该帐户授予其他用户或角色。 其结果是将帐户的权限和角色授予其他用户或角色。
这组语句演示了您可以向用户授予用户权限,向用户授予角色,向角色授予用户权限,或向角色授予角色:
创建用户'u1'; 创造角色'r1'; GRANT SELECT ON db1。* TO'u1'; GRANT SELECT ON db2。* TO'r1'; 创建用户'u2'; 创造角色'r2'; GRANT'u1','r1'到'u2'; GRANT'u1','r1'到'r2';
每种情况下的结果是向被授予者对象授予与授予对象相关联的特权。
执行这些语句之后,每个
u2
并
r2
已经从用户(授予的权限
u1
)和一个角色(
r1
):
MySQL的>SHOW GRANTS FOR 'u2' USING 'u1', 'r1';
+ ------------------------------- + | u2 @%|的补助金 + ------------------------------- + | 使用*。*给'u2` @`%`| | GRANT SELECT ON`db1`。* TO`u2` @`%`| | GRANT选择`db2`。* TO`u2` @`%`| | GRANT`u1` @`%`,`r1` @`%`to`u2` @`%`| + ------------------------------- + MySQL的>SHOW GRANTS FOR 'r2' USING 'u1', 'r1';
+ ------------------------------- + | r2 @%|的补助金 + ------------------------------- + | 授予使用*。*至`r2` @`%`| | GRANT选择`db1`。* TO`r2` @`%`| | GRANT选择`db2`。* to`r2` @`%`| | GRANT`u1` @`%`,`r1` @`%`to`r2` @`%`| + ------------------------------- +
前面的示例仅是说明性的,但用户帐户和角色的可互换性具有实际应用,例如在以下情况中:假设遗留应用程序开发项目在MySQL中的角色出现之前开始,因此与项目关联的所有用户帐户都是直接授予权限(而不是通过授予角色授予权限)。 其中一个帐户是最初被授予特权的开发人员帐户,如下所示:
创建用户'old_app_dev'@'localhost'识别'old_app_devpass'; 在old_app上全部授予。*''old_app_dev'@'localhost';
如果此开发人员离开项目,则必须将权限分配给另一个用户,或者如果开发活动已扩展,则可能将多个用户分配。 以下是处理该问题的一些方法:
不使用角色:更改帐户密码,以便原始开发人员无法使用它,并让新开发人员使用该帐户:
ALTER USER'old_app_dev'@'localhost'ENFENTIFIED BY' new_password
';
使用角色:锁定帐户以防止任何人使用它来连接到服务器:
ALTER USER'old_app_dev'@'localhost'ACCOUNT LOCK;
然后将该帐户视为一个角色。 对于项目的每个新开发人员,创建一个新帐户并向其授予原始开发人员帐户:
CREATE USER'new_app_dev1'@'localhost'ENFENTIFIED BY' new_password
';
GRANT'old_app_dev'@'localhost'TO'new_app_dev1'@'localhost';
效果是将原始开发者帐户权限分配给新帐户。
从MySQL 8.0.16开始,MySQL基于
SYSTEM_USER
特权
结合了用户帐户类别的概念
。
MySQL结合了用户帐户类别的概念,系统和常规用户根据他们是否拥有
SYSTEM_USER
权限进行
区分
:
具有该
SYSTEM_USER
权限的用户是系统用户。
没有
SYSTEM_USER
权限的用户是普通用户。
该
SYSTEM_USER
权限对给定用户可以应用其他权限的帐户有影响,以及用户是否受到其他帐户的保护:
系统用户可以修改系统和常规帐户。
也就是说,拥有对常规帐户执行给定操作的适当权限的用户通过拥有
SYSTEM_USER
也可以对系统帐户执行操作来
启用
。
系统帐户只能由具有适当权限的系统用户修改,而不能由常规用户修改。
具有适当权限的常规用户可以修改常规帐户,但不能修改系统帐户。 具有适当权限的系统和常规用户都可以修改常规帐户。
如果用户具有在常规帐户上执行给定操作的适当权限,则
SYSTEM_USER
允许用户还对系统帐户执行操作。
SYSTEM_USER
并不意味着任何其他特权,因此执行给定帐户操作的能力仍然取决于拥有任何其他所需特权。
例如,如果用户可以授予
常规帐户
SELECT
和
UPDATE
权限,那么
SYSTEM_USER
用户也可以授予
SELECT
和
UPDATE
系统帐户。
通过保护具有
SYSTEM_USER
来自
没有该
权限的帐户
的
权限的帐户,
系统和常规帐户之间的区别可以更好地控制某些帐户管理问题
。
例如,该
CREATE USER
权限不仅可以创建新帐户,还可以修改和删除现有帐户。
如果没有系统用户概念,拥有该
CREATE USER
权限
的用户
可以修改或删除任何现有帐户,包括该
root
帐户。
系统用户的概念允许限制对
root
帐户(本身是系统帐户)的
修改,
因此它们只能由系统用户进行。
定期用户
CREATE
USER
权限仍然可以修改或删除现有帐户,但只能修改或删除常规帐户。
该
SYSTEM_USER
权限会影响这些操作:
帐户操纵。
帐户操作包括创建和删除帐户,授予和撤消权限,更改帐户身份验证特征(如凭据或身份验证插件)以及更改其他帐户特征(如密码到期策略)。
SYSTEM_USER
使用帐户管理语句(例如
CREATE
USER
和)
操纵系统帐户需要
该
权限
GRANT
。
要防止帐户以这种方式修改系统帐户,请将其设为常规帐户,而不是授予其
SYSTEM_USER
权限。
(但是,要完全保护系统帐户不受常规帐户的影响,您还必须保留对常规帐户
mysql
系统架构的
修改权限
。请参阅
保护系统帐户
免受常规帐户
操作
。)
杀死当前会话和在其中执行的语句。
要杀死使用该
SYSTEM_USER
权限
执行的会话或语句,
SYSTEM_USER
除了任何其他所需权限外
,您自己的会话还必须具有该
权限(
CONNECTION_ADMIN
或
SUPER
)
。
在MySQL 8.0.16之前,
CONNECTION_ADMIN
或者
SUPER
足以杀死任何会话或语句。
设置
DEFINER
存储的对象。
要将
DEFINER
存储对象
的
属性
设置
为具有该
SYSTEM_USER
权限
的帐户,
SYSTEM_USER
除了任何其他所需权限之外
,您还必须具有该
权限(
SET_USER_ID
或者
SUPER
)
。
在MySQL 8.0.16之前,
SET_USER_ID
或者
SUPER
足以
DEFINER
为存储对象
指定任何
值。
指定强制角色。
具有该
SYSTEM_USER
权限的
角色
不能列在该值中
mandatory_roles
系统变量
。
在MySQL 8.0.16之前,可以列出任何角色
mandatory_roles
。
在服务器内执行的会话被区分为系统或常规会话,类似于系统和常规用户之间的区别:
拥有该
SYSTEM_USER
权限的会话是系统会话。
不具有
SYSTEM_USER
权限的会话是常规会话。
常规会话只能执行常规用户允许的操作。 系统会话还能够执行仅允许系统用户执行的操作。
会话拥有的权限是直接授予其基础帐户的权限,以及授予会话中当前活动的所有角色的权限。
因此,会话可能是系统会话,因为其帐户已被
SYSTEM_USER
直接
授予
权限,或者因为会话已激活具有
以下
权限的角色
SYSTEM_USER
特权
。
授予会话中未激活的帐户的角色不会影响会话权限。
由于激活和停用角色可以更改会话拥有的权限,因此会话可以从常规会话更改为系统会话,反之亦然。
如果会话激活或停用具有该
SYSTEM_USER
权限
的角色,
则会立即在该会话中立即进行常规会话和系统会话之间的适当更改:
如果常规会话使用该
SYSTEM_USER
权限
激活角色
,则会话将成为系统会话。
如果系统会话取消激活具有该
SYSTEM_USER
权限
的角色
,则会话将成为常规会话,除非具有该
SYSTEM_USER
权限的
其他某个角色
保持活动状态。
这些操作对现有会话没有影响:
如果
SYSTEM_USER
从帐户授予或撤消权限,则帐户的现有会话在常规会话和系统会话之间不会更改。
授予或撤消操作仅影响帐户后续连接的会话。
由会话中调用的存储对象执行的语句以系统或父会话的常规状态执行,即使对象
DEFINER
属性命名系统帐户也是如此。
由于角色激活仅影响会话而非影响帐户,因此授予具有
SYSTEM_USER
常规帐户权限
的角色
不会保护该帐户免受常规用户的影响。
该角色仅保护已激活角色的帐户的会话,并仅保护会话,防止被常规会话杀死。
帐户操作包括创建和删除帐户,授予和撤消权限,更改帐户身份验证特征(如凭据或身份验证插件)以及更改其他帐户特征(如密码到期策略)。
帐户操作可以通过两种方式完成:
通过使用账户管理语句,例如
CREATE
USER
和
GRANT
。
这是首选方法。
通过使用
INSERT
和
等语句直接授予表修改
UPDATE
。
不鼓励使用此方法,但对于
mysql
包含授权表
的
系统架构
具有适当权限的用户可以使用此方法
。
要完全保护系统帐户不被给定帐户修改,请将其设为常规帐户,并且不授予其对
mysql
架构的
修改权限
:
SYSTEM_USER
使用帐户管理语句操作系统帐户需要
该
权限。
要防止帐户以这种方式修改系统帐户,请通过不授予帐户使其成为常规帐户
SYSTEM_USER
。
这包括不授予
SYSTEM_USER
授予该帐户的任何角色。
mysql
即使修改帐户是常规帐户
,
模式的
权限也可以
通过直接修改授权表来操作系统帐户。
要限制通过常规帐户对系统帐户进行未经授权的直接修改,请不要将
mysql
架构的
修改权限授予
帐户(或授予该帐户的任何角色)。
如果常规帐户必须具有适用于所有模式的全局特权,
mysql
则可以使用部分撤消强加的特权限制来防止模式修改。
请参见
第6.2.12节“使用部分撤消的权限限制”
。
与扣除
SYSTEM_USER
权限(防止帐户修改系统帐户而非常规帐户)不同,隐藏
mysql
模式权限会阻止帐户修改系统帐户以及常规帐户。
这应该不是问题,因为如上所述,不鼓励直接授权表修改。
假设您要创建一个
u1
对所有模式具有所有权限
的用户
,除了
u1
应该是普通用户而无法修改系统帐户。
假设
partial_revokes
启用
了
系统变量,请
u1
按如下方式
配置
:
创建用户u1标识' password
';
全部授予*。*至u1 with GRANT OPTION;
- GRANT ALL包括SYSTEM_USER,所以此时
- u1可以操纵系统或常规帐户
REVOKE SYSTEM_USER ON *。* FROM u1;
- 撤销SYSTEM_USER使u1成为普通用户;
- 现在u1可以使用帐户管理语句
- 仅操纵常规帐户
REVOKE ALL ON mysql。* FROM u1;
- 这种部分撤销直接阻止了u1
- 修改授权表以操纵帐户
要阻止
mysql
帐户进行
所有
系统架构访问,请撤消对
mysql
架构的
所有权限
,如刚才所示。
还可以允许部分
mysql
模式访问,例如只读访问。
下面的示例创建具有一个帐户
SELECT
,
INSERT
,
UPDATE
,和
DELETE
特权全球范围内为所有的模式,但只
SELECT
为
mysql
模式:
创建用户u2标识' password
';
GRANT SELECT,INSERT,UPDATE,DELETE ON *。* TO u2;
REVOKE INSERT,UPDATE,DELETE ON mysql。* FROM u2;
另一种可能性是撤消所有
mysql
模式权限,但授予对特定
mysql
表或列的
访问权限
。
即使部分撤销,也可以这样做
mysql
。
以下语句启用
u1
对
mysql
模式
内的
只读访问权限
,但仅对
db
表的表
Host
和
User
列进行
user
:
创建用户u3标识' password
';
全部授予*。*至u3;
REVOKE ALL ON mysql。* FROM u3;
GRANT SELECT on mysql.db TO u3;
GRANT SELECT(主机,用户)ON mysql.user TO u3;
在MySQL 8.0.16之前,除了某些模式之外,不可能授予全局适用的权限。
从MySQL 8.0.16开始,如果
partial_revokes
启用
了
系统变量
,则可以
实现。
具体而言,对于具有全局级别权限的用户,
partial_revokes
可以撤消特定模式的权限,同时为其他模式保留特权。
这样强加的权限限制可能对管理具有全局权限但不允许访问某些模式的帐户有用。
例如,可以允许帐户修改除
mysql
系统架构
中的表之外的任何表
。
为简洁起见,
CREATE
USER
此处显示的语句不包括密码。
对于生产用途,请始终指定帐户密码。
该
partial_revokes
系统变量控制权限限制是否可以放在账户。
默认情况下,
partial_revokes
禁用并尝试部分撤消全局权限会产生错误:
mysql>CREATE USER u1;
mysql>GRANT SELECT, INSERT ON *.* TO u1;
mysql>REVOKE INSERT ON world.* FROM u1;
ERROR 1141(42000):在主机'%'上没有为用户'u1'定义此类授权
要允许
REVOKE
操作,请启用
partial_revokes
:
SET PERSIST partial_revokes = ON;
SET
PERSIST
设置正在运行的MySQL实例的值。
它还会保存该值,使其用于后续服务器重新启动。
要更改正在运行的MySQL实例的值而不保存它以便后续重新启动,请使用
GLOBAL
关键字而不是
PERSIST
。
请参见
第13.7.5.1节“变量赋值的SET语法”
。
与
partial_revokes
启用,部分撤销成功:
mysql>REVOKE INSERT ON world.* FROM u1;
mysql>SHOW GRANTS FOR u1;
+ ------------------------------------------ + | 为u1 @%|拨款 + ------------------------------------------ + | GRANT SELECT,INSERT ON *。* to`u1` @`%`| | REVOKE INSERT ON`world`。* FROM`u1` @`%`| + ------------------------------------------ +
SHOW
GRANTS
列出部分撤销作为
REVOKE
其输出中的语句。
结果表明
u1
具有全局
SELECT
和
INSERT
特权,除了
INSERT
不能对
world
模式中的
表执行
。
也就是说,
u1
对
world
表的
访问
是只读的。
服务器记录通过
mysql.user
系统表
中的部分撤销实现的权限限制
。
如果帐户已部分撤消,则其
User_attributes
列值具有以下
Restrictions
属性:
MySQL的>SELECT User, Host, User_attributes->>'$.Restrictions'
FROM mysql.user WHERE User_attributes->>'$.Restrictions' <> '';
+ ------ + ------ + ----------------------------------- ------------------- + | 用户| 主持人| User_attributes - >>'$。限制'| + ------ + ------ + ----------------------------------- ------------------- + | u1 | %| [{“数据库”:“世界”,“特权”:[“INSERT”]}] | + ------ + ------ + ----------------------------------- ------------------- +
虽然可以对任何模式进行部分撤销
mysql
,但特别是
对
系统模式的
特权限制
可用作防止常规帐户修改系统帐户的策略的一部分。
请参阅
通过常规帐户保护系统帐户免受操纵
。
部分撤销操作受以下条件限制:
部分撤销必须按字面意思命名模式。
不允许
包含
%
或
_
SQL通配符的
模式名称
(例如
myschema%
)。
可以使用部分撤销对不存在的模式进行限制,但前提是全局授予撤销的特权。 如果未全局授予权限,则为不存在的模式撤消该权限会产生错误。
部分撤销仅适用于架构级别。
对于仅全局(例如
FILE
或
BINLOG_ADMIN
)或表,列或例程特权
应用的特权,不能使用部分撤消
。
如前所述,模式级特权的部分撤销在
SHOW
GRANTS
输出中
显示
为
REVOKE
语句。
这与
SHOW
GRANTS
表示
“
普通
”
架构级特权的方式不同:
授予时,模式级特权由
GRANT
输出中
的自己的
语句
表示
:
mysql>CREATE USER u1;
mysql>GRANT UPDATE ON mysql.* TO u1;
mysql>GRANT DELETE ON world.* TO u1;
mysql>SHOW GRANTS FOR u1;
+ --------------------------------------- + | 为u1 @%|拨款 + --------------------------------------- + | 授予使用*。*给'u1` @`%`| | 授予更新`mysql`。* to`u1` @`%`| | GRANT DELETE ON`world`。* to`u1` @`%`| + --------------------------------------- +
撤消时,架构级特权会从输出中消失。
它们不作为
REVOKE
陈述
出现
:
mysql>REVOKE UPDATE ON mysql.* FROM u1;
mysql>REVOKE DELETE ON world.* FROM u1;
mysql>SHOW GRANTS FOR u1;
+ -------------------------------- + | 为u1 @%|拨款 + -------------------------------- + | 授予使用*。*给'u1` @`%`| + -------------------------------- +
当用户授予权限时,授予者对该权限的任何限制都由被授权者继承,除非被授权者已经拥有没有该限制的权限。
考虑以下两个用户,其中一个用户具有全局
SELECT
权限:
创建用户u1,u2; GRANT SELECT ON *。* TO u2;
假设管理用户
admin
具有全局但部分撤销的
SELECT
权限:
mysql>CREATE USER admin;
mysql>GRANT SELECT ON *.* TO admin WITH GRANT OPTION;
mysql>REVOKE SELECT ON mysql.* FROM admin;
mysql>SHOW GRANTS FOR admin;
+ ------------------------------------------------- ----- + | 管理员@%|的拨款 + ------------------------------------------------- ----- + | GRANT SELECT ON *。* TO`admin` @`%`WITH GRANT OPTION | | REVOKE SELECT on`mysql`。* FROM`admin` @`%`| + ------------------------------------------------- ----- +
如果
admin
补助
SELECT
全球范围内
u1
和
u2
,其结果相差为每个用户:
如果
全局
admin
授予(
无
权限开始),则
继承
权限限制:
SELECT
u1
SELECT
u1
admin
mysql>GRANT SELECT ON *.* TO u1;
mysql>SHOW GRANTS FOR u1;
+ ------------------------------------------ + | 为u1 @%|拨款 + ------------------------------------------ + | GRANT SELECT ON *。* TO`u1` @`%`| | REVOKE SELECT on`mysql`。* FROM`u1` @`%`| + ------------------------------------------ +
另一方面,
u2
已经拥有一个
SELECT
没有限制
的全球
特权。
GRANT
只能添加到受让人现有的特权,而不是减少他们,所以如果
admin
授予
SELECT
在全球范围内
u2
,
u2
不继承的
admin
限制:
mysql>GRANT SELECT ON *.* TO u2;
mysql>SHOW GRANTS FOR u2;
+ --------------------------------- + | u2 @%|的补助金 + --------------------------------- + | GRANT SELECT ON *。* TO`u2` @`%`| + --------------------------------- +
如果
GRANT
语句包含
子句,则应用的权限限制是由子句指定的用户/角色组合上的权限,而不是执行该语句的用户的权限限制。
有关该
子句的
信息
,请参见
第13.7.1.6节“GRANT语法”
。
AS
user
AS
授予帐户的新权限的限制将添加到该帐户的任何现有限制中:
mysql>CREATE USER u1;
mysql>GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO u1;
mysql>REVOKE INSERT ON mysql.* FROM u1;
mysql>SHOW GRANTS FOR u1;
+ ------------------------------------------------- -------- + | 为u1 @%|拨款 + ------------------------------------------------- -------- + | GRANT SELECT,INSERT,UPDATE,DELETE ON *。* TO`u1` @`%`| | REVOKE INSERT ON`mysql`。* FROM`u1` @`%`| + ------------------------------------------------- -------- + mysql>REVOKE DELETE, UPDATE ON db2.* FROM u1;
mysql>SHOW GRANTS FOR u1;
+ ------------------------------------------------- -------- + | 为u1 @%|拨款 + ------------------------------------------------- -------- + | GRANT SELECT,INSERT,UPDATE,DELETE ON *。* TO`u1` @`%`| | REVOKE UPDATE,删除`db2`。* FROM`u1` @`%`| | REVOKE INSERT ON`mysql`。* FROM`u1` @`%`| + ------------------------------------------------- -------- +
特权限制聚合既适用于显式部分撤销特权(如刚才所示),也适用于从执行语句的用户或
子句中
提到的用户隐式继承限制的情况
。
AS
user
如果帐户对架构具有权限限制:
该帐户无法向其他帐户授予对受限架构或其中任何对象的特权。
另一个没有限制的帐户可以为受限制的帐户或其中的对象授予受限帐户的权限。 假设一个不受限制的用户执行这些语句:
创建用户u1; GRANT SELECT,INSERT,UPDATE ON *。* TO u1; REVOKE SELECT,INSERT,UPDATE on mysql。* FROM u1; GRANT SELECT ON mysql.user TO u1; - grant table特权 GRANT SELECT(主机,用户)ON mysql.db TO u1; - 授予列权限
生成的帐户具有这些权限,能够在受限模式中执行有限的操作:
MySQL的> SHOW GRANTS FOR u1;
+ ------------------------------------------------- ---------- +
| 为u1 @%|拨款
+ ------------------------------------------------- ---------- +
| GRANT SELECT,INSERT,UPDATE ON *。* to`u1` @`%`|
| REVOKE SELECT,INSERT,UPDATE on`mysql`。* FROM`u1` @`%`|
| GRANT SELECT(`Host`,`User`)on`mysql` .db` to`u1` @`%`|
| GRANT SELECT on`mysql` .user` TO`u1` @`%`|
+ ------------------------------------------------- ---------- +
如果帐户对全局权限有限制,则通过以下任何操作都会删除该限制:
通过对权限没有限制的帐户向帐户全局授予权限。
在架构级别授予权限。
全球撤销特权。
考虑一个
u1
全局拥有多个权限但受到限制的用户
INSERT
,
UPDATE
并且
DELETE
:
mysql>CREATE USER u1;
mysql>GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO u1;
mysql>REVOKE INSERT, UPDATE, DELETE ON mysql.* FROM u1;
mysql>SHOW GRANTS FOR u1;
+ ------------------------------------------------- --------- + | 为u1 @%|拨款 + ------------------------------------------------- --------- + | GRANT SELECT,INSERT,UPDATE,DELETE ON *。* TO`u1` @`%`| | REVOKE INSERT,UPDATE,DELETE ON`mysql`。* FROM`u1` @`%`| + ------------------------------------------------- --------- +
u1
从没有限制的帐户
全局授予权限
会删除权限限制。
例如,要删除
INSERT
限制:
mysql>GRANT INSERT ON *.* TO u1;
mysql>SHOW GRANTS FOR u1;
+ ------------------------------------------------- -------- + | 为u1 @%|拨款 + ------------------------------------------------- -------- + | GRANT SELECT,INSERT,UPDATE,DELETE ON *。* TO`u1` @`%`| | REVOKE UPDATE,删除`mysql`。* FROM`u1` @`%`| + ------------------------------------------------- -------- +
在架构级别授予权限以
u1
删除权限限制。
例如,要删除
UPDATE
限制:
mysql>GRANT UPDATE ON mysql.* TO u1;
mysql>SHOW GRANTS FOR u1;
+ ------------------------------------------------- -------- + | 为u1 @%|拨款 + ------------------------------------------------- -------- + | GRANT SELECT,INSERT,UPDATE,DELETE ON *。* TO`u1` @`%`| | REVOKE DELETE ON`mysql`。* FROM`u1` @`%`| + ------------------------------------------------- -------- +
撤消全局权限会删除该权限,包括对其的任何限制。
例如,要删除
DELETE
限制(以删除所有
DELETE
访问权
为代价
):
mysql>REVOKE DELETE ON *.* FROM u1;
mysql>SHOW GRANTS FOR u1;
+ ------------------------------------------------- + | 为u1 @%|拨款 + ------------------------------------------------- + | GRANT SELECT,INSERT,UPDATE ON *。* to`u1` @`%`| + ------------------------------------------------- +
如果帐户在全局级别和架构级别都具有权限,则必须在架构级别将其撤消两次以实现部分撤消。
假设
u1
具有这些权限,
INSERT
全局和
world
模式
都保存在
哪里
:
mysql>CREATE USER u1;
mysql>GRANT SELECT, INSERT ON *.* TO u1;
mysql>GRANT INSERT ON world.* TO u1;
mysql>SHOW GRANTS FOR u1;
+ ----------------------------------------- + | 为u1 @%|拨款 + ----------------------------------------- + | GRANT SELECT,INSERT ON *。* to`u1` @`%`| | GRANT INSERT ON`world`。* to`u1` @`%`| + ----------------------------------------- +
撤销
INSERT
上
world
会撤销模式级特权(
SHOW
GRANTS
不再显示模式级
GRANT
语句):
mysql>REVOKE INSERT ON world.* FROM u1;
mysql>SHOW GRANTS FOR u1;
+ ----------------------------------------- + | 为u1 @%|拨款 + ----------------------------------------- + | GRANT SELECT,INSERT ON *。* to`u1` @`%`| + ----------------------------------------- +
撤销
INSERT
上
world
再次执行全局权限(的部分撤销
SHOW
GRANTS
,现在包括模式级
REVOKE
语句):
mysql>REVOKE INSERT ON world.* FROM u1;
mysql>SHOW GRANTS FOR u1;
+ ------------------------------------------ + | 为u1 @%|拨款 + ------------------------------------------ + | GRANT SELECT,INSERT ON *。* to`u1` @`%`| | REVOKE INSERT ON`world`。* FROM`u1` @`%`| + ------------------------------------------ +
为了提供对某些模式而非其他模式的帐户的访问,部分撤销提供了在不授予全局特权的情况下显式授予模式级访问权的方法的替代方法。 这两种方法有不同的优点和缺点。
授予模式级特权而不是全局特权:
添加新架构:默认情况下,现有帐户无法访问架构。 对于应该可以访问架构的任何帐户,DBA必须授予架构级访问权限。
添加新帐户:DBA必须为帐户应有权访问的每个模式授予模式级访问权限。
与部分撤销一起授予全局权限:
添加新架构:具有全局特权的现有帐户可以访问架构。 对于架构应该无法访问的任何此类帐户,DBA必须添加部分撤销。
添加新帐户:DBA必须授予全局权限,并且必须对每个受限制的模式进行部分撤销。
对于访问仅限于少数模式的帐户,使用显式模式级别授权的方法更方便。 对于除了少数几个以外的所有模式具有广泛访问权限的帐户,使用部分撤销的方法更方便。
启用后,
partial_revokes
如果任何帐户具有权限限制
,
则无法禁用。
如果存在任何此类帐户,则禁用
partial_revokes
失败:
对于尝试
partial_revokes
在启动时
禁用
,服务器会记录错误消息并启用
partial_revokes
。
对于
partial_revokes
在运行时
禁用的尝试
,会发生错误并且
partial_revokes
值保持不变。
要
partial_revokes
在存在限制时
禁用
,必须首先删除限制:
确定哪些帐户有部分撤销:
SELECT User,Host,User_attributes - >>'$。Restrictions' FROM mysql.user WHERE User_attributes - >>'$。Restrictions'<>'';
对于每个此类帐户,请删除其权限限制。
假设上一步显示帐户
u1
有这些限制:
[{“数据库”:“世界”,“权限”:[“INSERT”,“DELETE”]
可以通过多种方式删除限制:
全局授予权限,没有任何限制:
GRANT INSERT,DELETE ON *。* TO u1;
在架构级别授予权限:
GRANT INSERT,DELETE ON world。* TO u1;
全局撤销权限(假设不再需要它们):
REVOKE INSERT,DELETE ON *。* FROM u1;
删除帐户本身(假设不再需要):
DROP USER u1;
删除所有权限限制后,可以禁用部分撤消:
SET PERSIST partial_revokes = OFF;
在复制方案中,如果
partial_revokes
在任何主机上启用,则必须在所有主机上启用它。
否则,
REVOKE
部分撤销全局特权的语句对发生复制的所有主机的影响不同,可能导致复制不一致或错误。
如果
没有
选项
启动
mysqld
服务器
--skip-grant-tables
,它会在启动序列期间将所有授权表内容读入内存。
内存表在此时对访问控制有效。
如果使用帐户管理语句间接修改授权表,服务器会注意到这些更改并立即再次将授权表加载到内存中。
帐户管理声明在
第13.7.1节“帐户管理声明”中描述
。
实例包括
GRANT
,
REVOKE
,
SET
PASSWORD
,和
RENAME
USER
。
如果你修改授权表直接使用的语句,例如
INSERT
,
UPDATE
或
DELETE
(不推荐),该变化对特权的效果检查,直到你要么告诉服务器重新加载表或重新启动它。
因此,如果直接更改授权表但忘记重新加载它们,则在
重新启动服务器之前
,更改
不会生效
。
这可能会让您想知道为什么您的更改似乎没有任何区别!
要告诉服务器重新加载授权表,请执行flush-privileges操作。
这可以通过发出
FLUSH PRIVILEGES
语句或执行
mysqladmin flush-privileges
或
mysqladmin reload
命令来完成。
授权表重新加载会影响每个现有客户端会话的权限,如下所示:
表和列权限更改将随客户端的下一个请求生效。
数据库权限更改将在客户端下次执行
语句
时生效
。
USE
db_name
客户端应用程序可以缓存数据库名称 因此,如果不实际更改为不同的数据库,这些效果可能对他们不可见。
对于已连接的客户端,全局权限和密码不受影响。 这些更改仅在后续连接的会话中生效。
对会话中的活动角色集的更改将立即生效,仅适用于该会话。
该
SET
ROLE
语句执行会话角色激活和取消激活(请参见
第13.7.1.11节“SET ROLE语法”
)。
如果使用该
--skip-grant-tables
选项
启动服务器
,则它不会读取授权表或实现任何访问控制。
任何用户都可以连接并执行任何操作,
这是不安全的。
为了使服务器因此开始读取表并启用访问检查,请刷新权限。
连接到MySQL服务器的客户端所需的凭据可以包含密码。 本节介绍如何为MySQL帐户分配密码。
MySQL将凭证存储在
系统数据库
的
user
表中
mysql
。
分配或修改密码的操作仅允许具有该
CREATE USER
特权的
用户
,或者
mysql
数据库的
INSERT
特权(创建新帐户的
UPDATE
特权,修改现有帐户的特权)。
如果
read_only
启用
了
系统变量,则使用帐户修改语句,例如
CREATE
USER
或
ALTER
USER
另外需要
CONNECTION_ADMIN
或
SUPER
特权。
此处的讨论仅总结了最常见的密码赋值语句的语法。 有关其他可能性的完整详细信息,请参见 第13.7.1.3节“创建用户语法” , 第13.7.1.1节“ALTER USER语法” 和 第13.7.1.10节“SET PASSWORD语法” 。
MySQL使用插件来执行客户端身份验证;
请参见
第6.2.17节“可插入的身份验证”
。
在密码分配语句中,与帐户关联的身份验证插件执行指定的明文密码所需的任何散列。
这使MySQL能够在将密码存储在
mysql.user
系统表
之前对其进行模糊处理
。
对于此处描述的语句,MySQL会自动散列指定的密码。
还有语法的
CREATE
USER
和
ALTER
USER
从字面上指定许可证哈希值。
有关详细信息,请参阅这些语句的说明。
要在创建新帐户时指定密码,请使用
CREATE
USER
并包含
IDENTIFIED BY
子句:
创建用户'jeffrey'@'localhost'标识' password
';
CREATE
USER
还支持指定帐户身份验证插件的语法。
请参见
第13.7.1.3节“创建用户语法”
。
要为现有帐户分配或更改密码,请使用
ALTER
USER
带有
IDENTIFIED BY
子句
的
语句
:
ALTER USER'jeffrey'@'localhost'ENFENTIFIED BY' password
';
如果您未以匿名用户身份进行连接,则可以更改自己的密码,而无需按字面指定自己的帐户:
ALTER USER USER()通过' password
' 标识;
要从命令行更改帐户密码,请使用 mysqladmin 命令:
mysqladmin -uuser_name
-hhost_name
密码“password
”
此命令设置密码的帐户是
mysql.user
系统表中与
列
匹配
user_name
的
User
行以及
您
在
Host
列中
连接
的客户端主机
。
使用 mysqladmin 设置密码 应该被认为是 不安全的 。 在某些系统上,您的密码对系统状态程序(例如 ps) 可见 ,其他用户可以调用它来显示命令行。 MySQL客户端通常在初始化序列期间用零覆盖命令行密码参数。 但是,仍然存在一个短暂的间隔,在该间隔期间值是可见的。 此外,在某些系统上,此覆盖策略无效,并且 ps 仍然可以看到密码 。 (SystemV Unix系统和其他人可能遇到这个问题。)
如果您使用的是MySQL Replication,请注意,目前,复制从属设备使用的密码作为
CHANGE
MASTER TO
语句的
一部分
实际上限制为32个字符;
如果密码较长,则会截断任何多余的字符。
这不是由于MySQL服务器通常施加的任何限制,而是MySQL Replication特有的问题。
(有关更多信息,请参阅Bug#43439。)
MySQL支持这些密码管理功能:
密码过期,要求定期更改密码。
密码重用限制,以防止再次选择旧密码。
密码验证,要求密码更改还指定要替换的当前密码。
双密码,使客户端可以使用主密码或二级密码进行连接。
密码强度评估,要求强密码。
以下部分介绍了这些功能,密码强度评估除外,它使用
validate_password
插件
实现,
并在
第6.4.3节“密码验证组件”中进行了介绍
。
MySQL使用
mysql
系统数据库中的
表实现密码管理功能
。
如果从早期版本升级MySQL,则系统表可能不是最新的。
在这种情况下,服务器会在启动过程中将与此类似的消息写入错误日志(具体数字可能会有所不同):
[错误] mysql.user的列数错误。预期 49,发现47.该表可能已损坏 [警告] ACL表mysql.password_history缺失。 某些操作可能会失败。
要解决此问题,请执行MySQL升级过程。 请参见 第2.11节“升级MySQL” 。 在此之前, 无法更改密码。
这里所描述的密码管理功能仅适用于内部存储凭据的账户
mysql.user
系统表(
mysql_native_password
,
sha256_password
,或
caching_sha2_password
)。
对于使用对外部凭据系统执行身份验证的插件的帐户,还必须在该系统外部处理密码管理。
MySQL使数据库管理员可以手动使帐户密码过期,并建立自动密码过期的策略。 可以在全局建立到期策略,并且可以将个人帐户设置为遵循全局策略或使用特定的每帐户行为覆盖全局策略。
要手动过期帐户密码,请使用以下
ALTER
USER
语句:
ALTER USER'jeffrey'@'localhost'PASSWORD EXPIRE;
此操作将密码在
mysql.user
系统表
的相应行中标记为已过期
。
根据策略的密码到期是自动的,并且基于密码年龄,对于给定帐户,密码年龄根据其最近密码更改的日期和时间进行评估。
该
mysql.user
系统表显示为每个帐户时,其上次更改口令,服务器自动将作为客户端连接的过期时间,如果它的年龄比它允许生存更大的口令。
这适用于没有明确的手动密码到期。
要全局建立自动密码到期策略,请使用
default_password_lifetime
系统变量。
其默认值为0,禁用自动密码到期。
如果值为
default_password_lifetime
正整数
N
,则表示允许的密码生存期,因此必须每天更改密码
N
。
例子:
要建立密码具有大约六个月生命周期的全局策略,请在服务器
my.cnf
文件中
使用以下行启动服务器
:
的[mysqld] default_password_lifetime = 180
要建立密码永不过期的全局策略,请设置
default_password_lifetime
为0:
的[mysqld] default_password_lifetime = 0
default_password_lifetime
也可以在运行时设置和持久化:
SET PERSIST default_password_lifetime = 180; SET PERSIST default_password_lifetime = 0;
SET
PERSIST
设置正在运行的MySQL实例的值。
它还保存了用于后续服务器重启的值;
请参见
第13.7.5.1节“变量赋值的SET语法”
。
要更改正在运行的MySQL实例的值而不保存它以便后续重新启动,请使用
GLOBAL
关键字而不是
PERSIST
。
全局密码到期策略适用于尚未设置为覆盖它的所有帐户。
要为个人帐户建立策略,请使用
和
语句
的
PASSWORD EXPIRE
选项
。
请参见
第13.7.1.3节“创建用户语法”
和
第13.7.1.1节“更改用户语法”
。
CREATE
USER
ALTER USER
特定于帐户的语句示例:
要求密码每90天更改一次:
创建用户'jeffrey'@'localhost'密码EXPIRE INTERVAL 90天; ALTER USER'jeffrey'@'localhost'PASSWORD EXPIRE INTERVAL 90天;
此到期选项会覆盖该语句指定的所有帐户的全局策略。
禁用密码到期:
创建用户'jeffrey'@'localhost'密码永远不会出现; ALTER USER'jeffrey'@'localhost'PASSWORD EXPIRE NEVER;
此到期选项会覆盖该语句指定的所有帐户的全局策略。
遵循该语句指定的所有帐户的全局过期策略:
创建用户'jeffrey'@'localhost'PASSWORD EXPIRE DEFAULT; ALTER USER'jeffrey'@'localhost'PASSWORD EXPIRE DEFAULT;
当客户端成功连接时,服务器会确定帐户密码是否已过期:
服务器检查密码是否已手动过期。
否则,服务器根据自动密码过期策略检查密码年龄是否大于其允许的生存期。 如果是,则服务器认为密码已过期。
如果密码已过期(无论是手动还是自动),服务器将断开客户端连接或限制允许的操作(请参见 第6.2.16节“过期密码的服务器处理” )。 受限客户端执行的操作会导致错误,直到用户建立新的帐户密码:
MySQL的>SELECT 1;
ERROR 1820(HY000):您必须使用ALTER USER重置密码 执行此语句之前的语句。 MySQL的>ALTER USER USER() IDENTIFIED BY '
查询OK,0行受影响(0.01秒) MySQL的>password
';SELECT 1;
+ --- + | 1 | + --- + | 1 | + --- + 1排(0.00秒)
客户端重置密码后,服务器将恢复会话的正常访问,以及后续使用该帐户的连接。 管理用户也可以重置帐户密码,但该帐户的任何现有受限会话仍然受到限制。 使用该帐户的客户端必须断开连接并重新连接才能成功执行语句。
可以 通过将密码设置为其当前值 来 “ 重置 ” 密码。 作为一个好的政策问题,最好选择不同的密码。 DBA可以通过建立适当的密码重用策略来强制执行非重用。 请参阅 密码重用策略 。
MySQL允许对重用以前的密码进行限制。 可以根据密码更改次数,已用时间或两者来确定重用限制。 可以在全球范围内建立重用策略,并且可以将个人帐户设置为遵循全局策略或使用特定的每帐户行为覆盖全局策略。
帐户的密码历史记录包含过去分配的密码。 MySQL可以限制从此历史记录中选择新密码:
如果根据密码更改次数限制帐户,则无法从指定数量的最新密码中选择新密码。 例如,如果密码更改的最小数量设置为3,则新密码不能与任何最近的3个密码相同。
如果根据已用时间限制帐户,则无法从历史记录中比指定天数更新的密码中选择新密码。 例如,如果密码重用间隔设置为60,则新密码不得超过先前在过去60天内选择的密码。
空密码不会计入密码历史记录中,并且可以随时重复使用。
要全局建立密码重用策略,请使用
password_history
和
password_reuse_interval
系统变量。
例子:
要禁止重复使用365天以外的最后6个密码或密码,请将这些行放在服务器
my.cnf
文件中:
的[mysqld] PASSWORD_HISTORY = 6 password_reuse_interval = 365
要在运行时设置和持久化变量,请使用如下语句:
SET PERSIST password_history = 6; SET PERSIST password_reuse_interval = 365;
SET
PERSIST
设置正在运行的MySQL实例的值。
它还保存了用于后续服务器重启的值;
请参见
第13.7.5.1节“变量赋值的SET语法”
。
要更改正在运行的MySQL实例的值而不保存它以便后续重新启动,请使用
GLOBAL
关键字而不是
PERSIST
。
全局密码重用策略适用于尚未设置为覆盖它的所有帐户。
要为个人帐户建立策略,请使用
和
语句
的
PASSWORD HISTORY
和
PASSWORD REUSE INTERVAL
选项
。
请参见
第13.7.1.3节“创建用户语法”
和
第13.7.1.1节“更改用户语法”
。
CREATE
USER
ALTER USER
特定于帐户的语句示例:
在允许重用之前,至少需要更改5个密码:
创建用户'jeffrey'@'localhost'密码历史5; ALTER USER'jeffrey'@'localhost'PASSWORD HISTORY 5;
此历史记录长度选项会覆盖该语句指定的所有帐户的全局策略。
在允许重用之前至少需要365天:
创建用户'jeffrey'@'localhost'密码重新使用INTERVAL 365天; ALTER USER'jeffrey'@'localhost'PASSWORD REUSE INTERVAL 365天;
此time-elapsed选项会覆盖该语句指定的所有帐户的全局策略。
要结合这两种类型的重用限制,使用
PASSWORD HISTORY
和
PASSWORD
REUSE INTERVAL
在一起:
创建用户'jeffrey'@'localhost' 密码历史5 密码重复间隔365天; 更改用户'jeffrey'@'localhost' 密码历史5 密码重复间隔365天;
这些选项会覆盖语句指定的所有帐户的全局策略重用限制。
遵循两种类型的重用限制的全局策略:
创建用户'jeffrey'@'localhost' 密码历史默认 密码重复使用间隔默认值; 更改用户'jeffrey'@'localhost' 密码历史默认 密码重复使用间隔默认值;
从MySQL 8.0.13开始,可以要求通过指定要替换的当前密码来验证更改帐户密码的尝试。 这使DBA能够阻止用户更改密码,而无需证明他们知道当前密码。 否则可能发生这样的改变,例如,如果一个用户暂时离开终端会话而没有退出,并且恶意用户使用该会话来改变原始用户的MySQL密码。 这可能会产生不幸的后果:
在管理员重置帐户密码之前,原始用户无法访问MySQL。
在密码重置发生之前,恶意用户可以使用良性用户更改的凭据访问MySQL。
可以在全球范围内建立密码验证策略,并且可以将个人帐户设置为遵循全局策略或使用特定的每帐户行为覆盖全局策略。
对于每个帐户,其
mysql.user
行指示是否存在特定于帐户的设置,需要验证密码更改尝试的当前密码。
该设置由
和
语句
的
PASSWORD
REQUIRE
选项
建立
:
CREATE
USER
ALTER USER
如果帐户设置是
PASSWORD REQUIRE
CURRENT
,密码更改必须指定当前密码。
如果帐户设置是
PASSWORD REQUIRE CURRENT
OPTIONAL
,密码更改可能但不需要指定当前密码。
如果帐户设置为
PASSWORD REQUIRE CURRENT
DEFAULT
,则
password_require_current
系统变量确定帐户所需的验证策略:
如果
password_require_current
启用,则密码更改必须指定当前密码。
如果
password_require_current
禁用,则密码更改可能但不需要指定当前密码。
换句话说,如果帐户设置不是
PASSWORD
REQUIRE CURRENT DEFAULT
,则帐户设置优先于
password_require_current
系统变量
建立的全局策略
。
否则,帐户将按照
password_require_current
设置进行操作。
默认情况下,密码验证是可选的:
password_require_current
已禁用,并且创建的帐户没有
PASSWORD
REQUIRE
默认选项
PASSWORD REQUIRE
CURRENT DEFAULT
。
下表显示了每个帐户设置如何与
password_require_current
系统变量值
交互
以确定帐户密码验证所需的策略。
表6.10密码验证策略
每帐户设置 | password_require_current系统变量 | 密码更改需要当前密码? |
---|---|---|
PASSWORD REQUIRE CURRENT |
OFF |
是 |
PASSWORD REQUIRE CURRENT |
ON |
是 |
PASSWORD REQUIRE CURRENT OPTIONAL |
OFF |
没有 |
PASSWORD REQUIRE CURRENT OPTIONAL |
ON |
没有 |
PASSWORD REQUIRE CURRENT DEFAULT |
OFF |
没有 |
PASSWORD REQUIRE CURRENT DEFAULT |
ON |
是 |
无论是否需要验证策略,特权用户都可以更改任何帐户密码而无需指定当前密码。
特权用户是一个谁拥有全球的
CREATE USER
特权或
UPDATE
为特权
mysql
系统数据库。
要全局建立密码验证策略,请使用
password_require_current
系统变量。
其默认值为
OFF
,因此不需要帐户密码更改指定当前密码。
例子:
要建立密码更改必须指定当前密码的全局策略,请在服务器
my.cnf
文件中
使用以下行启动服务器
:
的[mysqld] password_require_current = ON
要
password_require_current
在运行时
设置和持久化
,请使用以下语句之一:
SET PERSIST password_require_current = ON; SET PERSIST password_require_current = OFF;
SET
PERSIST
设置正在运行的MySQL实例的值。
它还保存了用于后续服务器重启的值;
请参见
第13.7.5.1节“变量赋值的SET语法”
。
要更改正在运行的MySQL实例的值而不保存它以便后续重新启动,请使用
GLOBAL
关键字而不是
PERSIST
。
全局密码验证所需策略适用于尚未设置为覆盖它的所有帐户。
要为个人帐户建立策略,请使用
和
语句
的
PASSWORD
REQUIRE
选项
。
请参见
第13.7.1.3节“创建用户语法”
和
第13.7.1.1节“更改用户语法”
。
CREATE
USER
ALTER USER
特定于帐户的语句示例:
要求密码更改指定当前密码:
创建用户'jeffrey'@'localhost'密码请求当前; 更改用户'jeffrey'@'localhost'密码请求当前;
此验证选项会覆盖该语句指定的所有帐户的全局策略。
不要求密码更改指定当前密码(可以但不需要给出当前密码):
创建用户'jeffrey'@'localhost'密码请求当前可选; 更改用户'jeffrey'@'localhost'密码要求当前可选;
此验证选项会覆盖该语句指定的所有帐户的全局策略。
遵循该语句指定的所有帐户的全局密码验证所需策略:
创建用户'jeffrey'@'localhost'密码请求当前默认值; 更改用户'jeffrey'@'localhost'密码请求当前默认值;
当用户使用
ALTER
USER
or
SET
PASSWORD
语句
更改密码时,验证当前密码
。
使用的示例
ALTER
USER
优先
SET
PASSWORD
于此,但此处描述的原则对于两个语句都是相同的。
在password-change语句中,
REPLACE
子句指定要替换的当前密码。
例子:
更改当前用户的密码:
ALTER USER USER()通过'auth_string
'REPLACE'current_auth_string
' 识别;
更改指定用户的密码:
更改用户'jeffrey'@'localhost' 由'auth_string
' 识别 替换'current_auth_string
';
更改命名用户的身份验证插件和密码:
更改用户'jeffrey'@'localhost' 使用caching_sha2_password BY'auth_string
' 识别 替换'current_auth_string
';
该
REPLACE
条款的作用如下:
REPLACE
如果需要对帐户进行密码更改以指定当前密码,则必须给出,因为验证尝试进行更改的用户实际上知道当前密码。
REPLACE
如果帐户的密码更改可能但不需要指定当前密码,则是可选的。
如果
REPLACE
指定,则必须指定正确的当前密码,否则会发生错误。
即使
REPLACE
是可选的
也是如此
。
REPLACE
只有在更改当前用户的帐户密码时才能指定。
(这意味着在刚刚显示的示例中,
jeffrey
除非当前用户是,否则
明确命名帐户的语句将
失败
jeffrey
。)即使特权用户尝试对其他用户进行更改,也是如此。
但是,这样的用户可以更改任何密码而无需指定
REPLACE
。
REPLACE
从二进制日志中省略,以避免向其写入明文密码。
从MySQL 8.0.14开始,允许用户帐户拥有双密码,指定为主密码和辅助密码。 双密码功能可以在以下场景中无缝地执行凭证更改:
系统有大量MySQL服务器,可能涉及复制。
多个应用程序连接到不同的MySQL服务器
必须对应用程序用于连接服务器的帐户进行定期凭据更改。
考虑如果仅允许一个帐户使用一个帐户,必须如何在前一种类型的方案中执行凭据更改。 在这种情况下,必须密切合作,在所有服务器上进行帐户密码更改并传播时,以及更新使用该帐户的所有应用程序以使用新密码。 此过程可能涉及服务器或应用程序不可用的停机时间。
使用双密码,可以分阶段更轻松地更改凭证,无需紧密合作,无需停机:
对于每个受影响的帐户,请在服务器上建立新的主密码,并将当前密码保留为辅助密码。 这使服务器能够识别每个帐户的主密码或辅助密码,而应用程序可以使用与以前相同的密码(现在是辅助密码)继续连接到服务器。
密码更改传播到所有服务器后,使用帐户主密码修改使用任何受影响帐户进行连接的应用程序。
将所有应用程序从辅助密码迁移到主密码后,不再需要辅助密码,可以将其丢弃。 此更改传播到所有服务器后,只能使用每个帐户的主密码进行连接。 凭证更改现已完成。
MySQL实现了双密码功能,其语法可以保存和丢弃辅助密码:
在分配新的主密码时
RETAIN CURRENT PASSWORD
,
ALTER
USER
和
SET
PASSWORD
语句
的
子句
将帐户当前密码保存为其辅助密码。
该
DISCARD OLD PASSWORD
条款用于
ALTER
USER
丢弃帐户二级密码,仅保留主密码。
假设对于先前描述的凭证更改方案,
'appuser1'@'host1.example.com'
应用程序使用
名为的帐户
连接到服务器,并且帐户密码将从更改
为
。
'
password_a
''
password_b
'
要执行此凭据更改,请使用
ALTER
USER
以下内容:
在不是复制从属服务器的每台服务器上,建立
新的
主密码,将当前密码保留为辅助密码:
'
password_b
'appuser1
ALTER USER'appuser1'@'host1.example.com'
由' password_b
' 识别
保留当前密码;
等待密码更改以在整个系统中复制到所有从属服务器。
修改使用该
appuser1
帐户的
每个应用程序,
以便使用密码
而不是
密码连接到服务器
。
'
password_b
''
password_a
'
此时,不再需要二级密码。 在不是复制从属服务器的每台服务器上,丢弃辅助密码:
ALTER USER'appuser1'@'host1.example.com' 丢弃旧密码;
丢弃密码更改已复制到所有从属服务器后,凭据更改完成。
在
RETAIN CURRENT PASSWORD
和
DISCARD OLD PASSWORD
条款具有以下效果:
RETAIN CURRENT PASSWORD
保留帐户当前密码作为其辅助密码,替换任何现有的二级密码。
新密码将成为主密码,但客户端可以使用该帐户使用主密码或辅助密码连接到服务器。
(例外:如果
ALTER
USER
or
SET
PASSWORD
语句
指定的新密码
为空,则辅助密码也会变为空,即使
RETAIN CURRENT PASSWORD
已给出。)
如果
RETAIN CURRENT PASSWORD
为具有空主密码的帐户
指定
,则该语句将失败。
如果帐户具有辅助密码并且您在未指定
RETAIN CURRENT
PASSWORD
的
情况下更改其主密码
,则辅助密码将保持不变。
对于
ALTER
USER
,如果更改分配给该帐户的身份验证插件,则会丢弃该二级密码。
如果更改身份验证插件并指定
RETAIN
CURRENT PASSWORD
,则语句将失败。
对于
ALTER
USER
,
DISCARD OLD PASSWORD
丢弃二级密码(如果存在)。
该帐户仅保留其主密码,客户端可以使用该帐户仅使用主密码连接到服务器。
修改辅助密码的语句需要以下权限:
APPLICATION_PASSWORD_ADMIN
要使用
适用于您自己帐户
的
RETAIN CURRENT
PASSWORD
or
DISCARD OLD
PASSWORD
子句
ALTER
USER
和
SET
PASSWORD
语句,
该
特权是必需的
。
由于大多数用户只需要一个密码,因此需要使用该权限来操作您自己的二级密码。
如果允许某个帐户操作所有帐户的辅助密码,则应授予其
CREATE USER
权限,而不是
APPLICATION_PASSWORD_ADMIN
。
MySQL提供密码过期功能,使数据库管理员能够要求用户重置密码。 密码可以手动过期,并根据自动过期的策略(参见 第6.2.15节“密码管理” )。
对于使用具有过期密码的帐户的每个连接,服务器要么断开客户端连接,要么将客户端限制为 “ 沙箱模式 ” ,其中服务器仅允许客户端重置过期密码所需的那些操作。 服务器采取的操作取决于客户端和服务器设置,如稍后所述。
如果服务器断开客户端连接,则会返回
ER_MUST_CHANGE_PASSWORD_LOGIN
错误:
shell>mysql -u myuser -p
密码:******
ERROR 1862(HY000):您的密码已过期。要登录你必须 使用支持过期密码的客户端更改它。
如果服务器将客户端限制为沙盒模式,则在客户端会话中允许这些操作:
客户端可以使用
ALTER
USER
或
重置帐户密码
SET
PASSWORD
。
重置密码后,服务器将恢复会话的正常访问以及使用该帐户的后续连接。
可以 通过将密码设置为其当前值 来 “ 重置 ” 密码。 作为一个好的政策问题,最好选择不同的密码。 DBA可以通过建立适当的密码重用策略来强制执行非重用。 请参阅 密码重用策略 。
客户端可以使用
SET
语句。
对于会话中不允许的任何操作,服务器返回
ER_MUST_CHANGE_PASSWORD
错误:
MySQL的>USE performance_schema;
ERROR 1820(HY000):您必须使用ALTER USER重置密码 执行此语句之前的语句。 MySQL的>SELECT 1;
ERROR 1820(HY000):您必须使用ALTER USER重置密码 执行此语句之前的语句。
这是 mysql 客户端的 交互式调用通常会发生的情况, 因为默认情况下这样的调用是以沙盒模式进行的。 要清除错误并恢复正常运行,请选择新密码。
对于
mysql
客户端的
非交互式调用
(例如,在批处理模式下),如果密码过期,服务器通常会断开客户端的连接。
要允许非交互式
mysql
调用保持连接以便可以更改密码(使用刚才描述的语句),请将该
--connect-expired-password
选项
添加
到
mysql
命令。
如前所述,服务器是否断开过期密码客户端或将其限制为沙箱模式取决于客户端和服务器设置的组合。 以下讨论描述了相关设置及其交互方式。 该讨论仅适用于密码过期的帐户。 如果客户端使用非激活密码进行连接,则服务器会正常处理客户端。
在客户端,给定客户端指示它是否可以处理过期密码的沙箱模式。 对于使用C客户端库的客户端,有两种方法可以执行此操作:
在连接之前
将
MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS
标志
传递
mysql_options()
给:
arg = 1; result = mysql_options(mysql, MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, &ARG);
在
MySQL的
客户端允许
MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS
,如果调用交互或
--connect-expired-password
选项中给出。
在连接时
将
CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS
标志
传递
给
mysql_real_connect()
:
mysql = mysql_real_connect(mysql, 主机,用户,密码,db, port,unix_socket, CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS);
其他MySQL连接器有自己的约定,用于指示处理沙箱模式的准备情况。 请参阅您感兴趣的连接器的文档。
在服务器端,如果客户端指示它可以处理过期的密码,则服务器将其置于沙箱模式。
如果客户端未指示它可以处理过期的密码(或使用不能如此指示的旧版客户端库),则服务器操作取决于
disconnect_on_expired_password
系统变量
的值
:
如果
disconnect_on_expired_password
启用(默认值),则服务器会断开客户端的
ER_MUST_CHANGE_PASSWORD_LOGIN
错误。
如果
disconnect_on_expired_password
禁用,则服务器将客户端置于沙箱模式。
当客户端连接到MySQL服务器时,服务器使用客户端和客户端主机提供的用户名从
mysql.user
系统表中
选择适当的帐户行
。
然后,服务器对客户端进行身份验证,从帐户行确定哪个身份验证插件适用于客户端:
如果服务器找不到插件,则会发生错误并拒绝连接尝试。
否则,服务器调用该插件来验证用户,并且插件向服务器返回状态,指示用户是否提供了正确的密码并且是否允许连接。
可插入身份验证可实现以下重要功能:
选择身份验证方法。 可插入身份验证使DBA可以轻松选择和更改用于单个MySQL帐户的身份验证方法。
外部认证。
可插入身份验证使客户端可以使用适用于存储除
mysql.user
系统表
之外的凭据的身份验证方法的凭据连接到MySQL服务器
。
例如,可以创建插件以使用外部身份验证方法,如PAM,Windows登录ID,LDAP或Kerberos。
代理用户: 如果允许用户连接,则认证插件可以向服务器返回与连接用户名不同的用户名,以指示连接用户是另一个用户(代理用户)的代理。 当连接持续时,出于访问控制的目的,代理用户被视为具有代理用户的特权。 实际上,一个用户冒充另一个用户。 有关更多信息,请参见 第6.2.18节“代理用户” 。
如果使用该
--skip-grant-tables
选项
启动服务器,
即使已加载,也不会使用身份验证插件,因为服务器不执行客户端身份验证并允许任何客户端连接。
因为这是不安全的,如果使用该
--skip-grant-tables
选项
启动服务器
,它会
--skip-networking
自动
启用
以防止远程连接。
MySQL 8.0提供了这些身份验证插件:
一个执行本机身份验证的插件;
也就是说,基于在MySQL中引入可插入身份验证之前使用的密码哈希方法的身份验证。
该
mysql_native_password
插件基于此本机密码哈希方法实现身份验证。
请参见
第6.4.1.1节“本机可插入认证”
。
使用SHA-256密码散列执行身份验证的插件。 这比本机身份验证提供的加密更强。 请参见 第6.4.1.2节“SHA-256可插拔认证” 和 第6.4.1.3节“高速缓存SHA-2可插入认证” 。
客户端插件,无需散列或加密即可将密码发送到服务器。 此插件与服务器端插件结合使用,这些插件需要完全按照客户端用户提供的密码访问。 请参见 第6.4.1.4节“客户端明文可插拔认证” 。
一个使用PAM(可插入身份验证模块)执行外部身份验证的插件,使MySQL Server能够使用PAM对MySQL用户进行身份验证。 此插件也支持代理用户。 请参见 第6.4.1.5节“PAM可插拔认证” 。
一个在Windows上执行外部身份验证的插件,使MySQL Server能够使用本机Windows服务来验证客户端连接。 已登录Windows的用户可以根据其环境中的信息从MySQL客户端程序连接到服务器,而无需指定其他密码。 此插件也支持代理用户。 请参见 第6.4.1.6节“Windows可插入验证” 。
使用LDAP(轻量级目录访问协议)执行身份验证的插件,通过访问X.500等目录服务来验证MySQL用户。 这些插件也支持代理用户。 请参见 第6.4.1.7节“LDAP可插入认证” 。
一个插件,阻止所有客户端连接到任何使用它的帐户。 此插件的用例包括永远不允许直接登录的代理帐户,但只能通过代理帐户和帐户访问,这些帐户和帐户必须能够以提升的权限执行存储的程序和视图,而不会将这些权限暴露给普通用户。 请参见 第6.4.1.8节“无登录可插入认证” 。
一个插件,用于验证从本地主机通过Unix套接字文件连接的客户端。 请参见 第6.4.1.9节“Socket Peer-Credential Pluggable Authentication” 。
一个测试插件,用于检查帐户凭据并将成功或失败记录到服务器错误日志中。 此插件旨在用于测试和开发目的,并作为如何编写身份验证插件的示例。 请参见 第6.4.1.10节“测试可插拔认证” 。
有关使用可插入身份验证的当前限制的信息,包括哪些连接器支持哪些插件,请参见 第C.9节“可插入身份验证的限制” 。
第三方连接器开发人员应阅读该部分,以确定连接器可以利用可插入身份验证功能的程度以及采取哪些步骤以使其更加合规。
如果您有兴趣编写自己的身份验证插件,请参见 第29.2.4.9节“编写身份验证插件” 。
本节提供有关安装和使用身份验证插件的一般说明。 有关给定插件的特定说明,请参见 第6.4.1节“身份验证插件” 中描述该插件的 部分 。
通常,可插入身份验证在服务器端和客户端使用一对相应的插件,因此您使用给定的身份验证方法,如下所示:
如有必要,请安装包含相应插件的插件库或库。 在服务器主机上,安装包含服务器端插件的库,以便服务器可以使用它来验证客户端连接。 同样,在每个客户端主机上,安装包含客户端插件的库以供客户端程序使用。 无需安装内置的身份验证插件。
对于您创建的每个MySQL帐户,请指定用于身份验证的相应服务器端插件。
如果帐户要使用默认身份验证插件,则帐户创建语句无需明确指定插件。
该
default_authentication_plugin
系统变量配置默认的身份验证插件。
当客户端连接时,服务器端插件告诉客户端程序使用哪个客户端插件进行身份验证。
如果帐户使用的身份验证方法是服务器和客户端程序的默认方法,则服务器无需与客户端通信使用哪个客户端插件,并且客户端/服务器协商中的往返可以是避免。
对于标准MySQL客户端,例如
mysql
和
mysqladmin
,
可以在命令行上指定
该
选项,作为程序可以使用哪个客户端插件的提示,尽管如果服务器端插件与服务器端插件相关联,服务器将覆盖此选项。用户帐户需要不同的客户端插件。
--default-auth=
plugin_name
如果客户端程序找不到客户端插件库文件,请指定一个
选项以指示插件库目录位置。
--plugin-dir=
dir_name
可插入身份验证可以灵活地选择MySQL帐户的身份验证方法,但在某些情况下,由于客户端和服务器之间的身份验证插件不兼容,无法建立客户端连接。
成功的客户端连接到给定服务器上给定帐户的一般兼容性原则是客户端和服务器都必须支持 帐户所需 的身份验证 方法 。 由于身份验证方法是由身份验证插件实现的,因此客户端和服务器都必须支持 帐户所需 的身份验证 插件 。
身份验证插件不兼容性可能以各种方式出现。 例子:
使用5.7.22或更低版本的MySQL 5.7客户端连接到使用身份验证的MySQL 8.0服务器帐户
caching_sha2_password
。
这失败是因为5.7客户端无法识别MySQL 8.0中引入的插件。
(当
caching_sha2_password
MySQL客户端库和客户端程序中添加了客户端支持
时,此问题在MySQL 5.7及5.7.23中得到解决
。)
使用MySQL 5.5客户端连接到使用身份验证的MySQL 5.6服务器帐户
sha256_password
。
这失败是因为5.5客户端无法识别MySQL 5.6中引入的插件。
使用MySQL 5.7客户端连接到使用身份验证的5.7之前的服务器帐户
mysql_old_password
。
由于多种原因,这会失败。
首先,这种连接需要
--secure-auth=0
,这不再是受支持的选项。
即使它受支持,5.7客户端也无法识别该插件,因为它已在MySQL 5.7中删除。
使用MySQL 5.7客户端从社区分发连接到MySQL 5.7企业服务器帐户,该帐户使用一个仅限企业版的LDAP身份验证插件进行身份验证。 此操作失败,因为社区客户端无权访问Enterprise插件。
通常,当从同一MySQL发行版在客户端和服务器之间建立连接时,不会出现这些兼容性问题。 当来自不同MySQL系列的客户端和服务器之间建立连接时,可能会出现问题。 当MySQL引入新的身份验证插件或删除旧的身份验证插件时,这些问题是开发过程中固有的。 为尽量减少不兼容的可能性,请定期定期升级服务器,客户端和连接器。
存在MySQL客户端/服务器协议的各种实现。
在
libmysqlclient
C API客户端库是一个实现。
一些MySQL连接器(通常不是用C编写的连接器)提供自己的实现。
但是,并非所有协议实现都以相同的方式处理插件身份验证。
本节介绍协议实现者应考虑的身份验证问题。
在客户端/服务器协议中,服务器告诉连接客户端它认为哪个认证插件是默认的。 如果客户端使用的协议实现尝试加载默认插件并且客户端上不存在该插件,则加载操作将失败。 如果默认插件不是客户端尝试连接的帐户实际需要的插件,则这是不必要的失败。
如果客户端/服务器协议实现没有自己的默认身份验证插件的概念,并且总是尝试加载服务器指定的默认插件,那么如果该插件不可用,它将失败并显示错误。
为了避免这个问题,客户端使用的协议实现应该有自己的默认插件,并且应该将它作为它的第一选择(或者,如果无法加载服务器指定的默认插件,则可以使用它作为默认值) 。 例:
在MySQL 5.7中,
libmysqlclient
使用默认选项
mysql_native_password
或通过
MYSQL_DEFAULT_AUTH
选项
指定的插件
mysql_options()
。
当5.7客户端尝试连接到8.0服务器时,服务器
caching_sha2_password
将其
指定
为其默认的身份验证插件,但客户端仍然会发送凭据详细信息
mysql_native_password
或通过其指定的任何内容
MYSQL_DEFAULT_AUTH
。
客户端加载服务器指定的插件的唯一时间是更改插件请求,但在这种情况下,它可以是任何插件,具体取决于用户帐户。 在这种情况下,客户端必须尝试加载插件,如果该插件不可用,则错误不是可选的。
MySQL服务器使用身份验证插件验证客户端连接。 验证给定连接的插件可以请求将连接(外部)用户视为不同的用户以进行特权检查。 这使外部用户成为第二个用户的代理; 也就是说,假设第二个用户的权限:
外部用户是 “ 代理用户 ” (可以冒充或被称为另一个用户的用户)。
第二个用户是 “ 代理用户 ” ( 代理用户 可以承担其身份和特权的用户)。
本节介绍代理用户功能的工作原理。 有关身份验证插件的一般信息,请参见 第6.2.17节“可插入身份验证” 。 有关特定插件的信息,请参见 第6.4.1节“身份验证插件” 。 有关编写支持代理用户的身份验证插件的信息,请参见 第29.2.4.9.4节“在身份验证插件中实现代理用户支持” 。
作为代理用户的替代方案,您可能会发现角色提供了一种将用户映射到特定命名权限集的合适方法。 请参见 第6.2.10节“使用角色” 。
对于给定身份验证插件的代理,必须满足以下条件:
必须通过插件本身或代表插件的MySQL服务器来支持代理。 在后一种情况下,可能需要明确启用服务器支持; 请参阅 代理用户映射的服务器支持 。
必须将外部代理用户的帐户设置为由插件进行身份验证。
使用该
CREATE
USER
语句将帐户与身份验证插件相关联,或
ALTER
USER
更改其插件。
代理用户的帐户必须存在并被授予代理用户承担的权限。
使用
CREATE
USER
和
GRANT
语句。
对于连接到代理帐户的客户端将被视为代理用户,身份验证插件必须返回与客户端用户名不同的用户名,以指示代理帐户的用户名,该用户名定义代理所承担的权限用户。
或者,对于由服务器提供代理映射的插件,代理用户是
PROXY
由代理用户持有
的
特权
确定的
。
代理机制允许仅将外部客户端用户名映射到代理用户名。 没有规定映射主机名:
当客户端连接到服务器时,服务器根据客户端程序传递的用户名和客户端连接的主机确定正确的帐户。
如果该帐户是代理帐户,则服务器会尝试使用身份验证插件返回的用户名和代理帐户的主机名来查找代理帐户的匹配项。 代理帐户中的主机名将被忽略。
请考虑以下帐户定义:
- 创建代理帐户
创建用户'employee_ext'@'localhost'
使用my_auth_plugin识别
AS'my_auth_string';
- 创建代理帐户并授予其权限
创建用户'员工'@'localhost'
识别' employee_password
';
全部授予
员工。*
''employee'@'localhost';
- 授予代理帐户代理帐户的PROXY权限
授予代理权
在'员工'@'localhost'
到'employee_ext'@'localhost';
当客户端
employee_ext
从本地主机
连接时
,MySQL使用名为的插件
my_auth_plugin
执行身份验证。
假设
根据内容
和可能通过咨询某些外部认证系统
my_auth_plugin
返回
employee
服务器
的用户名
'my_auth_string'
。
名称
employee
不同
employee_ext
,因此返回
employee
用作服务器的请求
,以便将
employee_ext
权限检查作为
employee
本地用户
处理
外部
用户。
在这种情况下,
employee_ext
是代理用户并且
employee
是代理用户。
服务器
通过检查
(代理用户)
是否具有
(代理用户)的
特权来
验证
用户是否
employee
可以进行
代理身份验证
。
如果未授予此权限,则会发生错误。
否则,
假定的权限
。
服务器
根据授予的权限
检查客户端会话期间执行的语句
。
在这种情况下,
可以访问
数据库中的
表
。
employee_ext
employee_ext
PROXY
employee
employee_ext
employee
employee_ext
employee
employee_ext
employees
发生代理时,
可以使用
USER()
和
CURRENT_USER()
函数来查看连接用户(代理用户)与其权限在当前会话(代理用户)期间应用的帐户之间的区别。
对于刚刚描述的示例,这些函数返回以下值:
MySQL的> SELECT USER(), CURRENT_USER();
+ ------------------------ + -------------------- +
| USER()| CURRENT_USER()|
+ ------------------------ + -------------------- +
| employee_ext @ localhost | employee @ localhost |
+ ------------------------ + -------------------- +
在
CREATE
USER
创建代理用户帐户的
IDENTIFIED
WITH
语句中,为支持代理的身份验证插件命名
的
子句可选地后跟一个
子句
,该
子句指定服务器在用户连接时传递给插件的字符串。
如果存在,该字符串提供的信息有助于插件确定如何将代理(外部)客户端用户名映射到代理用户名。
每个插件都取决于是否需要该
子句。
如果是这样,身份验证字符串的格式取决于插件打算如何使用它。
有关其接受的身份验证字符串值的信息,请参阅给定插件的文档。
AS
'
auth_string
'AS
PROXY
需要
该
特权才能使外部用户能够以另一个用户的身份进行连接。
要授予此权限,请使用该
GRANT
语句。
例如:
授权'proxied_user
'去'proxy_user
';
该语句在
mysql.proxies_priv
授权表中
创建一行
。
在连接时,
proxy_user
必须表示有效的外部认证的MySQL用户,并且
proxied_user
必须代表有效的本地认证用户。
否则,连接尝试失败。
相应的
REVOKE
语法是:
REVOKE PROXY ON''FROMproxied_user
'proxy_user
';
MySQL
GRANT
和
REVOKE
语法扩展照常工作。
例子:
- 向多个帐户授予PROXY 授权'a'到'b','c','d'; - 撤销多个帐户的PROXY REVOKE PROXY'''从'b','c','d'; - 授予PROXY账户并启用账户授予 - 代理帐户代理 通过授予选项授予'a'到'd'的授权; - 将PROXY授予匿名帐户 授权''''''''';
该
PROXY
特权可以在这些情况下被授予:
通过具有用户
GRANT PROXY ... WITH GRANT
OPTION
的
proxied_user
。
通过
proxied_user
对自身:值
USER()
必须完全匹配
CURRENT_USER()
和
proxied_user
,同时为用户名和账户名的主机名部分。
root
在MySQL安装期间创建
的初始
帐户具有
对所有用户和所有主机
的
PROXY ... WITH GRANT
OPTION
特权
''@''
。
这样可以
root
设置代理用户,以及委托其他帐户设置代理用户的权限。
例如,
root
可以这样做:
创建用户'admin'@'localhost' 通过'测试'识别; 授予代理权 上 ''@'' TO'admin'@'localhost' WITH GRANT OPTION;
这些语句创建了一个
admin
可以管理所有
GRANT PROXY
映射
的
用户
。
例如,
admin
可以这样做:
授予莎莉的权利;
要指定某些或所有用户应使用给定的身份验证插件进行连接,请创建一个
“
空白
”
MySQL帐户(
''@''
),将其与该插件关联,然后让插件返回真实身份验证的用户名(如果与空白用户不同)。
例如,假设存在一个名为
ldap_auth
实现LDAP身份验证
的插件
,并将连接用户映射到开发人员或经理帐户。
要设置用户对这些帐户的代理,请使用以下语句:
- 创建默认代理帐户 用ldap_auth创建用户''''' AS'O = Oracle,OU = MySQL'; - 创建代理帐户 创建用户'开发者'@'localhost' 识别'developer_password
'; 创建用户'经理'@'localhost' 识别'manager_password
'; - 为代理帐户的默认代理帐户授予PROXY权限 授予代理权 在'经理'@'localhost' 至 ''@''; 授予代理权 ON'开发者'@'localhost' 至 ''@'';
现在假设客户端连接如下:
shell>mysql --user=myuser --password ...
输入密码:myuser_password
服务器将找不到
myuser
定义为MySQL用户。
但是,因为有一个空白的用户帐户(
''@''
相匹配的客户端用户名和主机名),该服务器验证针对该帐户的客户端:服务器调用
ldap_auth
身份验证插件和传球
myuser
,并
myuser_password
把它作为用户名和密码。
如果
ldap_auth
插件在LDAP目录中
myuser_password
找不到正确的密码
myuser
,则身份验证失败,服务器拒绝连接。
如果密码正确并且
ldap_auth
发现它
myuser
是开发人员,则会将用户名返回
developer
给MySQL服务器,而不是
myuser
。
将不同于
myuser
信号
的客户端用户名的用户名返回
到应将其
myuser
视为代理的服务器。
服务器验证
''@''
可以进行身份验证
developer
(因为该帐户
PROXY
有权这样做)并接受连接。
会话继续
myuser
具有
developer
代理用户
的特权
。
(这些权限应由DBA使用
GRANT
语句设置,未显示。)
USER()
和
CURRENT_USER()
函数返回这些值:
MySQL的> SELECT USER(), CURRENT_USER();
+ ------------------ + --------------------- +
| USER()| CURRENT_USER()|
+ ------------------ + --------------------- +
| myuser @ localhost | developer @ localhost |
+ ------------------ + --------------------- +
如果插件改为在
myuser
作为管理器
的LDAP目录中找到
,则它将
manager
作为用户名
返回
,并且会话继续
myuser
具有特权
manager
。
MySQL的> SELECT USER(), CURRENT_USER();
+ ------------------ + ------------------- +
| USER()| CURRENT_USER()|
+ ------------------ + ------------------- +
| myuser @ localhost | 经理@ localhost |
+ ------------------ + ------------------- +
为简单起见,外部身份验证不能是多级的:
在前面的示例中
,并未考虑凭证
developer
和那些
凭证
manager
。
但是,如果客户端尝试直接作为
developer
或
manager
帐户
进行连接和身份验证,则仍会使用它们
,这就是为这些代理帐户分配密码的原因。
确保代理帐户无法直接使用的其他方法:
ACCOUNT LOCK
创建帐户时
包括该
选项。
请参见
第13.7.1.3节“创建用户语法”
。
将帐户与
mysql_no_login
身份验证插件相关联。
请参见
第6.4.1.8节“无登录可插入认证”
。
如果您打算创建默认代理用户,请检查其他现有的 “ 匹配任何用户 ” 帐户,这些帐户优先于默认代理用户,因为它们可能会阻止该用户按预期工作。
在前面的讨论中,默认代理用户帐户
''
在主机部分中具有匹配任何主机的部分。
如果您设置了默认代理用户,请注意检查非代理帐户是否存在同一用户部分和
'%'
主机部分,因为它
'%'
也匹配任何主机,但优先于
''
服务器用于对帐户行进行排序的规则内部(参见
第6.2.6节“访问控制,第1阶段:连接验证”
)。
假设MySQL安装包括以下两个帐户:
- 创建默认代理帐户
创建用户 ''@''
通过some_plugin识别
AS'seat_auth_string';
- 创建匿名帐户
创建用户 ''@'%'
识别' some_password
';
第一个帐户(
''@''
)用作默认代理用户,用于验证与其他帐户不匹配的用户的连接。
第二个帐户(
''@'%'
)是一个匿名用户帐户,例如,可能已创建该帐户,以使没有自己帐户的用户能够匿名连接。
两个帐户都具有相同的用户part(
''
),匹配任何用户。
每个帐户都有一个与任何主机匹配的主机部分。
尽管如此,在帐户匹配优先级的连接尝试,因为匹配规则不大不小的主机
'%'
的前面
''
。
对于与任何更具体的帐户不匹配的帐户,服务器会尝试针对
''@'%'
(匿名用户)而不是
''@''
(默认代理用户)
对其进行身份验证
。
因此,永远不会使用默认代理帐户。
要避免此问题,请使用以下策略之一:
删除匿名帐户,使其不与默认代理用户冲突。 如果您想将每个连接与指定用户相关联,这可能是个好主意。
使用在匿名用户之前匹配的更具体的默认代理用户。
例如,要仅允许
localhost
代理连接,请使用
''@'localhost'
:
创建用户''@'localhost' 通过some_plugin识别 AS'seat_auth_string';
此外,修改任何
GRANT PROXY
语句
''@'localhost'
而不是
''@''
代理用户。
请注意,此策略会阻止匿名用户连接
localhost
。
使用指定的默认帐户而不是匿名默认帐户。
有关此技术的示例,请参阅使用该
authentication_windows
插件
的说明
。
请参见
第6.4.1.6节“Windows可插入身份验证”
创建多个代理用户,一个用于本地连接,另一个用于 “ 其他所有 ” (远程连接)。 当本地用户具有来自远程用户的不同权限时,这尤其有用。
创建代理用户:
- 为本地连接创建代理用户 创建用户''@'localhost' 通过some_plugin识别 AS'seat_auth_string'; - 为远程连接创建代理用户 创建用户 ''@'%' 通过some_plugin识别 AS'seat_auth_string';
创建代理用户:
- 为本地连接创建代理用户 创建用户'开发者'@'localhost' 识别'some_password
'; - 为远程连接创建代理用户 创建用户'开发者'@'%' 识别'some_password
';
为相应的代理用户授予每个代理用户的代理权限:
授予代理权 ON'开发者'@'localhost' 去'''localhost'; 授予代理权 ON'开发者'@'%' 至 ''@'%';
最后,为本地和远程代理用户(未显示)授予适当的权限。
假设
some_plugin
/
'some_auth_string'
组合导致
some_plugin
将客户端用户名映射到
developer
。
本地连接与
''@'localhost'
代理用户
匹配,
代理用户映射到
'developer'@'localhost'
代理用户。
远程连接与
''@'%'
代理用户
匹配,
代理用户映射到
'developer'@'%'
代理用户。
一些身份验证插件为自己实现代理用户映射(例如,PAM和Windows身份验证插件)。
默认情况下,其他身份验证插件不支持代理用户。
其中,有些人可以要求MySQL服务器本身根据授予的代理权限映射代理用户:
mysql_native_password
,
sha256_password
。
如果
check_proxy_users
启用
了
系统变量,则服务器会对发出此类请求的任何身份验证插件执行代理用户映射:
默认情况下,
check_proxy_users
禁用,因此即使对请求服务器支持代理用户的身份验证插件,服务器也不执行代理用户映射。
如果
check_proxy_users
启用,则可能还需要启用特定于插件的系统变量以利用服务器代理用户映射支持:
对于
mysql_native_password
插件,启用
mysql_native_password_proxy_users
。
对于
sha256_password
插件,启用
sha256_password_proxy_users
。
服务器执行的代理用户映射受以下限制:
即使
PROXY
授予
了关联的
权限
,服务器也不会代理匿名用户或从匿名用户代理
。
如果为单个帐户授予了多个代理帐户的代理权限,则服务器代理用户映射是不确定的。 因此,不鼓励为多个代理帐户授予单个帐户代理权限。
两个系统变量有助于跟踪代理登录过程:
proxy_user
:此值
NULL
是否未使用代理。
否则,它表示代理用户帐户。
例如,如果客户端通过
''@''
代理帐户进行
身份验证
,则此变量设置如下:
MySQL的> SELECT @@proxy_user;
+ -------------- +
| @@ proxy_user |
+ -------------- +
| ''@''|
+ -------------- +
external_user
:有时,身份验证插件可能会使用外部用户对MySQL服务器进行身份验证。
例如,使用Windows本机身份验证时,使用Windows API进行身份验证的插件不需要传递给它的登录ID。
但是,它仍使用Windows用户标识进行身份验证。
插件可以使用
external_user
只读会话变量
将此外部用户ID(或其前512个UTF-8字节)返回给服务器
。
如果插件未设置此变量,则其值为
NULL
。
MySQL支持使用
和
语句
的
ACCOUNT LOCK
和
ACCOUNT
UNLOCK
子句
锁定和解锁用户帐户
:
CREATE
USER
ALTER USER
与之一起使用时
CREATE
USER
,这些子句指定新帐户的初始锁定状态。
如果没有任何一个子句,则帐户将以解锁状态创建。
与之一起使用时
ALTER
USER
,这些子句指定现有帐户的新锁定状态。
如果没有任何一个子句,则帐户锁定状态保持不变。
帐户锁定状态记录在
系统表
的
account_locked
列中
mysql.user
。
输出来
SHOW
CREATE USER
指示帐户是锁定还是解锁。
如果客户端尝试连接到锁定的帐户,则尝试失败。
服务器递增
Locked_connects
状态变量,
该
变量指示连接到锁定帐户的尝试次数,返回
ER_ACCOUNT_HAS_BEEN_LOCKED
错误,并将消息写入错误日志:
用户'user_name
'@' 拒绝访问host_name
。 帐户被锁定。
锁定帐户不会影响使用假定锁定帐户身份的代理用户进行连接。
它也不会影响执行存储程序或视图的能力,这些程序或视图具有
DEFINER
命名锁定帐户
的
子句。
也就是说,锁定帐户不会影响使用代理帐户或存储的程序或视图的能力。
帐户锁定功能取决于
系统表中
是否存在
account_locked
列
mysql.user
。
对于早于5.7.6的MySQL版本的升级,请执行MySQL升级过程以确保此列存在。
请参见
第2.11节“升级MySQL”
。
对于没有
account_locked
列的非
升级安装,
服务器会将所有帐户视为已解锁,并使用
ACCOUNT
LOCK
或
ACCOUNT UNLOCK
子句会产生错误。
限制客户端使用MySQL服务器资源的一种方法是将全局
max_user_connections
系统变量设置为非零值。
这限制了任何给定帐户可以同时进行的连接数,但对连接后客户端可以执行的操作没有限制。
此外,设置
max_user_connections
无法管理个人帐户。
MySQL管理员都对这两种控件都很感兴趣。
为了解决这些问题,MySQL允许使用这些服务器资源限制个人帐户:
帐户每小时可以发出的查询数
帐户每小时可以发布的更新次数
帐户每小时可以连接到服务器的次数
帐户与服务器同时连接的数量
客户端可以发出的任何语句都会计入查询限制。 只有修改数据库或表的语句才会计入更新限制。
此上下文中
的
“
帐户
”
对应于
mysql.user
系统表中
的行
。
也就是说,根据
适用于连接
的
表行
中的
User
和
Host
值
来评估
user
连接。
例如,帐户
'usera'@'%.example.com'
对应于
user
表中具有
User
和的
Host
值的行,
usera
以及
%.example.com
允许
usera
从
example.com
域中的
任何主机进行连接
。
在这种情况下,服务器将此行中的资源限制共同应用于
域中
usera
任何主机的
所有连接,
example.com
因为所有此类连接都使用相同的帐户。
在MySQL 5.0之前
,根据用户连接的实际主机评估
“
帐户
”
。
可以通过使用该
--old-style-user-limits
选项
启动服务器来选择这种较旧的记帐方法
。
在这种情况下,如果
usera
同时从
host1.example.com
和
连接
host2.example.com
,则服务器将帐户资源限制分别应用于每个连接。
如果
usera
再次连接
host1.example.com
,则服务器将该连接的限制与该主机的现有连接一起应用。
要在帐户创建时为帐户建立资源限制,请使用该
CREATE
USER
语句。
要修改现有帐户的限制,请使用
ALTER
USER
。
提供一个
WITH
子句,命名每个资源是有限的。
每个限制的默认值为零(无限制)。
例如,要创建可以访问
customer
数据库但只能以有限方式
访问
数据库
的新帐户
,请发出以下语句:
mysql>CREATE USER 'francis'@'localhost' IDENTIFIED BY 'frank'
- >WITH MAX_QUERIES_PER_HOUR 20
- >MAX_UPDATES_PER_HOUR 10
- >MAX_CONNECTIONS_PER_HOUR 5
- >MAX_USER_CONNECTIONS 2;
限制类型不必全部在
WITH
子句中命名,但命名的那些可以按任何顺序存在。
每个每小时限制的值应该是一个表示每小时计数的整数。
对于
MAX_USER_CONNECTIONS
,限制是一个整数,表示帐户的最大同时连接数。
如果此限制设置为零,则全局
max_user_connections
系统变量值确定同时连接的数量。
如果
max_user_connections
也为零,则帐户没有限制。
要修改现有帐户的限制,请使用
ALTER
USER
语句。
以下语句将查询限制更改为
francis
100:
MySQL的> ALTER USER 'francis'@'localhost' WITH MAX_QUERIES_PER_HOUR 100;
该语句仅修改指定的限制值,否则保留帐户不变。
要删除限制,请将其值设置为零。
例如,要删除每小时
francis
可以连接的
次数限制
,请使用以下语句:
MySQL的> ALTER USER 'francis'@'localhost' WITH MAX_CONNECTIONS_PER_HOUR 0;
如前所述,帐户的同时连接限制由
MAX_USER_CONNECTIONS
限制和
max_user_connections
系统变量确定。
假设全局
max_user_connections
值为10,并且三个帐户具有指定的个别资源限制,如下所示:
ALTER USER'user1'@'localhost'WITH MAX_USER_CONNECTIONS 0; ALTER USER'user2'@'localhost'WITH MAX_USER_CONNECTIONS 5; ALTER USER'user3'@'localhost'WITH MAX_USER_CONNECTIONS 20;
user1
连接限制为10(全局
max_user_connections
值),因为它的
MAX_USER_CONNECTIONS
限制为零。
user2
并且分别
user3
具有5和20的连接限制,因为它们具有非零
MAX_USER_CONNECTIONS
限制。
服务器在
user
与该帐户对应
的
表行中
存储帐户的资源限制
。
的
max_questions
,
max_updates
和
max_connections
列存储每小时限制和
max_user_connections
列存储
MAX_USER_CONNECTIONS
限制。
(参见
第6.2.3节“授权表”
。)
当任何帐户对其使用任何资源具有非零限制时,将进行资源使用计数。
在服务器运行时,它会计算每个帐户使用资源的次数。 如果帐户在过去一小时内达到其连接数限制,则服务器将拒绝该帐户的其他连接,直到该小时为止。 同样,如果帐户达到其查询或更新数量的限制,服务器将拒绝进一步的查询或更新,直到小时结束。 在所有这些情况下,服务器都会发出相应的错误消息。
资源计数发生在每个帐户,而不是每个客户。 例如,如果您的帐户的查询限制为50,则无法通过与服务器建立两个同时的客户端连接来将限制增加到100。 在两个连接上发出的查询一起计算。
可以为所有帐户全局重置当前每小时资源使用计数,也可以针对给定帐户单独重置当前每小时资源使用计数:
要将所有帐户的当前计数重置为零,请发出
FLUSH USER_RESOURCES
声明。
还可以通过重新加载授权表来重置计数(例如,使用
FLUSH
PRIVILEGES
语句或
mysqladmin reload
命令)。
通过再次设置其任何限制,可以将个人帐户的计数重置为零。 指定等于当前分配给帐户的值的限制值。
每小时计数器重置不会影响
MAX_USER_CONNECTIONS
限制。
服务器启动时,所有计数从零开始。 计数不会通过服务器重启而延续。
对于
MAX_USER_CONNECTIONS
限制,如果帐户当前已打开允许的最大连接数,则可能出现边缘情况:
如果服务器尚未完全处理断开连接,则
连接快速断开连接可能导致错误(
ER_TOO_MANY_USER_CONNECTIONS
或
ER_USER_LIMIT_REACHED
)连接发生的时间。
当服务器完成断开连接处理时,将再次允许另一个连接。
如果在尝试连接到MySQL服务器时遇到问题,以下各项描述了可以采取的一些操作过程来解决问题。
确保服务器正在运行。 如果不是,客户端无法连接到它。 例如,如果尝试连接到服务器失败并显示以下消息之一,则一个原因可能是服务器未运行:
shell>mysql
ERROR 2003:无法连接到MySQL服务器'host_name
'(111) 外壳>mysql
ERROR 2002:无法通过套接字连接到本地MySQL服务器 '/tmp/mysql.sock'(111)
可能是服务器正在运行,但您尝试使用与服务器正在侦听的TCP / IP端口,命名管道或Unix套接字文件不同的TCP / IP端口进行连接。
要在调用客户端程序时更正此问题,请指定一个
--port
选项以指示正确的端口号,或
指定一个
选项以指示
--socket
正确的命名管道或Unix套接字文件。
要找出套接字文件的位置,可以使用以下命令:
外壳> netstat -ln | grep mysql
确保服务器尚未配置为忽略网络连接或(如果您尝试远程连接)尚未配置为仅在其网络接口上本地侦听。
如果服务器已启动
--skip-networking
,则根本不接受TCP / IP连接。
如果服务器是在
bind_address
系统变量设置为的情况
下启动的
127.0.0.1
,则它将仅在环回接口上本地侦听TCP / IP连接,并且不接受远程连接。
检查以确保没有防火墙阻止访问MySQL。 可以根据正在执行的应用程序或MySQL用于通信的端口号(默认为3306)来配置防火墙。 在Linux或Unix下,检查IP表(或类似)配置以确保端口未被阻止。 在Windows下,可能需要配置ZoneAlarm或Windows防火墙等应用程序,以阻止MySQL端口。
必须正确设置授权表,以便服务器可以使用它们进行访问控制。
对于某些分发类型(例如Windows上的二进制分发版或Linux上的RPM分发版),安装过程会初始化MySQL数据目录,包括
mysql
包含授权表
的
系统数据库。
对于不执行此操作的分发,必须手动初始化数据目录。
有关详细信息,请参见
第2.10节“安装后设置和测试”
。
要确定是否需要初始化授权表,请
mysql
在数据目录下
查找
目录。
(数据目录通常名为
data
或
var
位于MySQL安装目录下。)确保
user.MYD
在
mysql
数据库目录中
有一个文件
。
如果没有,请初始化数据目录。
执行此操作并启动服务器后,您应该能够连接到服务器。
全新安装后,如果您尝试以
root
不使用密码的
身份登录服务器
,则可能会收到以下错误消息。
外壳> mysql -u root
ERROR 1045(28000):用户'root'@'localhost'拒绝访问(使用密码:NO)
这意味着在安装期间已经分配了root密码,并且必须提供该密码。
有关
可以分配密码的不同方法
,
请参见
第2.10.4节“保护初始MySQL帐户”
,在某些情况下,
请参阅
如何查找密码。
如果需要重置root密码,请参见
第B.4.3.2节“如何重置root密码”中的说明
。
找到或重置密码后,请
root
使用
--password
(或
-p
)选项
再次登录
:
外壳> mysql -u root -p
输入密码:
但是,
root
如果您使用
mysqld
初始化MySQL
,则服务器将允许您连接
而不使用密码
--initialize-insecure
(
有关详细信息
,
请参见
第2.10.1节“初始化数据目录”
)。
这是一个安全风险,因此您应该为该
root
帐户
设置密码
;
有关说明,请参见
第2.10.4节“保护初始MySQL帐户”
。
如果您已将现有MySQL安装更新到较新版本,那么您是否执行了MySQL升级过程? 如果没有,请这样做。 添加新功能时,授权表的结构会偶尔发生变化,因此在升级之后,应始终确保表具有当前结构。 有关说明,请参见 第2.11节“升级MySQL” 。
如果客户端程序在尝试连接时收到以下错误消息,则表示服务器期望密码的格式比客户端能够生成的格式更新:
外壳> mysql
客户端不支持请求的身份验证协议
由服务器; 考虑升级MySQL客户端
请记住,客户端程序使用选项文件或环境变量中指定的连接参数。
如果客户端程序在您未在命令行中指定它们时似乎发送了错误的默认连接参数,请检查所有适用的选项文件和您的环境。
例如,如果
Access
denied
在没有任何选项的情况下运行客户端时
获得
,请确保未在任何选项文件中指定旧密码!
您可以通过使用该
--no-defaults
选项
调用客户端程序来禁止使用选项文件
。
例如:
外壳> mysqladmin --no-defaults -u root version
客户端使用的选项文件在 第4.2.2.2节“使用选项文件” 中列出 。 第4.9节“MySQL程序环境变量” 中列出了 环境变量 。
如果您收到以下错误,则表示您使用的
root
密码
不正确
:
外壳> mysqladmin -u root -pxxxx
ver
用户'root'@'localhost'拒绝访问(使用密码:YES)
如果即使您未指定密码也会发生上述错误,则表示某些选项文件中列出了错误的密码。
尝试
--no-defaults
上一项中描述
的
选项。
有关更改密码的信息,请参见 第6.2.14节“分配帐户密码” 。
如果丢失或忘记了
root
密码,请参见
第B.4.3.2节“如何重置root密码”
。
localhost
是本地主机名的同义词,如果未明确指定主机,它也是客户端尝试连接的默认主机。
您可以使用
--host=127.0.0.1
选项明确命名服务器主机。
这将与本地
mysqld
服务器
建立TCP / IP连接
。
您还可以通过指定
--host
使用本地主机的实际主机名的选项来
使用TCP / IP
。
在这种情况下,必须
user
在服务器主机上的表行中
指定主机名
,即使您在与服务器相同的主机上运行客户端程序也是如此。
该
Access denied
错误消息告诉您尝试登录的对象,您尝试连接的客户端主机以及您是否使用了密码。
通常,
user
表中
应该有一行
与错误消息中给出的主机名和用户名完全匹配。
例如,如果您收到包含的错误消息
using password: NO
,则表示您尝试在没有密码的情况下登录。
如果
Access denied
在尝试连接到数据库时出错
,则
表
可能存在问题
。
通过执行
并发出以下SQL语句来检查:
mysql -u
user_name
user
mysql -u root mysql
SELECT * FROM user;
结果应该包含一行,其中
Host
和
User
列匹配客户端的主机名和MySQL用户名。
如果尝试从运行MySQL服务器的主机以外的主机进行连接时发生以下错误,则表示
user
表中
没有
Host
与客户端主机匹配的值的
行
:
Host ...不允许连接到此MySQL服务器
您可以通过为尝试连接时使用的客户端主机名和用户名的组合设置帐户来解决此问题。
如果您不知道要连接的计算机的IP地址或主机名,则应
在
表中添加
一行
'%'
作为
Host
列值
user
。
尝试从客户端计算机连接后,使用
SELECT
USER()
查询来查看您的连接方式。
然后
'%'
将
user
表行中的
更改
为日志中显示的实际主机名。
否则,您的系统将处于不安全状态,因为它允许来自任何主机的连接以获取给定的用户名。
在Linux上,可能发生此错误的另一个原因是您使用的二进制MySQL版本使用与
glibc
您使用
的
库
不同版本的
库进行
编译
。
在这种情况下,您应该升级操作系统
glibc
,或者下载MySQL版本的源代码发行版并
自行
编译。
源RPM通常很容易编译和安装,所以这不是一个大问题。
如果在尝试连接时指定主机名,但是获取未显示主机名或IP地址的错误消息,则表示尝试将客户端主机的IP地址解析为MySQL服务器时出错一个名字:
外壳> mysqladmin -u root -pxxxx
-h some_hostname
ver
用户'root'@''访问被拒绝(使用密码:YES)
如果您尝试连接as
root
并获得以下错误,则表示您的
user
表中没有
User
列值为的行,
'root'
并且
mysqld
无法解析客户端的主机名:
访问被拒绝用户''@'未知'
这些错误表明存在DNS问题。 要修复它,请执行 mysqladmin flush-hosts 以重置内部DNS主机缓存。 请参见 第8.12.4.2节“DNS查找优化和主机缓存” 。
一些永久解决方案是:
确定DNS服务器的问题并进行修复。
在MySQL授权表中指定IP地址而不是主机名。
/etc/hosts
在Unix或
\windows\hosts
Windows
上
为客户端计算机名称添加条目
。
使用该
选项
启动
mysqld
--skip-name-resolve
。
使用该
选项
启动
mysqld
--skip-host-cache
。
在Unix上,如果您在同一台计算机上运行服务器和客户端,请连接到
localhost
。
对于连接
localhost
,MySQL程序尝试使用Unix套接字文件连接到本地服务器,除非指定了连接参数以确保客户端建立TCP / IP连接。
有关更多信息,请参见
第4.2.3节“连接到MySQL服务器”
。
在Windows上,如果在同一台计算机上运行服务器和客户端,并且服务器支持命名管道连接,请连接到主机名
.
(句点)。
连接
.
使用命名管道而不是TCP / IP。
如果
mysql -u root
有效但
结果
(
本地主机的实际主机名
在
哪里
),
表中
的主机可能没有正确的名称
。
这里的常见问题是
表行
中的
值
指定了非限定主机名,但系统的名称解析例程返回完全限定的域名(反之亦然)。
举例来说,如果你有一排主机
的
表,但是你的DNS告诉MySQL你的主机名是
,行也不行。
尝试在
包含主机IP地址
的
表中
添加一行
作为
mysql
-h
your_hostname
-u rootAccess denied
your_hostname
user
Host
user
'pluto'
user
'pluto.example.com'
user
Host
列值。
(或者,您可以
user
使用
Host
包含通配符
的
值
向
表中
添加一行
(例如,
'pluto.%'
)。但是,使用以
Host
值结尾
的
值
%
是
不安全的
,
不
建议使用!)
如果
有效但
没有,则您没有授予对指定数据库的给定用户的访问权限
。
mysql -u
user_name
mysql -u
user_name
some_db
some_db
如果
在服务器主机上执行时有效,但
在远程客户端主机上执行时无效
,
则表示尚未从远程主机启用对服务器的访问权限。
mysql -u
user_name
mysql -h
host_name
-u
user_name
如果您无法弄清楚为什么会得到
Access
denied
,请从
user
表中
删除
所有
Host
包含通配符值的行(包含
'%'
或
'_'
字符的
行
)。
一个非常常见的错误是使用
Host
=
'%'
和
User
=
插入一个新行
,认为这使您可以指定
从同一台计算机进行连接。
这不起作用的原因是默认权限包括带
=
和
=
的行
。
因为该行的
值
比特定的更具体
'
some_user
'localhost
Host
'localhost'
User
''
Host
'localhost'
'%'
,连接时优先使用新行
localhost
!
正确的步骤是插入一个第二行与
Host
=
'localhost'
和
User
=
,或删除的行
=
和
=
。
删除行后,请记住发出
声明以重新加载授权表。
另请参见
第6.2.6节“访问控制,第1阶段:连接验证”
。
'
some_user
'Host
'localhost'
User
''
FLUSH
PRIVILEGES
如果您能够连接到MySQL服务器,但
Access denied
在发出
SELECT
... INTO
OUTFILE
或
LOAD
DATA
声明
时
收到
消息
,则
user
表中的
行
不会
FILE
启用
该
权限。
如果直接更改授权表(例如,通过using
INSERT
,
UPDATE
或
DELETE
语句)并且您的更改似乎被忽略,请记住您必须执行
FLUSH PRIVILEGES
语句或
mysqladmin flush-privileges
命令以使服务器重新加载权限表。
否则,在下次重新启动服务器之前,您的更改将无效。
请记住,在
root
使用
UPDATE
语句
更改
密码
后,在刷新权限之前,您无需指定新密码,因为服务器不知道您已更改密码了!
如果您的权限在会话中间似乎已更改,则可能是MySQL管理员已更改它们。 重新加载授权表会影响新的客户端连接,但它也会影响现有连接,如 第6.2.13节“特权更改生效时”所示 。
如果您有Perl,PHP,Python或ODBC程序的访问问题,请尝试使用
或
连接到服务器
。
如果您能够使用
mysql
客户端
进行连接
,则问题在于您的程序,而不是访问权限。
(
密码和密码
之间没有空格
;您也可以使用
语法指定密码。如果您使用
没有密码值
的
或
选项,MySQL会提示您输入密码。)
mysql -u
user_name
db_name
mysql
-u
user_name
-pyour_pass
db_name
-p
--password=
your_pass
-p
--password
出于测试目的,
使用该
选项
启动
mysqld
服务器
--skip-grant-tables
。
然后,您可以更改MySQL授权表并使用该
SHOW
GRANTS
语句检查您的修改是否具有所需的效果。
如果对更改感到满意,请执行
mysqladmin flush-privileges
以告知
mysqld
服务器重新加载权限。
这使您可以开始使用新的授权表内容,而无需停止并重新启动服务器。
如果其他一切都失败了,请
使用调试选项
启动
mysqld
服务器(例如,
--debug=d,general,query
)。
这将打印有关尝试连接的主机和用户信息,以及有关所发出的每个命令的信息。
请参见
第29.5.4节“DBUG包”
。
如果您对MySQL授权表有任何其他问题,并且认为必须将问题发布到邮件列表,请始终提供MySQL授权表的转储。
您可以使用
mysqldump mysql
命令
转储表
。
要提交错误报告,请参见
第1.7节“如何报告错误或问题”中的说明
。
在某些情况下,你可能需要重新启动
mysqld的
与
--skip-grant-tables
运行
的mysqldump
。
应用程序可以使用以下准则来执行基于SQL的审计,该审计将数据库活动与MySQL帐户联系起来。
MySQL帐户对应于
mysql.user
系统表中的
行
。
当客户端成功连接时,服务器会将客户端验证到此表中的特定行。
此行中
的
User
和
Host
列值唯一标识帐户,并对应于
在SQL语句中写入帐户名称
的
格式。
'
user_name
'@'host_name
'
用于验证客户端的帐户确定客户端具有哪些权限。
通常,
CURRENT_USER()
可以调用
该
函数来确定这对于客户端用户来说是哪个帐户。
其值由
帐户
的
表行的
列
User
和
Host
列构成
user
。
但是,在某些情况下,该
CURRENT_USER()
值不对应于客户端用户,而是对应于不同的帐户。
当权限检查不基于客户端帐户时,会发生这种情况:
存储的例程(过程和函数)定义了
SQL SECURITY DEFINER
特征
用
SQL SECURITY DEFINER
特征
定义的视图
触发器和事件
在这些上下文中,对
DEFINER
帐户
进行权限检查
并
CURRENT_USER()
引用该帐户,而不是引用调用存储的例程或视图的客户端或引发触发器的用户的帐户。
要确定调用用户,可以调用该
USER()
函数,该函数返回一个值,该值指示客户端提供的实际用户名以及客户端连接的主机。
但是,此值不一定直接对应于
user
表中
的帐户
,因为该
USER()
值从不包含通配符,而帐户值(由返回的
CURRENT_USER()
)可能包含用户名和主机名通配符。
例如,空白用户名与任何用户匹配,因此帐户
''@'localhost'
允许客户端以本地主机的匿名用户身份使用任何用户名进行连接。
在这种情况下,如果客户端
user1
从本地主机
连接
,
USER()
并
CURRENT_USER()
返回不同的值:
MySQL的> SELECT USER(), CURRENT_USER();
+ ----------------- + ---------------- +
| USER()| CURRENT_USER()|
+ ----------------- + ---------------- +
| user1 @ localhost | @localhost |
+ ----------------- + ---------------- +
帐户的主机名部分也可以包含通配符。
如果主机名包含
'%'
或
'_'
模式字符或使用网络掩码表示法,则该帐户可用于从多个主机连接的客户端,该
CURRENT_USER()
值不会指示哪个
主机
。
例如,该帐户
'user2'@'%.example.com'
可用于
user2
从
example.com
域中的
任何主机进行连接
。
如果
user2
连接
remote.example.com
,
USER()
并
CURRENT_USER()
返回不同的值:
MySQL的> SELECT USER(), CURRENT_USER();
+ -------------------------- + --------------------- +
| USER()| CURRENT_USER()|
+ -------------------------- + --------------------- +
| user2@remote.example.com | user2@%.example.com |
+ -------------------------- + --------------------- +
如果应用程序必须
USER()
为用户审核
调用
(例如,如果它从触发器内部进行审核),但也必须能够将该
USER()
值与
user
表中
的帐户
相关联
,则必须避免在
User
或
Host
列
中包含通配符的帐户
。
具体来说,不允许
User
为空(创建匿名用户帐户),并且不允许在
Host
值中使用
模式字符或网络掩码表示法
。
所有帐户必须具有非空
User
值和字
Host
面值。
对于前面的示例,
应更改
''@'localhost'
和
'user2'@'%.example.com'
帐户不使用通配符:
RENAME USER''@'localhost'TO'user1'@'localhost'; RENAME USER'user2'@'%.example.com'TO'user2'@'remote.example.com';
如果
user2
必须能够从
example.com
域中的
多个主机进行连接
,则每个主机应该有一个单独的帐户。
要从
CURRENT_USER()
或
USER()
值中
提取用户名或主机名部分
,请使用以下
SUBSTRING_INDEX()
函数:
MySQL的>SELECT SUBSTRING_INDEX(CURRENT_USER(),'@',1);
+ --------------------------------------- + | SUBSTRING_INDEX(CURRENT_USER(),'@',1)| + --------------------------------------- + | user1 | + --------------------------------------- + MySQL的>SELECT SUBSTRING_INDEX(CURRENT_USER(),'@',-1);
+ ---------------------------------------- + | SUBSTRING_INDEX(CURRENT_USER(),'@', - 1)| + ---------------------------------------- + | localhost | + ---------------------------------------- +
通过MySQL客户端和服务器之间的未加密连接,有权访问网络的人可以查看所有流量并检查客户端和服务器之间发送或接收的数据。
当您必须以安全的方式通过网络移动信息时,未加密的连接是不可接受的。 要使任何类型的数据不可读,请使用加密。 加密算法必须包含安全元素,以抵御多种已知攻击,例如更改加密消息的顺序或重放数据两次。
MySQL支持使用TLS(传输层安全性)协议在客户端和服务器之间建立加密连接。 TLS有时被称为SSL(安全套接字层),但MySQL实际上并不使用SSL协议进行加密连接,因为它的加密很弱(请参见 第6.3.6节“加密连接协议和密码” )。
TLS使用加密算法来确保可以信任通过公共网络接收的数据。 它具有检测数据更改,丢失或重放的机制。 TLS还包含使用X.509标准提供身份验证的算法。
X.509可以识别互联网上的某个人。 在基本术语中,应该有一些称为 “ 证书颁发机构 ” (或CA)的 实体 ,它将电子证书分配给需要它们的任何人。 证书依赖于具有两个加密密钥(公钥和密钥)的非对称加密算法。 证书所有者可以将证书提供给另一方作为身份证明。 证书由其所有者的公钥组成。 使用该公钥加密的任何数据只能使用由证书所有者持有的相应密钥解密。
可以使用OpenSSL或wolfSSL编译MySQL以获得加密连接支持。 有关这些软件包的比较,请参见 第6.3.4节“SSL库相关功能”。 有关每个软件包支持的加密协议和密码的信息,请参见 第6.3.6节“加密连接协议和密码” 。
默认情况下,如果服务器支持加密连接,MySQL程序将尝试使用加密进行连接,如果无法建立加密连接,则会回退到未加密的连接。 有关影响加密连接使用的选项的信息,请参见 第6.3.1节“配置MySQL以使用加密连接” 和 第6.3.2节“加密连接的命令选项” 。
MySQL基于每个连接执行加密,并且对给定用户使用加密可以是可选的或强制的。
这使您可以根据各个应用程序的要求选择加密或未加密的连接。
有关如何要求用户使用加密连接的信息,请参见
第13.7.1.3节“创建用户语法”
REQUIRE
中对
CREATE
USER
语句
子句
的讨论
。
另见的描述
系统变量在
第5.1.8节,“服务器系统变量”
require_secure_transport
可以在主复制服务器和从属复制服务器之间使用加密连接。 请参见 第17.3.9节“设置复制以使用加密连接” 。
有关使用MySQL C API的加密连接的信息,请参见 第28.7.22节“C API加密连接支持” 。
也可以使用SSH连接内的加密连接到MySQL服务器主机。 有关示例,请参见 第6.3.7节“使用SSH从Windows远程连接到MySQL” 。
有几个选项可用于指示是否使用加密连接,以及指定适当的证书和密钥文件。 本节提供有关为加密连接配置服务器和客户端的一般指导:
有关建立加密连接的选项的完整列表,请参见 第6.3.2节“加密连接的命令选项” 。 有关创建任何所需证书和密钥文件的说明,请参见 第6.3.3节“创建SSL和RSA证书和密钥” 。
加密连接也可以在这些上下文中使用:
主从复制服务器之间。 请参见 第17.3.9节“设置复制以使用加密连接” 。
在组复制服务器中。 请参见 第18.5.2节“组复制安全套接字层(SSL)支持” 。
通过基于MySQL C API的客户端程序。 请参见 第28.7.22节“C API加密连接支持” 。
在服务器端,该
--ssl
选项指定服务器允许但不需要加密连接。
默认情况下启用此选项,因此无需显式指定。
要要求客户端使用加密连接进行连接,请启用
require_secure_transport
系统变量。
请参阅将
加密连接配置为必需
。
服务器端的这些选项指定服务器在允许客户端建立加密连接时使用的证书和密钥文件:
--ssl-ca
:证书颁发机构(CA)证书文件的路径名。
(
--ssl-capath
类似但指定CA证书文件目录的路径名。)
--ssl-cert
:服务器公钥证书文件的路径名。
可以将此证书发送到客户端,并根据其拥有的CA证书进行身份验证。
--ssl-key
:服务器私钥文件的路径名。
例如,要为服务器启用加密连接,请在
my.cnf
文件中
使用这些行启动它,
根据需要更改文件名:
的[mysqld] SSL的CA = ca.pem SSL证书=服务器cert.pem SSL的密钥=服务器key.pem
要另外指定客户端需要使用加密连接,请启用
require_secure_transport
系统变量:
的[mysqld] SSL的CA = ca.pem SSL证书=服务器cert.pem SSL的密钥=服务器key.pem require_secure_transport = ON
每个证书和密钥选项都以PEM格式命名文件。
如果需要创建所需的证书和密钥文件,请参见
第6.3.3节“创建SSL和RSA证书和密钥”
。
使用OpenSSL编译的MySQL服务器可以在启动时自动生成缺少的证书和密钥文件。
请参见
第6.3.3.1节“使用MySQL创建SSL和RSA证书和密钥”
。
或者,如果您有MySQL源代码分发,则可以使用其
mysql-test/std_data
目录中
的演示证书和密钥文件来测试您的设置
。
服务器执行证书和密钥文件自动发现。
如果
--ssl
启用(可能同时
--ssl-cipher
)并且
未
给出
其他
选项
以明确配置加密连接,则服务器会尝试在启动时自动启用加密连接支持:
--ssl-
xxx
如果服务器发现有效的证书和命名的密钥文件
ca.pem
,
server-cert.pem
以及
server-key.pem
在数据目录中,它能够通过客户端加密的连接支持。
(这些文件不需要自动生成;重要的是它们具有这些名称并且是有效的。)
如果服务器在数据目录中找不到有效的证书和密钥文件,它将继续执行但不支持加密连接。
如果服务器自动启用加密连接支持,它会将注释写入错误日志。 如果服务器发现CA证书是自签名的,则会向错误日志写入警告。 (如果服务器自动创建证书,则证书是自签名的,或者使用 mysql_ssl_rsa_setup 手动创建 证书 。)
MySQL还为服务器端SSL控制提供了以下选项:
--ssl-cipher
:用于连接加密的允许密码列表。
--ssl-crl
:包含证书吊销列表的文件的路径名。
(
--ssl-crlpath
类似但指定证书吊销列表文件的目录的路径名。)
的值
选项中设置相应的系统变量的(值
,
,
,等等)。
--ssl-
xxx
ssl_ca
ssl_cert
ssl_key
要明确指定服务器允许加密连接的加密协议和密码套件,请使用
tls_version
和
tls_ciphersuites
系统变量;
请参见
第6.3.6节“加密连接协议和密码”
。
例如,您可以设置
tls_version
为阻止客户端使用安全性较低的协议。
某些加密相关的系统变量可以在运行时设置:
require_secure_transport
和(从MySQL 8.0.16开始)
tls_version
和
tls_ciphersuites
。
如果更改为
SET
GLOBAL
,则新值适用于更改后建立的连接,并仅应用于服务器重新启动。
如果更改为
SET
PERSIST
,则新值也适用于后续服务器重新启动。
请参见
第13.7.5.1节“变量赋值的SET语法”
。
此外,从MySQL 8.0.16开始,服务器用于新连接的SSL上下文在运行时可重新配置。 例如,此功能可能很有用,可以避免重新启动已运行太久以至于其SSL证书已过期的MySQL服务器。
服务器根据上下文相关的系统变量在启动时具有的值创建初始SSL上下文。 它还初始化一组与上下文相关的状态变量,以指示上下文中使用的值。 下表显示了定义SSL上下文的系统变量以及指示当前活动上下文值的相应状态变量。
要在运行时重新配置SSL上下文,请使用以下过程:
设置应更改为其新值的任何与SSL上下文相关的系统变量。
执行
ALTER INSTANCE
RELOAD
TLS
。
此语句从SSL上下文相关系统变量的当前值重新配置活动SSL上下文。
它还设置与上下文相关的状态变量以反映新的活动上下文值。
该声明需要
CONNECTION_ADMIN
特权。
执行
ALTER INSTANCE
RELOAD TLS
使用新SSL上下文
后建立的新连接
。
现有连接不受影响。
如果应终止现有连接,请使用该
KILL
语句。
由于重新配置过程的工作方式,每对系统和状态变量的成员可能会暂时具有不同的值:
在
ALTER INSTANCE
RELOAD TLS
更改SSL上下文
之前对系统变量的
更改。
此时,这些更改对新连接没有影响,并且相应的上下文相关系统和状态变量可能具有不同的值。
这使您可以对系统变量进行任何更改,然后在
ALTER INSTANCE
RELOAD TLS
完成所有系统变量更改后,
以原子方式更新活动SSL上下文
。
之后
ALTER INSTANCE
RELOAD
TLS
,相应的系统和状态变量具有相同的值。
在下次更改系统变量之前,这一点仍然有效。
在某些情况下,
ALTER INSTANCE
RELOAD
TLS
本身可能足以重新配置SSL上下文,而无需更改任何系统变量。
假设名为的文件中的证书
ssl_cert
已过期。
用未映射的证书替换现有文件内容就足够了,并执行
ALTER
INSTANCE RELOAD TLS
以使新文件内容被读取并用于新连接。
默认情况下,
RELOAD TLS
如果配置值不允许创建新的SSL上下文
,则
操作将回滚并显示错误,并且无效。
先前的上下文值继续用于新连接。
如果
NO ROLLBACK ON ERROR
给出
了可选
子句并且无法创建新上下文,则不会发生回滚。
而是生成警告,并为新连接禁用SSL。
服务器端
--ssl
选项仅在服务器启动时才会影响服务器是否接受SSL连接。
它被忽略,并且对...的操作没有影响
ALTER INSTANCE
RELOAD
TLS
。
例如,您可以使用
--ssl=0
禁用SSL连接来启动服务器,然后重新配置SSL并执行
ALTER INSTANCE
RELOAD TLS
以在运行时启用SSL连接。
ALTER INSTANCE RELOAD TLS
仅更改服务器本身用于新连接的SSL上下文。
它不会影响其他已启用的服务器插件或组件(如X插件或组复制)使用的SSL上下文。
在MySQL 8.0.16之前,SSL上下文相关的系统变量不是动态的。 它们可以在服务器启动时设置,但之后无法更改。 因此,这些系统变量确定服务器用于所有新连接的SSL上下文值。
默认情况下,如果服务器支持加密连接,MySQL客户端程序将尝试建立加密连接,并通过以下
--ssl-mode
选项
进一步控制
:
如果没有
--ssl-mode
选项,客户端将尝试使用加密进行连接,如果无法建立加密连接,则会回退到未加密的连接。
这也是具有显式
--ssl-mode=PREFFERED
选项
的行为
。
使用时
--ssl-mode=REQUIRED
,客户端需要加密连接,如果无法建立,则会失败。
使用
--ssl-mode=DISABLED
,客户端使用未加密的连接。
使用
--ssl-mode=VERIFY_CA
或
--ssl-mode=VERIFY_IDENTITY
,客户端需要加密连接,并对服务器CA证书和(与
VERIFY_IDENTITY
)
证书
中的服务器主机名执行验证。
如果在
require_secure_transport
服务器端启用
了
系统变量以使服务器需要加密连接,
则尝试建立未加密的连接会失败
。
请参阅将
加密连接配置为必需
。
客户端上的以下选项标识客户端在建立到服务器的加密连接时使用的证书和密钥文件。
它们类似于在服务器端使用的选项,但
--ssl-cert
并
--ssl-key
识别客户端公钥和私钥:
--ssl-ca
:证书颁发机构(CA)证书文件的路径名。
如果使用此选项,则必须指定服务器使用的相同证书。
(
--ssl-capath
类似但指定CA证书文件目录的路径名。)
--ssl-cert
:客户端公钥证书文件的路径名。
--ssl-key
:客户端私钥文件的路径名。
为了提供相对于默认加密提供的安全性的额外安全性,客户端可以提供与服务器使用的CA证书匹配的CA证书,并启用主机名身份验证。 通过这种方式,服务器和客户端将信任放在同一个CA证书中,并且客户端会验证它所连接的主机是否为预期的主机:
要指定CA证书,请使用
--ssl-ca
(或
--ssl-capath
)并指定
--ssl-mode=VERIFY_CA
。
要启用主机名身份验证,请使用
--ssl-mode=VERIFY_IDENTITY
而不是
--ssl-mode=VERIFY_CA
。
主机名身份验证
VERIFY_IDENTITY
不适用于服务器自动创建的自签名证书
,
也不能使用
mysql_ssl_rsa_setup
手动使用
(请参见
第6.3.3.1节“使用MySQL创建SSL和RSA证书和密钥”
)。
此类自签名证书不包含服务器名称作为Common Name值。
主机名身份验证也不适用于使用通配符指定公用名的证书,因为该名称将逐字比较到服务器名称。
MySQL还为客户端SSL控制提供了以下选项:
--ssl-cipher
:用于连接加密的允许密码列表。
--ssl-crl
:包含证书吊销列表的文件的路径名。
(
--ssl-crlpath
类似但指定证书吊销列表文件的目录的路径名。)
--tls-version
,
--tls-ciphersuites
:允许的加密协议和密码组;
请参见
第6.3.6节“加密连接协议和密码”
。
根据客户端使用的MySQL帐户的加密要求,客户端可能需要指定使用加密连接到MySQL服务器的某些选项。
假设您要使用没有特殊加密要求的帐户或使用
CREATE
USER
包含该
REQUIRE SSL
子句
的
语句
创建的帐户进行连接
。
假设服务器支持加密连接,客户端可以使用加密连接,没有
--ssl-mode
选项或显式
--ssl-mode=PREFFERED
选项:
MySQL的
要么:
mysql --ssl-mode = PREFERRED
对于使用
REQUIRE SSL
子句
创建的帐户
,如果无法建立加密连接,则连接尝试将失败。
对于没有特殊加密要求的帐户,如果无法建立加密连接,则尝试将回退到未加密的连接。
如果无法获得加密连接以防止回退和失败,请按以下方式连接:
mysql --ssl-mode = REQUIRED
如果帐户具有更严格的安全要求,则必须指定其他选项以建立加密连接:
对于使用
REQUIRE X509
子句
创建的帐户
,客户端必须至少指定
--ssl-cert
和
--ssl-key
。
此外,
建议使用
--ssl-ca
(或
--ssl-capath
),以便验证服务器提供的公共证书。
例如:
mysql --ssl-ca = ca.pem \ --ssl-cert = client-cert.pem \ --ssl密钥=客户端 - key.pem
对于使用
REQUIRE
ISSUER
or
REQUIRE SUBJECT
子句
创建的帐户
,加密要求与for相同
REQUIRE X509
,但证书必须分别与帐户定义中指定的问题或主题匹配。
有关该
REQUIRE
子句的
其他信息
,请参见
第13.7.1.3节“CREATE USER语法”
。
要防止使用加密并覆盖其他
选项,请使用以下命令调用客户端程序
:
--ssl-
xxx
--ssl-mode=DISABLED
mysql --ssl-mode = DISABLED
要确定当前与服务器的连接是否使用加密,请检查
Ssl_cipher
状态变量
的会话值
。
如果值为空,则表示连接未加密。
否则,连接被加密,值表示加密密码。
例如:
MySQL的> SHOW SESSION STATUS LIKE 'Ssl_cipher';
+ --------------- + --------------------------- +
| Variable_name | 价值|
+ --------------- + --------------------------- +
| Ssl_cipher | DHE-RSA-AES128-GCM-SHA256 |
+ --------------- + --------------------------- +
对于
mysql
客户端,另一种方法是使用
STATUS
or
\s
命令并检查
SSL
行:
MySQL的> \s
...
SSL:未使用
...
要么:
MySQL的> \s
...
SSL:使用的密码是DHE-RSA-AES128-GCM-SHA256
...
对于某些MySQL部署,使用加密连接(例如,满足法规要求)不仅是可取的,而且是强制性的。 本节讨论使您能够执行此操作的配置设置。 这些控制级别可用:
您可以将服务器配置为要求客户端使用加密连接进行连接。
您可以调用单个客户端程序以要求加密连接,即使服务器允许但不需要加密。
您可以将单个MySQL帐户配置为仅在加密连接上可用。
要要求客户端使用加密连接进行连接,请启用
require_secure_transport
系统变量。
例如,将这些行放在服务器
my.cnf
文件中:
的[mysqld] require_secure_transport = ON
或者,要在运行时设置并保持该值,请使用以下语句:
SET PERSIST require_secure_transport = ON;
SET
PERSIST
设置正在运行的MySQL实例的值。
它还会保存该值,使其用于后续服务器重新启动。
请参见
第13.7.5.1节“变量赋值的SET语法”
。
与
require_secure_transport
启用,到服务器的客户端连接都需要使用某种形式的安全传输,而服务器只允许使用SSL的TCP / IP连接,或使用一个套接字文件(在Unix)连接或共享内存(在Windows上)。
服务器拒绝不安全的连接尝试,该尝试因
ER_SECURE_TRANSPORT_REQUIRED
错误
而失败
。
调用的客户端程序,使得它需要加密连接服务器是否需要加密,使用
--ssl-mode
的选项值
REQUIRED
,
VERIFY_CA
或
VERIFY_IDENTITY
。
例如:
mysql --ssl-mode = REQUIRED mysqldump --ssl-mode = VERIFY_CA mysqladmin --ssl-mode = VERIFY_IDENTITY
要将MySQL帐户配置为仅在加密连接上可用,请
REQUIRE
在
CREATE
USER
创建帐户
的
语句中
包含一个
子句
,在该子句中指定所需的加密特征。
例如,要要求加密连接并使用有效的X.509证书,请使用
REQUIRE X509
:
CREATE USER'jeffrey'@'localhost'REQUIRE X509;
有关该
REQUIRE
子句的
其他信息
,请参见
第13.7.1.3节“CREATE USER语法”
。
要修改没有加密要求的现有帐户,请使用该
ALTER
USER
语句。
本节介绍指定是使用加密连接的选项,证书和密钥文件的名称以及与加密连接支持相关的其他参数。 可以在命令行或选项文件中提供这些选项。 有关建议用法的示例以及如何检查连接是否已加密,请参见 第6.3.1节“配置MySQL以使用加密连接” 。
有关使用MySQL C API的加密连接的信息,请参见 第28.7.22节“C API加密连接支持” 。
表6.12加密连接选项摘要
格式 | 描述 | 介绍 |
---|---|---|
--skip-SSL | 不要使用加密连接 | |
--ssl | 启用加密连接 | |
--ssl-CA | 包含受信任的SSL证书颁发机构列表的文件 | |
--ssl-capath | 包含受信任的SSL证书颁发机构证书文件的目录 | |
--ssl证书 | 包含X.509证书的文件 | |
--ssl-密码 | 用于连接加密的允许密码列表 | |
--ssl-CRL | 包含证书吊销列表的文件 | |
--ssl-crlpath | 包含证书吊销列表文件的目录 | |
--ssl-FIPS模式 | 是否在客户端启用FIPS模式 | 8.0.11 |
--ssl键 | 包含X.509密钥的文件 | |
--ssl模式 | 与服务器连接的安全状态 | |
--tls-密码套件 | 允许加密连接的TLSv1.3密码套件 | 8.0.16 |
--tls版本 | 允许加密连接的协议 |
--ssl
MySQL 8.0中删除了
客户端
选项。
对于客户端程序,请
--ssl-mode
改用。
在服务器端,该
--ssl
选项指定服务器允许但不需要加密连接。
默认情况下,该选项在服务器端启用。
--ssl
其他
选项
暗示了
这些选项的描述中所示。
--ssl-
xxx
在
--ssl
以否定的形式选项表示加密应该
不
使用,并覆盖其他
选项。
将选项指定为
或同义词(
,
)。
--ssl-
xxx
--ssl=0
--skip-ssl
--disable-ssl
要加密的连接指定其他参数,至少使用
--ssl-cert
和
--ssl-key
在服务器侧和
--ssl-ca
客户端侧。
请参见
第6.3.1节“配置MySQL以使用加密连接”
。
该部分还描述了证书和密钥文件自动生成和自动发现的服务器功能。
PEM格式的证书颁发机构(CA)证书文件的路径名。
在服务器端,此选项意味着
--ssl
。
要在建立与服务器的加密连接时告诉客户端不要验证服务器证书,请同时指定
--ssl-ca
nor
--ssl-capath
。
服务器仍然根据为客户端帐户建立的任何适用要求验证客户端,并且它仍然使用
服务器端指定的
任何
--ssl-ca
或
--ssl-capath
选项值。
包含PEM格式的受信任SSL证书颁发机构(CA)证书文件的目录的路径名。
在服务器端,此选项意味着
--ssl
。
要在建立与服务器的加密连接时告诉客户端不要验证服务器证书,请同时指定
--ssl-ca
nor
--ssl-capath
。
服务器仍然根据为客户端帐户建立的任何适用要求验证客户端,并且它仍然使用
服务器端指定的
任何
--ssl-ca
或
--ssl-capath
选项值。
对此选项的支持取决于用于编译MySQL的SSL库。 请参见 第6.3.4节“SSL库相关功能” 。
PEM格式的SSL公钥证书文件的路径名。
在客户端,这是客户端公钥证书。
在服务器端,这是服务器公钥证书。
在服务器端,此选项意味着
--ssl
。
用于连接加密的允许密码列表。
如果支持列表中的密码,则加密连接将不起作用。
在服务器端,此选项意味着
--ssl
。
为了获得最大的可移植性,
cipher_list
应该是一个由冒号分隔的一个或多个密码名称的列表。
例子:
--ssl-密码= AES128-SHA --ssl-密码= DHE-RSA-AES128-GCM-SHA256:AES128-SHA
OpenSSL支持更灵活的语法来指定密码,如 https://www.openssl.org/docs/manmaster/man1/ciphers.html上 的OpenSSL文档中所述 。 wolfSSL没有,因此尝试使用扩展语法失败,因为使用wolfSSL编译的MySQL分发。
有关MySQL支持哪些加密密码的信息,请参见 第6.3.6节“加密连接协议和密码” 。
包含证书吊销的文件的路径名以PEM格式列出。
在服务器端,此选项意味着
--ssl
。
如果既未
给出
也
--ssl-crl
未
--ssl-crlpath
给出,则即使CA路径包含证书吊销列表,也不执行CRL检查。
对此选项的支持取决于用于编译MySQL的SSL库。 请参见 第6.3.4节“SSL库相关功能” 。
包含PEM格式的证书吊销列表文件的目录的路径名。
在服务器端,此选项意味着
--ssl
。
如果既未
给出
也
--ssl-crl
未
--ssl-crlpath
给出,则即使CA路径包含证书吊销列表,也不执行CRL检查。
对此选项的支持取决于用于编译MySQL的SSL库。 请参见 第6.3.4节“SSL库相关功能” 。
--ssl-fips-mode={OFF|ON|STRICT}
控制是否在客户端启用FIPS模式。
该
--ssl-fips-mode
选项与其他选项的不同之处在于
,它不用于建立加密连接,而是用于影响允许的加密操作。
请参见
第6.5节“FIPS支持”
。
--ssl-
xxx
--ssl-fips-mode
允许
这些
值:
OFF
:禁用FIPS模式。
ON
:启用FIPS模式。
STRICT
:启用
“
严格
”
FIPS模式。
如果OpenSSL的FIPS对象模块不可用时,对于唯一的允许值
--ssl-fips-mode
是
OFF
。
在这种情况下,设置
--ssl-fips-mode
为
ON
或
STRICT
导致客户端在启动时生成警告并在非FIPS模式下运行。
PEM格式的SSL私钥文件的路径名。
在客户端,这是客户端私钥。
在服务器端,这是服务器私钥。
在服务器端,此选项意味着
--ssl
。
如果密钥文件受密码短语保护,则程序会提示用户输入密码短语。 密码必须以交互方式提供; 它不能存储在文件中。 如果密码不正确,程序将继续,就好像它无法读取密钥一样。
为了更好的安全性,请使用RSA密钥大小至少为2048位的证书。
此选项仅适用于客户端程序,而不适用于服务器。 它指定与服务器的连接的安全状态。 允许使用以下选项值:
PREFERRED
:如果服务器支持加密连接,则建立加密连接;如果无法建立加密连接,则回退到未加密连接。
如果
--ssl-mode
未指定,
则为默认值
。
默认情况下禁用Unix套接字上
PREFERRED
的加密连接
,因此
不会建立加密连接。
要对Unix套接字连接强制执行加密,请使用
REQUIRED
或以上。
REQUIRED
:如果服务器支持加密连接,则建立加密连接。
如果无法建立加密连接,则连接尝试将失败。
VERIFY_CA
:Like
REQUIRED
,但另外根据配置的CA证书验证服务器证书颁发机构(CA)证书。
如果未找到有效的匹配CA证书,则连接尝试将失败。
VERIFY_IDENTITY
:喜欢
VERIFY_CA
,但另外通过检查客户端用于连接服务器的主机名与服务器发送给客户端的证书中的标识来执行主机名身份验证:
从MySQL 8.0.12开始,如果客户端使用OpenSSL 1.0.2或更高版本,则客户端会检查它用于连接的主机名是否与服务器证书中的“使用者备用名称”值或“公用名”值匹配。
否则,客户端会检查它用于连接的主机名是否与服务器证书中的Common Name值匹配。
如果不匹配,连接将失败。 对于加密连接,此选项有助于防止中间人攻击。
主机名身份验证
VERIFY_IDENTITY
不适用于服务器自动创建的自签名证书
,
也不能使用
mysql_ssl_rsa_setup
手动使用
(请参见
第6.3.3.1节“使用MySQL创建SSL和RSA证书和密钥”
)。
此类自签名证书不包含服务器名称作为Common Name值。
主机名身份验证也不适用于使用通配符指定公用名的证书,因为该名称将逐字比较到服务器名称。
DISABLED
:建立未加密的连接。
该
--ssl-mode
选项与CA证书选项交互,如下所示:
如果
--ssl-mode
没有明确设置,则使用
--ssl-ca
或
--ssl-capath
暗示
--ssl-mode=VERIFY_CA
。
对于
--ssl-mode
的值
VERIFY_CA
或
VERIFY_IDENTITY
,
--ssl-ca
或
--ssl-capath
还需要,以提供匹配由服务器使用的一个CA证书。
--ssl-mode
除了
指定CA证书选项
之外
,具有
除
VERIFY_CA
or
之外的值
的显式
选项
VERIFY_IDENTITY
以及与explicit
--ssl-ca
或
--ssl-capath
option
一起
产生警告,即不会对服务器证书进行验证。
要求MySQL帐户使用加密连接,请使用
CREATE
USER
创建带有
REQUIRE SSL
子句
的帐户
,或使用
ALTER
USER
现有帐户添加
REQUIRE SSL
子句。
除非MySQL支持加密连接并且可以建立加密连接,否则将拒绝使用该帐户的客户端的连接尝试。
该
REQUIRE
条款允许其他与加密相关的选项,这些选项可用于强制执行比更严格的安全要求
REQUIRE
SSL
。
有关其他详细信息有关哪些选项可以或必须由连接使用使用各种配置的帐户的客户来指定命令
REQUIRE
选项,见描述
REQUIRE
在
第13.7.1.3,“CREATE USER语法”
。
--tls-ciphersuites=
ciphersuite_list
对于客户端程序,指定客户端允许加密连接的TLSv1.3密码套件。 该值是一个或多个以冒号分隔的密码组名称的列表。 例如:
MySQL的--tls-密码组= “suite1
:suite2
:suite3
”
可以为此选项命名的密码套件取决于用于编译MySQL的SSL库。 有关详细信息,请参见 第6.3.6节“加密连接协议和密码” 。
MySQL 8.0.16中添加了此选项。
要指定服务器允许的密码组,请改用
tls_ciphersuites
系统变量。
对于客户端程序,指定客户端允许加密连接的协议。 该值是一个或多个以逗号分隔的协议名称的列表。 例如:
mysql --tls-version =“TLSv1.1,TLSv1.2”
可以为此选项命名的协议取决于用于编译MySQL的SSL库。 有关详细信息,请参见 第6.3.6节“加密连接协议和密码” 。
要指定服务器允许的协议,请改用
tls_version
系统变量。
以下讨论描述了如何在MySQL中创建SSL和RSA支持所需的文件。 可以使用MySQL本身提供的工具或 直接 调用 openssl 命令 来执行文件创建 。
SSL证书和密钥文件使MySQL能够使用SSL支持加密连接。 请参见 第6.3.1节“配置MySQL以使用加密连接” 。
RSA密钥文件使MySQL能够通过未加密的连接支持通过
sha256_password
或
caching_sha2_password
插件
验证的帐户的安全密码交换
。
请参见
第6.4.1.2节“SHA-256可插拔认证”
和
第6.4.1.3节“高速缓存SHA-2可插入认证”
。
MySQL提供了这些方法来创建SSL证书和密钥文件以及使用SSL支持加密连接所需的RSA密钥对文件,以及使用RSA通过未加密连接进行安全密码交换(如果缺少这些文件):
对于使用OpenSSL编译的MySQL发行版,服务器可以在启动时自动生成这些文件。
用户可以 手动 调用 mysql_ssl_rsa_setup 实用程序。
对于某些分发类型(例如RPM包), 在数据目录初始化期间会发生 mysql_ssl_rsa_setup 调用。 在这种情况下,只要 openssl 命令可用 ,就不需要使用OpenSSL编译MySQL发行 版。
服务器自动生成和 mysql_ssl_rsa_setup 有助于降低使用SSL的障碍,方便生成所需的文件。 但是,这些方法生成的证书是自签名的,可能不是很安全。 获得使用此类文件的经验后,请考虑从已注册的证书颁发机构获取证书/密钥材料。
对于使用OpenSSL编译的MySQL发行版,MySQL服务器能够在启动时自动生成缺少的SSL和RSA文件。
的
auto_generate_certs
,
sha256_password_auto_generate_rsa_keys
和
caching_sha2_password_auto_generate_rsa_keys
系统变量控制自动生成这些文件。
默认情况下启用这些变量。
它们可以在启动时启用并检查,但不能在运行时设置。
启动时,如果
auto_generate_certs
启用
了
系统变量
,则服务器会自动在数据目录中生成服务器端和客户端SSL证书和密钥文件
,不会
--ssl
指定
除
指定
之外的SSL选项
,并且数据中缺少服务器端SSL文件目录。
这些文件使用SSL启用加密的客户端连接;
请参见
第6.3.1节“配置MySQL以使用加密连接”
。
服务器使用以下名称检查数据目录中的SSL文件:
ca.pem 服务器cert.pem 服务器key.pem
如果存在任何这些文件,则服务器不会创建任何SSL文件。 否则,它会创建它们,以及一些其他文件:
ca.pem自签名CA证书 ca-key.pem CA私钥 server-cert.pem服务器证书 server-key.pem服务器私钥 client-cert.pem客户端证书 client-key.pem客户端私钥
如果服务器自动生成SSL文件,它使用的名称
ca.pem
,
server-cert.pem
以及
server-key.pem
文件来设置相应的系统变量(
ssl_ca
,
ssl_cert
,
ssl_key
)。
在启动时,如果满足所有这些条件,则服务器会自动在数据目录中生成RSA私钥/公钥对文件:
sha256_password_auto_generate_rsa_keys
或者
caching_sha2_password_auto_generate_rsa_keys
启用系统变量;
没有指定RSA选项;
数据目录中缺少RSA文件。
这些密钥对文件通过未加密的连接使用RSA进行安全密码交换,以便对由
sha256_password
or或
caching_sha2_password
plugin
进行身份验证的帐户进行安全密码交换
。
请参见
第6.4.1.2节“SHA-256可插拔认证”
和
第6.4.1.3节“高速缓存SHA-2可插拔认证”
。
服务器使用以下名称检查数据目录中的RSA文件:
private_key.pem私钥/公钥对的私有成员 public_key.pem私钥/公钥对的公共成员
如果存在任何这些文件,则服务器不会创建任何RSA文件。 否则,它会创建它们。
如果服务器自动生成RSA文件,它将使用其名称来设置相应的系统变量(
sha256_password_private_key_path
和
sha256_password_public_key_path
;
caching_sha2_password_private_key_path
和
caching_sha2_password_public_key_path
)。
MySQL发行版包括一个 mysql_ssl_rsa_setup 实用程序,可以手动调用 该 实用程序来生成SSL和RSA文件。 所有MySQL发行版都包含此实用程序(无论是使用OpenSSL还是使用wolfSSL编译),但它确实需要 openssl 命令可用。 有关使用说明,请参见 第4.4.3节“ mysql_ssl_rsa_setup - 创建SSL / RSA文件” 。
由服务器自动创建或通过调用 mysql_ssl_rsa_setup 创建的SSL和RSA文件 具有以下特征:
SSL和RSA密钥的大小为2048位。
SSL CA证书是自签名的。
使用
sha256WithRSAEncryption
签名算法
使用CA证书和密钥对SSL服务器和客户端证书进行
签名。
SSL证书使用这些公用名(CN)值以及相应的证书类型(CA,Server,Client):
ca.pem:MySQL_Server_suffix
_Auto_Generated_CA_Certificate server-cert.pm:MySQL_Server_suffix
_Auto_Generated_Server_Certificate client-cert.pm:MySQL_Server_suffix
_Auto_Generated_Client_Certificate
该
suffix
值基于MySQL版本号。
对于
mysql_ssl_rsa_setup
生成的文件
,可以使用该
--suffix
选项
显式指定后缀
。
对于服务器生成的文件,如果生成的CN值超过64个字符,
则省略
该
部分名称。
_
suffix
SSL文件具有国家/地区(C),州或省(ST),组织(O),组织单位名称(OU)和电子邮件地址的空白值。
服务器或 mysql_ssl_rsa_setup 创建的SSL文件自生成之 日起 有效期为十年。
RSA文件不会过期。
SSL文件对于每个证书/密钥对具有不同的序列号(1个用于CA,2个用于服务器,3个用于客户端)。
由服务器自动创建的文件由运行服务器的帐户拥有。
使用
mysql_ssl_rsa_setup
创建的文件
由调用该程序的用户拥有。
chown()
如果程序被调用,
则可以在支持
系统调用
的
系统
上更改
root
此
--uid
选项
,
并
指定应该拥有文件的用户。
在Unix和类Unix系统上,证书文件(即世界可读)的文件访问模式为644,密钥文件的文件访问模式为600(即只能由运行服务器的帐户访问)。
要查看SSL证书的内容(例如,要检查其有效的日期范围),请 直接 调用 openssl :
openssl x509 -text -in ca.pem openssl x509 -text -in server-cert.pem openssl x509 -text -in client-cert.pem
也可以使用以下SQL语句检查SSL证书过期信息:
MySQL的> SHOW STATUS LIKE 'Ssl_server_not%';
+ ----------------------- + ------------------------- - +
| Variable_name | 价值|
+ ----------------------- + ------------------------- - +
| Ssl_server_not_after | 4月28日14:16:39 2027 GMT |
| Ssl_server_not_before | 2017年5月1日14:16:39 GMT |
+ ----------------------- + ------------------------- - +
本节介绍如何使用 openssl 命令设置供MySQL服务器和客户端使用的SSL证书和密钥文件。 第一个示例显示了一个简化的过程,例如您可以从命令行使用。 第二个显示包含更多详细信息的脚本。 前两个示例旨在用于Unix,并且都使用 openssl 命令,它是OpenSSL的一部分。 第三个示例描述了如何在Windows上设置SSL文件。
生成SSL所需文件比使用此处描述的过程更容易:让服务器自动生成它们或使用 mysql_ssl_rsa_setup 程序。 请参见 第6.3.3.1节“使用MySQL创建SSL和RSA证书和密钥” 。
无论您使用哪种方法生成证书和密钥文件,用于服务器和客户端证书/密钥的公用名称值都必须与用于CA证书的公用名称值不同。 否则,证书和密钥文件将不适用于使用OpenSSL编译的服务器。 这种情况下的典型错误是:
ERROR 2026(HY000):SSL连接错误: 错误:00000001:LIB(0):函数(0):原因(1)
以下示例显示了一组用于创建MySQL服务器和客户端证书以及密钥文件的命令。 您需要通过 openssl 命令 响应多个提示 。 要生成测试文件,可以按Enter键以显示所有提示。 要生成供生产使用的文件,您应该提供非空的响应。
#创建干净的环境 rm -rf newcerts mkdir newcerts && cd newcerts #创建CA证书 openssl genrsa 2048> ca-key.pem openssl req -new -x509 -nodes -days 3600 \ -key ca-key.pem -out ca.pem #创建服务器证书,删除密码并签名 #server-cert.pem = public key,server-key.pem =私钥 openssl req -newkey rsa:2048 -days 3600 \ -nodes -keyout server-key.pem -out server-req.pem openssl rsa -in server-key.pem -out server-key.pem openssl x509 -req -in server-req.pem -days 3600 \ -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem #创建客户端证书,删除密码并签名 #client-cert.pem = public key,client-key.pem = private key openssl req -newkey rsa:2048 -days 3600 \ -nodes -keyout client-key.pem -out client-req.pem openssl rsa -in client-key.pem -out client-key.pem openssl x509 -req -in client-req.pem -days 3600 \ -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
生成证书后,验证它们:
openssl verify -CAfile ca.pem server-cert.pem client-cert.pem
您应该看到这样的回复:
server-cert.pem:好的 client-cert.pem:好的
要查看证书的内容(例如,要检查证书有效的日期范围),请 像这样 调用 openssl :
openssl x509 -text -in ca.pem openssl x509 -text -in server-cert.pem openssl x509 -text -in client-cert.pem
现在您有一组可以按如下方式使用的文件:
ca.pem
:将此作为
--ssl-ca
服务器和客户端
的参数
。
(如果使用CA证书,则双方的证书必须相同。)
server-cert.pem
,
server-key.pem
:使用这些作为
服务器端
--ssl-cert
和
--ssl-key
服务器端
的参数
。
client-cert.pem
,
client-key.pem
:使用这些作为
客户端
--ssl-cert
和
--ssl-key
客户端
的参数
。
有关其他使用说明,请参见 第6.3.1节“配置MySQL以使用加密连接” 。
下面是一个示例脚本,演示如何为MySQL设置SSL证书和密钥文件。 执行脚本后,使用 第6.3.1节“配置MySQL使用加密连接”中 所述的SSL连接文件 。
DIR =`pwd` / OpenSSL的 PRIV = $ DIR /私有 mkdir $ DIR $ PRIV $ DIR / newcerts cp /usr/share/ssl/openssl.cnf $ DIR 替换./demoCA $ DIR - $ DIR / openssl.cnf #创建必要的文件:$ database,$ serial和$ new_certs_dir #directory(可选) 触摸$ DIR / index.txt echo“01”> $ DIR / serial # #证书颁发机构(CA)的生成 # openssl req -new -x509 -keyout $ PRIV / cakey.pem -out $ DIR / ca.pem \ -days 3600 -config $ DIR / openssl.cnf #示例输出: #使用/home/monty/openssl/openssl.cnf中的配置 #生成1024位RSA私钥 #................ ++++++ #......... ++++++ #将新私钥写入'/home/monty/openssl/private/cakey.pem' #输入PEM密码短语: #验证密码 - 输入PEM密码短语: #----- #您将被要求输入将要提供的信息 #并入您的证书申请。 #您将要进入的是所谓的专有名称 #或DN。 #有很多字段,但你可以留空 #对于某些字段,将有一个默认值, #如果输入“。”,该字段将留空。 #----- #国名(2个字母代码)[AU]:FI #州或省名(全名)[Some-State]: #地点名称(例如,城市)[]: #组织名称(例如,公司)[Internet Widgits Pty Ltd]:MySQL AB #组织单位名称(例如,部分)[]: #Common Name(例如,你的名字)[]:MySQL admin # 电子邮件地址 []: # #创建服务器请求和密钥 # openssl req -new -keyout $ DIR / server-key.pem -out \ $ DIR / server-req.pem -days 3600 -config $ DIR / openssl.cnf #示例输出: #使用/home/monty/openssl/openssl.cnf中的配置 #生成1024位RSA私钥 #.. ++++++ #.......... ++++++ #将新私钥写入'/home/monty/openssl/server-key.pem' #输入PEM密码短语: #验证密码 - 输入PEM密码短语: #----- #您将被要求输入将要提供的信息 #并入您的证书申请。 #您将要进入的是所谓的专有名称 #或DN。 #有很多字段,但你可以留空 #对于某些字段,将有一个默认值, #如果输入“。”,该字段将留空。 #----- #国名(2个字母代码)[AU]:FI #州或省名(全名)[Some-State]: #地点名称(例如,城市)[]: #组织名称(例如,公司)[Internet Widgits Pty Ltd]:MySQL AB #组织单位名称(例如,部分)[]: #Common Name(例如,你的名字)[]:MySQL服务器 # 电子邮件地址 []: # #请输入以下'额外'属性 #与您的证书请求一起发送 #挑战密码[]: #可选的公司名称[]: # #从密钥中删除密码 # openssl rsa -in $ DIR / server-key.pem -out $ DIR / server-key.pem # #签署服务器证书 # openssl ca -cert $ DIR / ca.pem -policy policy_anything \ -out $ DIR / server-cert.pem -config $ DIR / openssl.cnf \ -infiles $ DIR / server-req.pem #示例输出: #使用/home/monty/openssl/openssl.cnf中的配置 #输入PEM密码短语: #检查请求是否与签名匹配 #签名确定 #主题专有名称如下 #countryName:PRINTABLE:'FI' #organizationName:PRINTABLE:'MySQL AB' #commonName:PRINTABLE:'MySQL admin' #证书将于格林尼治标准时间9月13日14:22:46之前获得认证 #(365天) #签署证书?[Y / N]:Y # # #1中有1个证书请求已通过认证,提交?[Y / N - ] Y #用1个新条目写出数据库 #Data Base已更新 # #创建客户端请求和密钥 # openssl req -new -keyout $ DIR / client-key.pem -out \ $ DIR / client-req.pem -days 3600 -config $ DIR / openssl.cnf #示例输出: #使用/home/monty/openssl/openssl.cnf中的配置 #生成1024位RSA私钥 #..................................... ++++++ #............................................. +++ ++ #将新私钥写入'/home/monty/openssl/client-key.pem' #输入PEM密码短语: #验证密码 - 输入PEM密码短语: #----- #您将被要求输入将要提供的信息 #并入您的证书申请。 #您将要进入的是所谓的专有名称 #或DN。 #有很多字段,但你可以留空 #对于某些字段,将有一个默认值, #如果输入“。”,该字段将留空。 #----- #国名(2个字母代码)[AU]:FI #州或省名(全名)[Some-State]: #地点名称(例如,城市)[]: #组织名称(例如,公司)[Internet Widgits Pty Ltd]:MySQL AB #组织单位名称(例如,部分)[]: #Common Name(例如,你的名字)[]:MySQL用户 # 电子邮件地址 []: # #请输入以下'额外'属性 #与您的证书请求一起发送 #挑战密码[]: #可选的公司名称[]: # #从密钥中删除密码 # openssl rsa -in $ DIR / client-key.pem -out $ DIR / client-key.pem # #签署客户证书 # openssl ca -cert $ DIR / ca.pem -policy policy_anything \ -out $ DIR / client-cert.pem -config $ DIR / openssl.cnf \ -infiles $ DIR / client-req.pem #示例输出: #使用/home/monty/openssl/openssl.cnf中的配置 #输入PEM密码短语: #检查请求是否与签名匹配 #签名确定 #主题专有名称如下 #countryName:PRINTABLE:'FI' #organizationName:PRINTABLE:'MySQL AB' #commonName:PRINTABLE:'MySQL用户' #证书将于格林尼治标准时间9月13日16:45:17之前通过认证 #(365天) #签署证书?[Y / N]:Y # # #1中有1个证书请求已通过认证,提交?[Y / N - ] Y #用1个新条目写出数据库 #Data Base已更新 # #创建一个可用于测试证书的my.cnf文件 # 猫<< EOF> $ DIR / my.cnf [客户] SSL-CA = $ DIR / ca.pem SSL证书= $ DIR /客户cert.pem SSL密钥= $ DIR /客户key.pem 的[mysqld] SSL-CA = $ DIR / ca.pem SSL证书= $ DIR /服务器cert.pem SSL密钥= $ DIR /服务器key.pem EOF
如果您的系统上未安装OpenSSL for Windows,请下载它。 可在此处查看可用包的概述:
http://www.slproweb.com/products/Win32OpenSSL.html
选择Win32 OpenSSL Light或Win64 OpenSSL Light程序包,具体取决于您的体系结构(32位或64位)。
默认安装位置为
C:\OpenSSL-Win32
或
C:\OpenSSL-Win64
,具体取决于您下载的软件包。
以下说明假定默认位置为
C:\OpenSSL-Win32
。
如果您使用的是64位软件包,请根据需要进行修改。
如果在安装程序指示期间出现消息
'...critical component is missing: Microsoft Visual
C++ 2008 Redistributables'
,请取消设置并下载以下软件包之一,这取决于您的体系结构(32位或64位):
Visual C ++ 2008 Redistributables(x86),可从以下位置获得:
http://www.microsoft.com/downloads/details.aspx?familyid=9B2DA534-3E03-4391-8A4D-074B9F2BC1BF
Visual C ++ 2008 Redistributables(x64),可从以下位置获得:
http://www.microsoft.com/downloads/details.aspx?familyid=bd2a6171-e2d6-4230-b809-9a8d7548c1b6
安装附加软件包后,重新启动OpenSSL安装过程。
在安装过程中,保留默认值
C:\OpenSSL-Win32
作为安装路径,并保留
'Copy OpenSSL DLL files
to the Windows system directory'
选中
的默认选项
。
安装完成后,添加
C:\OpenSSL-Win32\bin
到服务器的Windows系统路径变量中(根据您的Windows版本,以下路径设置说明可能略有不同):
在Windows桌面上,右键单击“ 我的电脑” 图标,然后选择“ 。
从出现的“
菜单中 选择“ 选项卡 ,然后单击“ 按钮。在“ 系统变量”下 ,选择“ ,然后单击“ 按钮。 应出现 “ 对话框。
添加
';C:\OpenSSL-Win32\bin'
到最后(注意分号)。
按OK 3次。
通过打开新的命令控制台(“ 开始”>“运行”>“cmd.exe” )并验证OpenSSL是否可用,检查OpenSSL是否 已正确集成到Path变量中 :
Microsoft Windows [版本...] 版权所有(c)2006 Microsoft Corporation。版权所有。 C:\ Windows \ System32下>cd \
C:\>openssl
OpenSSL>exit
<<<如果看到OpenSSL提示,则安装成功。 C:\>
安装OpenSSL后,使用类似于示例1(本节前面所示)的说明,并进行以下更改:
更改以下Unix命令:
#创建干净的环境 rm -rf newcerts mkdir newcerts && cd newcerts
在Windows上,请改用以下命令:
#创建干净的环境 md c:\ newcerts cd c:\ newcerts
当一个
'\'
字符显示在命令行的末尾时,
'\'
必须删除
该
字符并在一行中输入所有命令行。
生成证书和密钥文件后,要将它们用于SSL连接,请参见 第6.3.1节“配置MySQL以使用加密连接” 。
本节介绍如何使用
openssl
命令设置RSA密钥文件,这些文件使MySQL能够通过未加密的连接支持通过
sha256_password
和
caching_sha2_password
插件
验证的帐户的安全密码交换
。
生成RSA所需文件比使用此处描述的过程更容易:让服务器自动生成它们或使用 mysql_ssl_rsa_setup 程序。 请参见 第6.3.3.1节“使用MySQL创建SSL和RSA证书和密钥” 。
要创建RSA私钥和公钥对文件,请在登录用于运行MySQL服务器的系统帐户时运行这些命令,以便该文件归该帐户所有:
openssl genrsa -out private_key.pem 2048 openssl rsa -in private_key.pem -poutout -out public_key.pem
这些命令创建2,048位密钥。 要创建更强的键,请使用更大的值。
然后设置密钥文件的访问模式。 私钥只能由服务器读取,而公钥可以自由分发给客户端用户:
chmod 400 private_key.pem chmod 444 public_key.pem
可以使用OpenSSL或wolfSSL编译MySQL,这两者都支持基于OpenSSL API的加密连接:
MySQL Enterprise Edition二进制发行版使用OpenSSL编译。 在MySQL Enterprise Edition中使用wolfSSL是不可能的。
MySQL Community Edition二进制发行版使用OpenSSL编译。
可以使用OpenSSL或wolfSSL编译MySQL Community Edition源代码分发(请参见 第6.3.5节“使用支持加密连接构建MySQL” )。
OpenSSL和wolfSSL提供相同的基本功能,但使用OpenSSL编译的MySQL发行版具有其他功能:
OpenSSL支持更灵活的语法,用于为
--ssl-cipher
选项
指定密码
,并支持更广泛的加密密码供您选择。
请参见
第6.3.2节“加密连接的命令选项”
和
第6.3.6节“加密连接协议和密码”
。
OpenSSL支持
--ssl-capath
。
使用wolfSSL编译的MySQL发行版不会因为wolfSSL没有查看任何目录而不遵循链式证书树。
wolfSSL要求CA证书树的所有组件都包含在单个CA证书树中,并且文件中的每个证书都具有唯一的SubjectName值。
要解决此限制,请将包含证书树的各个证书文件连接到一个新文件中,并将该文件指定为该
--ssl-ca
选项
的值
。
OpenSSL支持
--ssl-crl
和
--ssl-crlpath
选项。
使用wolfSSL编译的发行版不会因为撤销列表不能与wolfSSL一起使用。
(wolfSSL接受这些选项,但默默地忽略它们。)
OpenSSL 1.1.1和更高版本支持TLSv1.3协议。
使用
sha256_password
插件进行
身份验证的帐户
可以使用RSA密钥文件通过未加密的连接进行安全密码交换。
请参见
第6.4.1.2节“SHA-256可插拔认证”
。
(使用
caching_sha2_password
插件进行
身份验证的帐户
可以使用基于RSA密钥对的密码交换,无论MySQL是使用OpenSSL还是使用wolfSSL编译。请参见
第6.4.1.3节“缓存SHA-2可插入身份验证”
。)
服务器可以在启动时自动生成缺少的SSL和RSA证书和密钥文件。 请参见 第6.3.3.1节“使用MySQL创建SSL和RSA证书和密钥” 。
OpenSSL支持更多的加密模式
AES_ENCRYPT()
和
AES_DECRYPT()
功能。
请参见
第12.13节“加密和压缩函数”
只有在使用OpenSSL编译MySQL时,才会出现某些与OpenSSL相关的系统和状态变量:
要确定是否使用OpenSSL编译服务器,请测试是否存在任何这些变量。 例如,如果使用OpenSSL,则此语句返回一行;如果使用wolfSSL,则返回空结果:
显示状态如'Rsa_public_key';
要在MySQL服务器和客户端程序之间使用加密连接,您的系统必须支持OpenSSL或wolfSSL:
MySQL Enterprise Edition二进制发行版使用OpenSSL编译。 在MySQL Enterprise Edition中使用wolfSSL是不可能的。
MySQL Community Edition二进制发行版使用OpenSSL编译。
可以使用OpenSSL或wolfSSL编译MySQL Community Edition源代码分发。
如果从源代码分发编译MySQL, CMake会将 分发配置为默认使用OpenSSL。
要使用OpenSSL进行编译,请使用以下过程:
确保系统上已安装OpenSSL 1.0.1或更高版本。 如果安装的OpenSSL版本低于1.0.1,则 CMake 会在MySQL配置时生成错误。 如果有必要获得OpenSSL,请访问 http://www.openssl.org 。
该
CMake的
选项确定为编译MySQL使用的SSL库(参见
第2.9.4“MySQL的源代码,配置选项”
)。
默认值为
,使用OpenSSL。
要明确这一点,请在
CMake
命令行
上指定该选项
。
例如:
WITH_SSL
-DWITH_SSL=system
cmake。-DWITH_SSL =系统
该命令配置分发以使用已安装的OpenSSL库。 或者,要显式指定OpenSSL安装的路径名,请使用以下语法。 如果您安装了多个版本的OpenSSL,这可能很有用,以防止 CMake 选择错误的版本:
cmake。-DWITH_SSL =path_name
编译并安装发行版。
要使用wolfSSL进行编译,请下载wolfSSL发行版并应用一个小补丁。
有关说明,请参阅该
extra/README-wolfssl.txt
文件。
要检查
mysqld
服务器
是否
支持加密连接,请检查
have_ssl
系统变量
的值
:
MySQL的> SHOW VARIABLES LIKE 'have_ssl';
+ --------------- + ------- +
| Variable_name | 价值|
+ --------------- + ------- +
| have_ssl | 是的|
+ --------------- + ------- +
如果值为
YES
,则服务器支持加密连接。
如果值为
DISABLED
,则服务器能够支持加密连接,但未使用适当的
选项
启动
以启用加密连接;
请参见
第6.3.1节“配置MySQL以使用加密连接”
。
--ssl-
xxx
要确定服务器是使用OpenSSL还是使用wolfSSL编译,请检查是否存在仅适用于OpenSSL的系统或状态变量。 请参见 第6.3.4节“SSL库相关功能”
要确定加密连接使用哪种加密协议和密码,请使用以下语句检查
Ssl_version
和
Ssl_cipher
状态变量的值:
MySQL的>SHOW SESSION STATUS LIKE 'Ssl_version';
+ --------------- + ------- + | Variable_name | 价值| + --------------- + ------- + | Ssl_version | TLSv1 | + --------------- + ------- + MySQL的>SHOW SESSION STATUS LIKE 'Ssl_cipher';
+ --------------- + --------------------------- + | Variable_name | 价值| + --------------- + --------------------------- + | Ssl_cipher | DHE-RSA-AES128-GCM-SHA256 | + --------------- + --------------------------- +
如果连接未加密,则两个变量都具有空值。
MySQL支持使用TLSv1,TLSv1.1,TLSv1.2和TLSv1.3协议的加密连接。
从MySQL 8.0.16开始支持TLSv1.3协议,但需要使用OpenSSL 1.1.1或更高版本编译MySQL。 如果SSL库不支持TLSv1.3,则以下讨论中的MySQL和TLSv1.3相关部分也不适用。
目前,Group Replication不支持TLSv1.3。
tls_version
系统变量
的值
确定服务器允许加密连接的协议。
该
tls_version
值适用于使用常规主/从复制的客户端和从服务器的连接。
变量值是此列表中一个或多个逗号分隔的协议名称的列表(不区分大小写):TLSv1,TLSv1.1,TLSv1.2和(如果可用)TLSV1.3。
默认情况下,此变量列出用于编译MySQL的SSL库支持的所有协议。
要确定
tls_version
运行时
的值
,请使用以下语句:
MySQL的> SHOW GLOBAL VARIABLES LIKE 'tls_version';
+ --------------- + ----------------------- +
| Variable_name | 价值|
+ --------------- + ----------------------- +
| tls_version | TLSv1,TLSv1.1,TLSv1.2 |
+ --------------- + ----------------------- +
要更改其值
tls_version
,请在服务器启动时设置它。
例如,要允许使用TLSv1.1或TLSv1.2协议的连接,但禁止使用安全性较低的TLSv1协议的连接,请在服务器
my.cnf
文件中
使用以下行
:
的[mysqld] tls_version = TLSv1.1,TLSv1.2工作
为了更加严格,只允许TLSv1.2连接,设置
tls_version
如下:
的[mysqld] tls_version = TLSv1.2工作
从MySQL 8.0.16开始,
tls_version
也可以在运行时更改。
请参阅
加密连接的服务器端运行时配置
。
对于客户端程序,该
--tls-version
选项指定客户端允许与服务器连接的TLS协议。
选项值的格式与
tls_version
系统变量
的格式相同
。
对于常规复制,该
语句
的
MASTER_TLS_VERSION
选项
CHANGE MASTER TO
指定从服务器允许与主服务器连接的TLS协议。
选项值的格式与
tls_version
系统变量
的格式相同
。
请参见
第17.3.9节“设置复制以使用加密连接”
。
可以指定的协议
MASTER_TLS_VERSION
仅依赖于SSL库。
此选项独立
tls_version
于从服务器上配置
的
值
,不受其影响
。
例如,可以将充当复制从站的服务器配置为
tls_version
设置为TLSv1.3,以仅允许使用TLSv1.3的传入连接,但也使用
MASTER_TLS_VERSION
set to TLSv1.2
配置
为仅作为从站连接到允许的主站TLSv1.2工作。
默认情况下,MySQL会尝试使用可用的最高TLS协议版本,具体取决于用于编译服务器和客户端的SSL库,使用的密钥大小,以及服务器或客户端是否限制使用某些协议(例如,的意思是
tls_version
:)
--tls-version
:
如果TLSv1.3可用,则尽可能使用它。 如果没有,MySQL继续通过可用协议列表,如果可能的话使用TLSv1.2,依此类推。
TLSv1.2不适用于密钥大小为512位或更小的所有密码。
要将此协议与此类密钥一起使用,请使用
--ssl-cipher
以明确指定密码名称:
AES128-SHA AES128-SHA256 AES256-SHA AES256-SHA256 CAMELLIA128-SHA CAMELLIA256-SHA DES-CBC3-SHA DHE-RSA-AES256-SHA RC4,MD5 RC4-SHA SEED-SHA
为了更好的安全性,请使用RSA密钥大小至少为2048位的证书。
如果服务器和客户端协议功能没有共同的协议,则服务器终止连接请求。 例子:
如果配置了服务器,则
tls_version=TLSv1.1,TLSv1.2
调用的客户端的连接尝试失败
--tls-version=TLSv1
,对于不支持该
--tls-version
选项的
旧客户端,
并且仅隐式支持TLSv1。
同样,对于配置了的复制从站的连接尝试失败
MASTER_TLS_VERSION =
'TLSv1'
,对于不支持该
MASTER_TLS_VERSION
选项且仅隐式支持TLSv1的
旧从站
,连接尝试失败
。
OpenSSL 1.1.1及更高版本支持以下密码套件,前三个密码套件默认启用:
TLS_AES_128_GCM_SHA256 TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_CCM_SHA256 TLS_AES_128_CCM_8_SHA256
要明确配置允许的TLSv1.3密码套件:
在服务器端,使用
tls_ciphersuites
系统变量。
在客户端,使用该
--tls-ciphersuites
选项。
在每种情况下,配置值是一个或多个冒号分隔的密码组名称的列表。
MySQL允许指定要支持的协议列表。
此列表直接传递到底层SSL库,最终由该库提供从提供的列表中实际启用的协议。
SSL_CTX_new()
有关SSL库如何处理此问题的信息,
请参阅MySQL源代码和OpenSSL
文档。
要确定给定服务器支持的密码,请使用以下语句检查
Ssl_cipher_list
状态变量
的值
:
显示会话状态,如'Ssl_cipher_list';
的
Ssl_cipher_list
状态变量列出了可能的SSL密码(空非SSL连接)。
如果MySQL支持TLSv1.3,则该值包括可能的TLSv1.3密码套件。
MySQL传递给SSL库的密码顺序非常重要。 列表中首先提到了更安全的密码,并选择了提供的证书支持的第一个密码。
MySQL将此密码列表传递给SSL库:
ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES256-SHA384 DHE-RSA-AES128-GCM-SHA256 DHE-DSS-AES128-GCM-SHA256 DHE-RSA-AES128-SHA256 DHE-DSS-AES128-SHA256 DHE-DSS-AES256-GCM-SHA384 DHE-RSA-AES256-SHA256 DHE-DSS-AES256-SHA256 ECDHE-RSA-AES128-SHA ECDHE-ECDSA-AES128-SHA ECDHE-RSA-AES256-SHA ECDHE-ECDSA-AES256-SHA DHE-DSS-AES128-SHA DHE-RSA-AES128-SHA TLS_DHE_DSS_WITH_AES_256_CBC_SHA DHE-RSA-AES256-SHA AES128-GCM-SHA256 DH-DSS-AES128-GCM-SHA256 ECDH-ECDSA-AES128-GCM-SHA256 AES256-GCM-SHA384 DH-DSS-AES256-GCM-SHA384 ECDH-ECDSA-AES256-GCM-SHA384 AES128-SHA256 DH-DSS-AES128-SHA256 ECDH-ECDSA-AES128-SHA256 AES256-SHA256 DH-DSS-AES256-SHA256 ECDH-ECDSA-AES256-SHA384 AES128-SHA DH-DSS-AES128-SHA ECDH-ECDSA-AES128-SHA AES256-SHA DH-DSS-AES256-SHA ECDH-ECDSA-AES256-SHA DHE-RSA-AES256-GCM-SHA384 DH-RSA-AES128-GCM-SHA256 ECDH-RSA-AES128-GCM-SHA256 DH-RSA-AES256-GCM-SHA384 ECDH-RSA-AES256-GCM-SHA384 DH-RSA-AES128-SHA256 ECDH-RSA-AES128-SHA256 DH-RSA-AES256-SHA256 ECDH-RSA-AES256-SHA384 ECDHE-RSA-AES128-SHA ECDHE-ECDSA-AES128-SHA ECDHE-RSA-AES256-SHA ECDHE-ECDSA-AES256-SHA DHE-DSS-AES128-SHA DHE-RSA-AES128-SHA TLS_DHE_DSS_WITH_AES_256_CBC_SHA DHE-RSA-AES256-SHA AES128-SHA DH-DSS-AES128-SHA ECDH-ECDSA-AES128-SHA AES256-SHA DH-DSS-AES256-SHA ECDH-ECDSA-AES256-SHA DH-RSA-AES128-SHA ECDH-RSA-AES128-SHA DH-RSA-AES256-SHA ECDH-RSA-AES256-SHA DES-CBC3-SHA
这些密码限制到位:
以下密码永久受限:
!DHE-DSS-DES-CBC3-SHA !DHE-RSA-DES-CBC3-SHA !ECDH-RSA-DES-CBC3-SHA !ECDH-ECDSA-DES-CBC3-SHA !ECDHE-RSA-DES-CBC3-SHA !ECDHE-ECDSA-DES-CBC3-SHA
以下类别的密码是永久限制的:
!A零位 !ENULL !出口 !低 !MD5 !DES !RC2 !RC4 !PSK !的SSLv3
如果使用使用任何前述受限密码或密码类别的兼容证书启动服务器,则服务器启动时禁用加密连接。
本节介绍如何使用SSH获取与远程MySQL服务器的加密连接。
该信息由David Carlson提供
。
<dcarlson@mplcomm.com>
在Windows计算机上安装SSH客户端。 有关SSH客户端的比较,请参阅 http://en.wikipedia.org/wiki/Comparison_of_SSH_clients 。
启动Windows SSH客户端。
设置
。
设置
为登录您的服务器。
此
值可能与您的MySQL帐户的用户名不同。
Host_Name =
yourmysqlserver_URL_or_IP
userid=
your_userid
userid
设置端口转发。
要么是遥控前进(设置
local_port: 3306
,
,
)或本地转发(设置
,
,
)。
remote_host:
yourmysqlservername_or_ip
remote_port: 3306
port: 3306
host:
localhost
remote port: 3306
保存所有内容,否则您将不得不在下次重做它。
使用刚刚创建的SSH会话登录服务器。
在Windows计算机上,启动一些ODBC应用程序(例如Access)。
在Windows中创建一个新文件,并使用ODBC驱动程序以与通常相同的方式链接到MySQL,除了输入
localhost
MySQL主机服务器,不是
yourmysqlservername
。
此时,您应该与MySQL建立ODBC连接,使用SSH加密。
MySQL包含几个实现安全功能的组件和插件:
用于验证客户端连接到MySQL服务器的尝试的插件。 插件可用于多种身份验证协议。 有关身份验证过程的一般讨论,请参见 第6.2.17节“可插入身份验证” 。 有关特定身份验证插件的特性,请参见 第6.4.1节“身份验证插件” 。
密码验证组件,用于实施密码强度策略和评估潜在密码的强度。 请参见 第6.4.3节“密码验证组件” 。
密钥环插件,为敏感信息提供安全存储。 请参见 第6.4.4节“MySQL密钥环” 。
(仅限MySQL企业版)使用服务器插件实现的MySQL Enterprise Audit使用开放的MySQL Audit API来启用基于策略的标准监视以及在特定MySQL服务器上执行的连接和查询活动的日志记录。 MySQL Enterprise Audit旨在满足Oracle审计规范,为受内部和外部监管准则管理的应用程序提供开箱即用,易于使用的审计和合规性解决方案。 请参见 第6.4.5节“MySQL Enterprise Audit” 。
用户定义的函数使应用程序可以将自己的消息事件添加到审计日志中。 请参见 第6.4.6节“审计消息组件” 。
(仅限MySQL企业版)MySQL企业防火墙,一种应用程序级防火墙,允许数据库管理员根据与已接受语句模式的白名单进行匹配来允许或拒绝SQL语句执行。 这有助于强化MySQL服务器免受SQL注入等攻击或尝试通过在合法查询工作负载特征之外使用应用程序来利用应用程序。 请参见 第6.4.7节“MySQL Enterprise Firewall” 。
(仅限MySQL企业版)MySQL企业数据屏蔽和去标识,作为包含插件和一组用户定义函数的插件库实现。 数据屏蔽通过用替换替换实际值来隐藏敏感信息。 MySQL企业数据屏蔽和去标识功能可以使用多种方法屏蔽现有数据,例如模糊处理(删除识别特征),格式化随机数据的生成以及数据替换或替换。 请参见 第6.4.8节“MySQL企业数据屏蔽和取消标识” 。
以下部分描述了MySQL中可用的可插入身份验证方法以及实现这些方法的插件。 有关身份验证过程的一般讨论,请参见 第6.2.17节“可插入身份验证” 。
默认插件由
default_authentication_plugin
系统变量
的值指示
。
MySQL包含一个
mysql_native_password
实现本机身份验证
的
插件;
也就是说,在引入可插入身份验证之前,基于密码哈希方法的身份验证使用。
下表显示了服务器端和客户端上的插件名称。
表6.13本机密码验证的插件和库名称
插件或文件 | 插件或文件名 |
---|---|
服务器端插件 | mysql_native_password |
客户端插件 | mysql_native_password |
库文件 | 无(插件内置) |
以下部分提供特定于本机可插入身份验证的安装和使用信息:
有关MySQL中可插入身份验证的一般信息,请参见 第6.2.17节“可插入身份验证” 。
该
mysql_native_password
插件存在于服务器和客户端表单中:
服务器端插件内置于服务器中,无需显式加载,也无法通过卸载来禁用。
客户端插件内置于
libmysqlclient
客户端库中,可用于任何链接的程序
libmysqlclient
。
MySQL客户端程序
mysql_native_password
默认
使用
。
该
--default-auth
选项可用作关于程序可以使用哪个客户端插件的提示:
外壳> mysql --default-auth=mysql_native_password ...
MySQL提供了两个身份验证插件,可以为用户帐户密码实现SHA-256哈希:
sha256_password
:实现基本的SHA-256身份验证。
caching_sha2_password
:实现SHA-256身份验证(如
sha256_password
),但在服务器端使用缓存以获得更好的性能,并具有更广泛的适用性的附加功能。
本节介绍原始非缓存SHA-2身份验证插件。 有关缓存插件的信息,请参见 第6.4.1.3节“缓存SHA-2可插入身份验证” 。
在MySQL 8.0中,
caching_sha2_password
是默认的身份验证插件而不是
mysql_native_password
。
有关此更改对服务器操作的影响以及服务器与客户端和连接器的兼容性的信息,请参阅
caching_sha2_password作为首选身份验证插件
。
因为它
caching_sha2_password
是MySQL 8.0中的默认身份验证插件并提供了
sha256_password
身份验证插件
功能的超集
,
sha256_password
所以不推荐使用,并且将在未来的MySQL版本中删除。
sha256_password
应该迁移使用
身份验证的MySQL帐户
以使用
caching_sha2_password
。
要使用通过
sha256_password
插件进行
身份验证的帐户连接到服务器
,您必须使用TLS连接或支持使用RSA密钥对进行密码交换的未加密连接,如本节后面所述。
无论哪种方式,
sha256_password
插件都使用MySQL的加密功能。
请参见
第6.3节“使用加密连接”
。
在名称中
sha256_password
,
“
sha256
”
指的是插件用于加密的256位摘要长度。
在名称中
caching_sha2_password
,
“
sha2
”
更一般地指SHA-2类加密算法,其中256位加密是一个实例。
后一个名称选择为将来扩展可能的摘要长度留下了空间,而无需更改插件名称。
下表显示了服务器端和客户端上的插件名称。
以下部分提供特定于SHA-256可插入身份验证的安装和使用信息:
有关MySQL中可插入身份验证的一般信息,请参见 第6.2.17节“可插入身份验证” 。
该
sha256_password
插件存在于服务器和客户端表单中:
服务器端插件内置于服务器中,无需显式加载,也无法通过卸载来禁用。
客户端插件内置于
libmysqlclient
客户端库中,可用于任何链接的程序
libmysqlclient
。
要设置使用
sha256_password
插件进行SHA-256密码哈希
的帐户,请使用
以下语句,其中
password
包含所需的帐户密码:
创建用户'sha256user'@'localhost'
用sha256_password BY' password
' 识别;
服务器将
sha256_password
插件
分配给
帐户并使用它来使用SHA-256加密密码,并将这些值存储
在
系统表
的
plugin
和
authentication_string
列中
mysql.user
。
前面的说明不假定这
sha256_password
是默认的身份验证插件。
如果
sha256_password
是默认的身份验证插件,
CREATE
USER
则可以使用
更简单的
语法。
要在默认身份验证插件设置为的情况下启动服务器
sha256_password
,请将这些行放在服务器选项文件中:
的[mysqld] default_authentication_plugin = sha256_password
这会导致
sha256_password
默认情况下为新帐户使用插件。
因此,可以创建帐户并设置其密码,而无需明确命名插件:
创建用户'sha256user'@'localhost'IDENTIFIED BY' password
';
设置的另一个结果
default_authentication_plugin
来
sha256_password
的是,使用一些其他的插件创建帐户,您必须指定插件明确。
例如,要使用该
mysql_native_password
插件,请使用以下语句:
创建用户'nativeuser'@'localhost'
使用mysql_native_password BY' password
' 识别;
sha256_password
通过安全传输支持连接。
sha256_password
如果满足以下条件,还支持使用RSA通过未加密的连接进行加密密码交换:
MySQL是使用OpenSSL编译的。
可以使用OpenSSL或yaSSL编译MySQL(请参见
第6.3.4节“SSL库依赖功能”
),并
sha256_password
使用使用任一软件包编译的分发版,但RSA支持需要OpenSSL。
您要连接的MySQL服务器配置为支持RSA(使用本节后面给出的RSA配置过程)。
RSA支持具有以下特征:
在服务器端,两个系统变量命名RSA私钥和公钥对文件:
sha256_password_private_key_path
和
sha256_password_public_key_path
。
如果要使用的密钥文件的名称与系统变量缺省值不同,则数据库管理员必须在服务器启动时设置这些变量。
服务器使用
sha256_password_auto_generate_rsa_keys
系统变量来确定是否自动生成RSA密钥对文件。
请参见
第6.3.3节“创建SSL和RSA证书和密钥”
。
该
Rsa_public_key
状态变量显示由使用的RSA公钥值
sha256_password
认证插件。
拥有RSA公钥的客户端可以在连接过程中与服务器执行基于RSA密钥对的密码交换,如稍后所述。
对于通过身份验证的帐户
sha256_password
和基于RSA公钥对的密码交换的连接,服务器会根据需要将RSA公钥发送到客户端。
但是,如果客户端主机上有公钥的副本,则客户端可以使用它来保存客户端/服务器协议中的往返:
对于这些命令行客户端,使用
--server-public-key-path
选项指定RSA公钥文件:
mysql
,
mysqladmin
,
mysqlbinlog
,
mysqlcheck
,
mysqldump
,
mysqlimport
,
mysqlpump
,
mysqlshow
,
mysqlslap
,
mysqltest
,
mysql_upgrade
。
对于使用C API的程序,
mysql_options()
通过传递
MYSQL_SERVER_PUBLIC_KEY
选项和文件名来
调用
以指定RSA公钥
文件。
对于复制从属服务器,请使用
CHANGE MASTER TO
带有该
MASTER_PUBLIC_KEY_PATH
选项
的
语句
来指定RSA公用密钥文件。
对于组复制,
group_replication_recovery_get_public_key
系统变量用于相同的目的。
对于使用该
sha256_password
插件的
客户端
,密码在连接到服务器时绝不会以明文形式公开。
密码传输的方式取决于是使用安全连接还是RSA加密:
如果连接是安全的,则不需要RSA密钥对,也不使用。 这适用于使用TLS的加密连接。 密码以明文形式发送,但由于连接安全,因此无法窥探密码。
如果连接不安全,并且RSA密钥对可用,则连接保持未加密状态。 这适用于没有TLS的未加密连接。 RSA仅用于客户端和服务器之间的密码交换,以防止密码窥探。 当服务器收到加密密码时,它会对其进行解密。 加密中使用加扰来防止重复攻击。
如果未使用安全连接且RSA加密不可用,则连接尝试将失败,因为密码无法在未显示为明文的情况下发送。
如前所述,只有在使用OpenSSL编译MySQL时,RSA密码加密才可用。 使用wolfSSL编译的MySQL发行版的含义是,要使用SHA-256密码,客户端 必须 使用加密连接来访问服务器。 请参见 第6.3.1节“配置MySQL以使用加密连接” 。
要使用RSA密码加密
sha256_password
,必须使用OpenSSL编译客户端和服务器,而不仅仅是其中之一。
假设MySQL已使用OpenSSL编译,请使用以下过程在客户端连接过程中使用RSA密钥对进行密码交换:
使用 第6.3.3节“创建SSL和RSA证书和密钥”中 的说明创建RSA专用和公用密钥对文件 。
如果私钥和公钥文件都位于数据目录中,名为
private_key.pem
和
public_key.pem
(的默认值
sha256_password_private_key_path
和
sha256_password_public_key_path
系统变量),服务器在启动时自动使用它们。
否则,要明确命名密钥文件,请将系统变量设置为服务器选项文件中的密钥文件名。 如果文件位于服务器数据目录中,则无需指定其完整路径名:
的[mysqld] sha256_password_private_key_path = myprivkey.pem sha256_password_public_key_path = mypubkey.pem
如果密钥文件不在数据目录中,或者在系统变量值中显示其位置,请使用完整路径名:
的[mysqld] sha256_password_private_key_path =的/ usr /本地/ MySQL的/ myprivkey.pem sha256_password_public_key_path =的/ usr /本地/ MySQL的/ mypubkey.pem
重新启动服务器,然后连接到它并检查
Rsa_public_key
状态变量值。
该值将与此处显示的值不同,但应该是非空的:
MySQL的> SHOW STATUS LIKE 'Rsa_public_key'\G
*************************** 1。排******************** *******
Variable_name:Rsa_public_key
价值:-----开始公钥-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO9nRUDd + KvSZgY7cNBZMNpwX6
MvE1PbJFXO7u18nJ9lwc99Du / E7lw6CVXw7VKrXPeHbVQUzGyUNkf45Nz / ckaaJa
aLgJOBCIDmNVnyU54OT / 1lcs2xiyfaDMe8fCJ64ZwTnKbY2gkt1IMjUAB5Ogd5kJ
g8aV7EtKwyhHb0c30QIDAQAB
----- END PUBLIC KEY -----
如果值为空,则服务器发现密钥文件存在问题。 检查错误日志以获取诊断信息。
使用RSA密钥文件配置服务器后,使用该
sha256_password
插件进行
身份验证的帐户可以
选择使用这些密钥文件连接到服务器。
如前所述,此类帐户可以使用安全连接(在这种情况下不使用RSA)或使用RSA执行密码交换的未加密连接。
假设使用了未加密的连接。
例如:
shell>mysql --ssl-mode=DISABLED -u sha256user -p
输入密码:password
对于此连接尝试
sha256user
,服务器确定该
sha256_password
是适当的身份验证插件并调用它(因为那是
CREATE
USER
时间
指定的插件
)。
该插件发现连接未加密,因此需要使用RSA加密传输密码。
在这种情况下,插件将RSA公钥发送给客户端,客户端使用它来加密密码并将结果返回给服务器。
该插件使用服务器端的RSA私钥来解密密码,并根据密码是否正确接受或拒绝连接。
服务器根据需要将RSA公钥发送给客户端。
但是,如果客户端具有包含服务器所需的RSA公钥的本地副本的文件,则它可以使用以下
--server-public-key-path
选项
指定该文件
:
shell> 输入密码:mysql --ssl-mode=DISABLED -u sha256user -p --server-public-key-path=
file_name
password
--server-public-key-path
选项
命名的文件中的公钥值
应与
sha256_password_public_key_path
系统变量
指定的服务器端文件中的键值相同
。
如果密钥文件包含有效的公钥值但值不正确,则会发生访问拒绝错误。
如果密钥文件不包含有效的公钥,则客户端程序无法使用它。
在这种情况下,
sha256_password
插件将公钥发送到客户端,就好像没有
--server-public-key-path
指定选项一样。
客户端用户可以通过两种方式获取RSA公钥:
数据库管理员可以提供公钥文件的副本。
可以通过其他方式连接到服务器的客户端用户可以使用
SHOW STATUS LIKE
'Rsa_public_key'
语句并将返回的键值保存在文件中。
MySQL提供了两个身份验证插件,可以为用户帐户密码实现SHA-256哈希:
sha256_password
:实现基本的SHA-256身份验证。
caching_sha2_password
:实现SHA-256身份验证(如
sha256_password
),但在服务器端使用缓存以获得更好的性能,并具有更广泛的适用性的附加功能。
本节介绍缓存SHA-2身份验证插件。 有关原始基本(非高速缓存)插件的信息,请参见 第6.4.1.2节“SHA-256可插入认证” 。
在MySQL 8.0中,
caching_sha2_password
是默认的身份验证插件而不是
mysql_native_password
。
有关此更改对服务器操作的影响以及服务器与客户端和连接器的兼容性的信息,请参阅
caching_sha2_password作为首选身份验证插件
。
要使用通过
caching_sha2_password
插件进行
身份验证的帐户连接到服务器
,您必须使用安全连接或支持使用RSA密钥对进行密码交换的未加密连接,如本节后面所述。
无论哪种方式,
caching_sha2_password
插件都使用MySQL的加密功能。
请参见
第6.3节“使用加密连接”
。
在名称中
sha256_password
,
“
sha256
”
指的是插件用于加密的256位摘要长度。
在名称中
caching_sha2_password
,
“
sha2
”
更一般地指SHA-2类加密算法,其中256位加密是一个实例。
后一个名称选择为将来扩展可能的摘要长度留下了空间,而无需更改插件名称。
与
caching_sha2_password
以下相比,
该
插件具有以下优势
sha256_password
:
在服务器端,内存缓存可以更快地重新验证之前再次连接时已连接的用户。
无论与MySQL链接的SSL库如何,都可以使用基于RSA的密码交换。
支持使用Unix套接字文件和共享内存协议的客户端连接。
下表显示了服务器端和客户端上的插件名称。
表6.15 SHA-2身份验证的插件和库名称
插件或文件 | 插件或文件名 |
---|---|
服务器端插件 | caching_sha2_password |
客户端插件 | caching_sha2_password |
库文件 | 无(插件内置) |
以下部分提供了特定于缓存SHA-2可插入身份验证的安装和使用信息:
有关MySQL中可插入身份验证的一般信息,请参见 第6.2.17节“可插入身份验证” 。
该
caching_sha2_password
插件存在于服务器和客户端表单中:
服务器端插件内置于服务器中,无需显式加载,也无法通过卸载来禁用。
客户端插件内置于
libmysqlclient
客户端库中,可用于任何链接的程序
libmysqlclient
。
服务器端插件使用
sha2_cache_cleaner
审计插件作为帮助程序来执行密码缓存管理。
sha2_cache_cleaner
,比如
caching_sha2_password
,内置,无需安装。
要设置使用
caching_sha2_password
插件进行SHA-256密码哈希
的帐户,请使用
以下语句,其中
password
包含所需的帐户密码:
创建用户'sha2user'@'localhost'
通过caching_sha2_password BY' password
' 识别;
服务器将
caching_sha2_password
插件
分配给
帐户并使用它来使用SHA-256加密密码,并将这些值存储
在
系统表
的
plugin
和
authentication_string
列中
mysql.user
。
前面的说明不假定这
caching_sha2_password
是默认的身份验证插件。
如果
caching_sha2_password
是默认的身份验证插件,
CREATE
USER
则可以使用
更简单的
语法。
要在默认身份验证插件设置为的情况下启动服务器
caching_sha2_password
,请将这些行放在服务器选项文件中:
的[mysqld] default_authentication_plugin = caching_sha2_password
这会导致
caching_sha2_password
默认情况下为新帐户使用插件。
因此,可以创建帐户并设置其密码,而无需明确命名插件:
创建用户'sha2user'@'localhost'IDENTIFIED BY' password
';
设置的另一个结果
default_authentication_plugin
来
caching_sha2_password
的是,使用一些其他的插件创建帐户,您必须指定插件明确。
例如,要使用该
mysql_native_password
插件,请使用以下语句:
创建用户'nativeuser'@'localhost'
使用mysql_native_password BY' password
' 识别;
caching_sha2_password
通过安全传输支持连接。
如果您遵循本节后面给出的RSA配置过程,它还支持使用RSA通过未加密的连接进行加密密码交换。
RSA支持具有以下特征:
在服务器端,两个系统变量命名RSA私钥和公钥对文件:
caching_sha2_password_private_key_path
和
caching_sha2_password_public_key_path
。
如果要使用的密钥文件的名称与系统变量缺省值不同,则数据库管理员必须在服务器启动时设置这些变量。
服务器使用
caching_sha2_password_auto_generate_rsa_keys
系统变量来确定是否自动生成RSA密钥对文件。
请参见
第6.3.3节“创建SSL和RSA证书和密钥”
。
该
Caching_sha2_password_rsa_public_key
状态变量显示由使用的RSA公钥值
caching_sha2_password
认证插件。
拥有RSA公钥的客户端可以在连接过程中与服务器执行基于RSA密钥对的密码交换,如稍后所述。
对于通过身份验证的帐户
caching_sha2_password
和基于RSA密钥对的密码交换的连接,服务器默认情况下不会将RSA公钥发送到客户端。
客户端可以使用所需公钥的客户端副本,或从服务器请求公钥。
使用公钥的可信本地副本使客户端能够避免客户端/服务器协议中的往返,并且比从服务器请求公钥更安全。 另一方面,从服务器请求公钥更方便(它不需要管理客户端文件),并且在安全网络环境中可以接受。
对于命令行客户端,请使用该
--server-public-key-path
选项指定RSA公钥文件。
使用该
--get-server-public-key
选项从服务器请求公钥。
以下程序支持两个选项:
mysql
,
mysqlsh
,
mysqladmin
,
mysqlbinlog
,
mysqlcheck
,
mysqldump
,
mysqlimport
,
mysqlpump
,
mysqlshow
,
mysqlslap
,
mysqltest
,
mysql_upgrade
。
对于使用C API的程序,
mysql_options()
通过传递
MYSQL_SERVER_PUBLIC_KEY
选项和文件名来
调用
以指定RSA公钥
文件,或通过传递
MYSQL_OPT_GET_SERVER_PUBLIC_KEY
选项
从服务器请求公钥
。
对于复制从属服务器,请使用
CHANGE MASTER TO
带有
MASTER_PUBLIC_KEY_PATH
选项
的
语句
指定RSA公钥文件,或使用
GET_MASTER_PUBLIC_KEY
从主服务器请求公钥
的
选项。
对于组复制,
系统变量
group_replication_recovery_public_key_path
和
group_replication_recovery_get_public_key
系统变量具有相同的用途。
在所有情况下,如果给出了指定有效公钥文件的选项,则它优先于从服务器请求公钥的选项。
对于使用该
caching_sha2_password
插件的
客户端
,密码在连接到服务器时绝不会以明文形式公开。
密码传输的方式取决于是使用安全连接还是RSA加密:
如果连接是安全的,则不需要RSA密钥对,也不使用。 这适用于使用TLS的加密TCP连接,以及Unix套接字文件和共享内存连接。 密码以明文形式发送,但由于连接安全,因此无法窥探密码。
如果连接不安全,则使用RSA密钥对。 这适用于没有TLS和命名管道连接的未加密TCP连接。 RSA仅用于客户端和服务器之间的密码交换,以防止密码窥探。 当服务器收到加密密码时,它会对其进行解密。 加密中使用加扰来防止重复攻击。
要在客户端连接过程中使用RSA密钥对进行密码交换,请使用以下过程:
使用 第6.3.3节“创建SSL和RSA证书和密钥”中 的说明创建RSA专用和公用密钥对文件 。
如果私钥和公钥文件都位于数据目录中,名为
private_key.pem
和
public_key.pem
(的默认值
caching_sha2_password_private_key_path
和
caching_sha2_password_public_key_path
系统变量),服务器在启动时自动使用它们。
否则,要明确命名密钥文件,请将系统变量设置为服务器选项文件中的密钥文件名。 如果文件位于服务器数据目录中,则无需指定其完整路径名:
的[mysqld] caching_sha2_password_private_key_path = myprivkey.pem caching_sha2_password_public_key_path = mypubkey.pem
如果密钥文件不在数据目录中,或者在系统变量值中显示其位置,请使用完整路径名:
的[mysqld] caching_sha2_password_private_key_path =的/ usr /本地/ MySQL的/ myprivkey.pem caching_sha2_password_public_key_path =的/ usr /本地/ MySQL的/ mypubkey.pem
重新启动服务器,然后连接到它并检查
Caching_sha2_password_rsa_public_key
状态变量值。
该值将与此处显示的值不同,但应该是非空的:
MySQL的> SHOW STATUS LIKE 'Caching_sha2_password_rsa_public_key'\G
*************************** 1。排******************** *******
Variable_name:Caching_sha2_password_rsa_public_key
价值:-----开始公钥-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO9nRUDd + KvSZgY7cNBZMNpwX6
MvE1PbJFXO7u18nJ9lwc99Du / E7lw6CVXw7VKrXPeHbVQUzGyUNkf45Nz / ckaaJa
aLgJOBCIDmNVnyU54OT / 1lcs2xiyfaDMe8fCJ64ZwTnKbY2gkt1IMjUAB5Ogd5kJ
g8aV7EtKwyhHb0c30QIDAQAB
----- END PUBLIC KEY -----
如果值为空,则服务器发现密钥文件存在问题。 检查错误日志以获取诊断信息。
使用RSA密钥文件配置服务器后,使用该
caching_sha2_password
插件进行
身份验证的帐户可以
选择使用这些密钥文件连接到服务器。
如前所述,此类帐户可以使用安全连接(在这种情况下不使用RSA)或使用RSA执行密码交换的未加密连接。
假设使用了未加密的连接。
例如:
shell>mysql --ssl-mode=DISABLED -u sha2user -p
输入密码:password
对于此连接尝试
sha2user
,服务器确定该
caching_sha2_password
是适当的身份验证插件并调用它(因为那是
CREATE
USER
时间
指定的插件
)。
该插件发现连接未加密,因此需要使用RSA加密传输密码。
但是,服务器不会将公钥发送到客户端,并且客户端不提供公钥,因此无法加密密码并且连接失败:
ERROR 2061(HY000):身份验证插件'caching_sha2_password' 报告错误:身份验证需要安全连接。
要从服务器请求RSA公钥,请指定
--get-server-public-key
选项:
shell>mysql --ssl-mode=DISABLED -u sha2user -p --get-server-public-key
输入密码:password
在这种情况下,服务器将RSA公钥发送给客户端,客户端使用它来加密密码并将结果返回给服务器。 该插件使用服务器端的RSA私钥来解密密码,并根据密码是否正确接受或拒绝连接。
或者,如果客户端具有包含服务器所需的RSA公钥的本地副本的文件,则它可以使用以下
--server-public-key-path
选项
指定该文件
:
shell> 输入密码:mysql --ssl-mode=DISABLED -u sha2user -p --server-public-key-path=
file_name
password
在这种情况下,客户端使用公钥来加密密码并将结果返回给服务器。 该插件使用服务器端的RSA私钥来解密密码,并根据密码是否正确接受或拒绝连接。
--server-public-key-path
选项
命名的文件中的公钥值
应与
caching_sha2_password_public_key_path
系统变量
指定的服务器端文件中的键值相同
。
如果密钥文件包含有效的公钥值但值不正确,则会发生访问拒绝错误。
如果密钥文件不包含有效的公钥,则客户端程序无法使用它。
客户端用户可以通过两种方式获取RSA公钥:
数据库管理员可以提供公钥文件的副本。
可以通过其他方式连接到服务器的客户端用户可以使用
SHOW STATUS LIKE
'Caching_sha2_password_rsa_public_key'
语句并将返回的键值保存在文件中。
在服务器端,该
caching_sha2_password
插件使用内存缓存来更快地验证之前已连接的客户端。
条目由帐户名/密码哈希对组成。
缓存的工作方式如下:
当客户端连接时,
caching_sha2_password
检查客户端和密码是否与某些缓存条目匹配。
如果是,则身份验证成功。
如果没有匹配的缓存条目,则插件会尝试根据
mysql.user
系统表
中的凭据验证客户端
。
如果成功,
caching_sha2_password
则将客户端条目添加到哈希。
否则,身份验证失败,连接被拒绝。
这样,当客户端首次连接时,
mysql.user
就会
对
系统表进行
身份验证
。
当客户端随后连接时,会对缓存进行更快的身份验证。
除了添加条目之外的密码缓存操作由
sha2_cache_cleaner
审计插件
处理,
审计插件代表以下方式执行以下操作
caching_sha2_password
:
它会清除重命名或删除的任何帐户的缓存条目,或者更改凭据或身份验证插件的任何帐户。
它在
FLUSH
PRIVILEGES
执行语句
时清空缓存
。
它会在服务器关闭时清空缓存。 (这意味着缓存在服务器重新启动时不会持久。)
缓存清除操作会影响后续客户端连接的身份验证要求。 对于每个用户帐户,在执行以下任何操作之后,用户的第一个客户端连接必须使用安全连接(使用TCP使用TLS凭据,Unix套接字文件或共享内存)或基于RSA密钥对的密码交换:
创建帐户后。
更改帐户密码后。
之后
RENAME USER
的帐户。
之后
FLUSH PRIVILEGES
。
FLUSH PRIVILEGES
清除整个缓存并影响使用该
caching_sha2_password
插件的
所有帐户
。
其他操作会清除特定的高速缓存条目,并仅影响属于该操作的帐户。
用户成功验证后,帐户将进入缓存,后续连接不需要安全连接或RSA密钥对,直到发生影响帐户的另一个缓存清除事件。 (当可以使用缓存时,服务器使用质询 - 响应机制,该机制不使用明文密码传输,也不需要安全连接。)
客户端身份验证插件可用,使客户端能够以明文形式向服务器发送密码,而无需散列或加密。 这个插件内置在MySQL客户端库中。
下表显示了插件名称。
许多客户端身份验证插件在客户端将其发送到服务器之前执行散列或密码加密。 这使客户端可以避免以明文形式发送密码。
无法对需要服务器接收客户端输入的密码的身份验证方案进行散列或加密。
在这种情况下,使用客户端
mysql_clear_password
插件,使客户端能够以明文形式将密码发送到服务器。
没有相应的服务器端插件。
相反,
mysql_clear_password
可以在客户端使用任何需要明文密码的服务器端插件。
(例如PAM和简单LDAP身份验证插件;请参见
第6.4.1.5节“PAM可插入身份验证”
和
第6.4.1.7节“LDAP可插入身份验证”
。)
以下讨论提供了特定于明文可插入身份验证的使用信息。 有关MySQL中可插入身份验证的一般信息,请参见 第6.2.17节“可插入身份验证” 。
在某些配置中,将密码作为明文发送可能是一个安全问题。 如果有可能截获密码以避免出现问题,客户端应使用保护密码的方法连接到MySQL Server。 可能性包括SSL(请参见 第6.3节“使用加密连接” ),IPsec或专用网络。
为了
mysql_clear_password
不太可能
无意中使用
插件,MySQL客户端必须明确启用它。
这可以通过以下几种方式完成:
在设置
LIBMYSQL_ENABLE_CLEARTEXT_PLUGIN
环境变量,且开头的值
1
,
Y
或
y
。
这为所有客户端连接启用了插件。
在
MySQL的
,
中mysqladmin
,
mysqlcheck的
,
mysqldump的
,
mysqlshow
和
mysqlslap
客户端程序支持
--enable-cleartext-plugin
,允许在每调用基础的插件选项。
的
mysql_options()
C API函数支持
MYSQL_ENABLE_CLEARTEXT_PLUGIN
选项,使在每个连接的基础插件。
此外,任何使用
libmysqlclient
和读取选项文件的程序都可以
enable-cleartext-plugin
通过在客户端库读取的选项组中
包含
选项
来启用插件
。
PAM可插入身份验证是MySQL企业版(一种商业产品)中包含的扩展。 要了解有关商业产品的更多信息,请访问 https://www.mysql.com/products/ 。
MySQL企业版支持一种身份验证方法,使MySQL服务器能够使用PAM(可插入身份验证模块)对MySQL用户进行身份验证。 PAM使系统能够使用标准接口访问各种身份验证方法,例如传统的Unix密码或LDAP目录。
PAM可插拔身份验证提供以下功能:
外部身份验证:PAM身份验证使MySQL Server能够接受来自MySQL授权表外部定义的用户的连接,并使用PAM支持的方法进行身份验证。
代理用户支持:根据外部用户所属的PAM组和提供的身份验证字符串,PAM身份验证可以向MySQL返回与客户端程序传递的外部用户名不同的用户名。
这意味着该插件可以返回MySQL用户,该用户定义外部PAM认证用户应具有的权限。
例如,名为的操作系统用户
joe
可以连接并具有名为的MySQL用户的权限
developer
。
PAM可插拔身份验证已在Linux和macOS上进行了测试。
下表显示了插件和库文件名。
文件名后缀可能与您的系统不同。
该文件必须位于
plugin_dir
系统变量
指定的目录中
。
有关安装信息,请参阅
安装PAM可插入身份验证
。
表6.17 PAM身份验证的插件和库名称
插件或文件 | 插件或文件名 |
---|---|
服务器端插件 | authentication_pam |
客户端插件 | mysql_clear_password |
库文件 | authentication_pam.so |
mysql_clear_password
与服务器端PAM插件通信
的客户端
明文插件内置于
libmysqlclient
客户端库中,并包含在所有发行版中,包括社区发行版。
在所有MySQL发行版中包含客户端cleartext插件,可以使任何发行版的客户端连接到加载了服务器端PAM插件的服务器。
以下部分提供了特定于PAM可插入身份验证的安装和使用信息:
有关MySQL中可插入身份验证的一般信息,请参见
第6.2.17节“可插入身份验证”
。
有关
mysql_clear_password
插件的
信息
,请参见
第6.4.1.4节“客户端明文可插入认证”
。
有关代理用户信息,请参见
第6.2.18节“代理用户”
。
本节概述了MySQL和PAM如何协同工作以验证MySQL用户。 有关如何设置MySQL帐户以使用特定PAM服务的示例,请参阅 使用PAM可插入身份验证 。
客户端程序和服务器通信,客户端向服务器发送客户端用户名(默认为操作系统用户名)和密码:
客户端用户名是外部用户名。
对于使用PAM服务器端身份验证插件的帐户,相应的客户端插件是
mysql_clear_password
。
此客户端插件不执行密码散列,结果客户端以明文形式将密码发送到服务器。
服务器根据外部用户名和客户端连接的主机找到匹配的MySQL帐户。 PAM插件使用MySQL Server传递给它的信息(例如用户名,主机名,密码和认证字符串)。 定义使用PAM进行身份验证的MySQL帐户时,身份验证字符串包含:
PAM服务名称,系统管理员可以使用该名称来引用特定应用程序的身份验证方法。 可以有多个与单个数据库服务器实例关联的应用程序,因此服务名称的选择留给SQL应用程序开发人员。
(可选)如果要使用代理,则从PAM组到MySQL用户名的映射。
该插件使用身份验证字符串中指定的PAM服务来检查用户凭据并返回
或
。
密码必须适合PAM服务使用的密码存储。
例子:
'Authentication succeeded, Username is
user_name
''Authentication failed'
对于传统的Unix密码,该服务会查找存储在
/etc/shadow
文件中的
密码
。
对于LDAP,该服务查找存储在LDAP目录中的密码。
如果凭据检查失败,则服务器拒绝连接。
否则,验证字符串指示是否发生代理。 如果字符串不包含PAM组映射,则不会发生代理。 在这种情况下,MySQL用户名与外部用户名相同。
否则,基于PAM组映射指示代理,其中MySQL用户名基于映射列表中的第一个匹配组来确定。 “ PAM组 ” 的含义 取决于PAM服务。 例子:
对于传统的Unix密码,组是
/etc/group
文件中
定义的Unix组
,可能
在
文件中补充了额外的PAM信息
/etc/security/group.conf
。
对于LDAP,组是LDAP目录中定义的LDAP组。
如果代理用户(外部用户)具有
PROXY
代理MySQL用户名的特权,则代理用户将承担代理用户的特权,从而进行代理。
本节介绍如何安装PAM身份验证插件。 有关安装插件的一般信息,请参见 第5.6.1节“安装和卸载插件” 。
要使服务器可以使用,插件库文件必须位于MySQL插件目录(
plugin_dir
系统变量
指定的目录
)中。
如有必要,通过设置
plugin_dir
服务器启动时
的值来配置插件目录位置
。
插件库文件基本名称是
authentication_pam
。
文件名后缀因平台
.so
而异
(例如,
对于Unix和类Unix系统,
.dll
对于Windows)。
要在服务器启动时加载插件,请使用该
--plugin-load-add
选项命名包含它的库文件。
使用此插件加载方法,每次服务器启动时都必须提供该选项。
例如,将这些行放在服务器
my.cnf
文件中(
.so
根据需要
调整
平台
的
后缀):
的[mysqld] 插件的负载加= authentication_pam.so
修改后
my.cnf
,重新启动服务器以使新设置生效。
或者,要在运行时注册插件,请使用此语句(
.so
根据需要
调整
后缀):
INSTALL PLUGIN authentication_pam SONAME'authentication_pam.so';
INSTALL
PLUGIN
立即加载插件,并将其注册到
mysql.plugins
系统表中,以使服务器为每个后续的正常启动加载它。
要验证插件安装,请检查
INFORMATION_SCHEMA.PLUGINS
表或使用该
SHOW PLUGINS
语句(请参见
第5.6.2节“获取服务器插件信息”
)。
例如:
MySQL的>SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE '%pam%';
+ -------------------- + --------------- + | PLUGIN_NAME | PLUGIN_STATUS | + -------------------- + --------------- + | authentication_pam | ACTIVE | + -------------------- + --------------- +
如果插件无法初始化,请检查服务器错误日志以获取诊断消息。
要将MySQL帐户与PAM插件关联,请参阅 使用PAM可插入身份验证 。
用于卸载PAM身份验证插件的方法取决于您安装它的方式:
如果您在服务器启动时使用
--plugin-load-add
选项
安装了插件,请在
没有该选项的情况下重新启动服务器。
如果您在运行时使用安装插件
INSTALL PLUGIN
,它将在服务器重新启动
时
保持安装。
要卸载它,请使用
UNINSTALL PLUGIN
:
UNINSTALL PLUGIN authentication_pam;
本节概括地描述了如何使用PAM身份验证插件从MySQL客户端程序连接到服务器。 以下部分提供了以特定方式使用PAM身份验证的说明。 假设服务器在启用服务器端PAM插件的情况下运行,如 安装PAM可插入身份验证中所述 。
要在
语句
的
IDENTIFIED WITH
子句中
引用PAM身份验证插件
CREATE
USER
,请使用该名称
authentication_pam
。
例如:
创建用户user
通过authentication_pam识别 AS'auth_string
';
身份验证字符串指定以下类型的信息:
PAM服务名称(请参阅
MySQL用户的PAM身份验证如何工作
)。
以下讨论中的示例使用服务名称
mysql-unix
进行使用传统Unix密码
mysql-ldap
的身份验证
,以及
使用LDAP进行身份验证。
对于代理支持,PAM为PAM模块提供了一种方法,以便在连接到服务器时,将客户端程序传递的外部用户名以外的MySQL用户名返回给服务器。 使用身份验证字符串来控制从外部用户名到MySQL用户名的映射。 如果要利用代理用户功能,则身份验证字符串必须包含此类映射。
例如,如果帐户使用
mysql-unix
PAM服务名称并且应该将
root
和
users
PAM组
中的操作系统用户分别映射
到
developer
和
data_entry
MySQL用户,请使用如下语句:
创建用户 user
通过authentication_pam识别
AS'mysql-unix,root = developer,users = data_entry';
PAM身份验证插件的身份验证字符串语法遵循以下规则:
该字符串由PAM服务名称组成,可选地后跟PAM组映射列表,该列表由一个或多个关键字/值对组成,每个关键字/值对指定一个PAM组名称和一个MySQL用户名:
pam_service_name
[,pam_group_name
=mysql_user_name
] ......
插件为每个使用该帐户的连接尝试解析身份验证字符串。 为了尽量减少开销,请尽可能缩短字符串。
每
对必须以逗号开头。
pam_group_name
=mysql_user_name
不在双引号内的前导和尾随空格将被忽略。
未加引号
pam_service_name
,
pam_group_name
和
mysql_user_name
值可包含除等号,逗号或空间什么。
如果
使用双引号引用
a
pam_service_name
,
pam_group_name
或
mysql_user_name
值,则引号之间的所有内容都是值的一部分。
例如,如果值包含空格字符,则这是必需的。
除双引号和反斜杠(
\
)
外,所有字符都是合法的
。
要包含任一字符,请使用反斜杠转义它。
如果插件成功验证了外部用户名(客户端传递的名称),它会在身份验证字符串中查找PAM组映射列表,如果存在,则使用它来向MySQL服务器返回不同的MySQL用户名。哪些PAM组外部用户是以下成员:
如果身份验证字符串不包含PAM组映射列表,则插件将返回外部名称。
如果验证字符串确实包含PAM组映射列表,插件检查每个
列表中对由左到右,并试图找到一个匹配
分配给经过身份验证的用户和收益组的非MySQL目录值
的它找到的第一场比赛。
如果插件找不到任何PAM组的匹配项,则返回外部名称。
如果插件无法在目录中查找组,则会忽略PAM组映射列表并返回外部名称。
pam_group_name
=mysql_user_name
pam_group_name
mysql_user_name
以下部分描述了如何设置使用PAM身份验证插件的多个身份验证方案:
没有代理用户。
这仅使用PAM来检查登录名和密码。
允许连接到MySQL服务器的每个外部用户都应该具有匹配的MySQL帐户,该帐户被定义为使用PAM身份验证。
(对于
与外部用户匹配的
MySQL帐户
,
必须是外部用户名,并且
必须与客户端连接的主机匹配。)可以通过各种PAM支持的方法执行身份验证。
后面的讨论显示了如何使用传统的Unix密码和LDAP中的密码验证客户端凭据。
'
user_name
'@'host_name
'user_name
host_name
PAM身份验证(不通过代理用户或PAM组完成)要求MySQL用户名与操作系统用户名相同。 MySQL用户名限制为32个字符(请参见 第6.2.3节“授权表” ),这会将PAM非委托身份验证限制为名称最多为32个字符的Unix帐户。
仅限代理用户,具有PAM组映射。 对于此方案,请创建一个或多个定义不同权限集的MySQL帐户。 (理想情况下,没有人应该直接使用这些帐户进行连接。)然后定义一个默认用户通过PAM进行身份验证,该用户使用一些映射方案(通常基于用户所属的外部PAM组)将所有外部用户名映射到少数MySQL持有特权集的帐户。 连接并指定外部用户名作为客户端用户名的任何客户端都映射到其中一个MySQL帐户并使用其权限。 讨论显示了如何使用传统的Unix密码进行设置,
这些方案的变化是可能的:
您可以允许某些用户直接登录(无需代理),但要求其他用户通过代理帐户进行连接。
通过在经过PAM验证的帐户中使用不同的PAM服务名,可以为某些用户使用一种PAM身份验证方法,为其他用户使用另一种方法。
例如,您可以
mysql-unix
为某些用户和
mysql-ldap
其他
用户
使用
PAM服务
。
这些例子做出以下假设。 如果您的系统设置不同,则可能需要进行一些调整。
登录名和密码分别为
antonio
和
antonio_password
。
更改这些以对应您要进行身份验证的用户。
PAM配置目录是
/etc/pam.d
。
PAM服务名称对应于身份验证方法(
mysql-unix
或
mysql-ldap
在此讨论中)。
要使用给定的PAM服务,必须在PAM配置目录中设置具有相同名称的PAM文件(如果文件不存在,则创建该文件)。
此外,您必须在
CREATE USER
使用该PAM服务进行身份验证的任何帐户
的
语句
的身份验证字符串中命名
PAM服务。
PAM身份验证插件在初始化时检查是否
AUTHENTICATION_PAM_LOG
在服务器的启动环境中设置
了
环境值。
如果是这样,该插件可以将诊断消息记录到标准输出。
根据服务器的启动方式,消息可能会显示在控制台或错误日志中。
这些消息有助于调试插件执行身份验证时发生的与PAM相关的问题。
有关更多信息,请参阅
PAM身份验证调试
。
此身份验证方案使用PAM检查根据操作系统用户名和Unix密码定义的外部用户,而无需代理。 允许连接到MySQL服务器的每个这样的外部用户都应该有一个匹配的MySQL帐户,该帐户被定义为通过传统的Unix密码存储使用PAM身份验证。
使用该
/etc/shadow
文件
检查传统的Unix密码
。
有关与此文件相关的可能问题的信息,请参阅
对Unix密码存储的PAM身份验证访问
。
验证Unix身份验证是否允许使用用户名
antonio
和密码
登录操作系统
antonio_password
。
通过创建
mysql-unix
名为
的
PAM服务文件,
设置PAM以使用传统的Unix密码验证MySQL连接
/etc/pam.d/mysql-unix
。
文件内容与系统有关,因此请检查目录中现有的与登录相关的文件,
/etc/pam.d
以查看它们的外观。
在Linux上,该
mysql-unix
文件可能如下所示:
#%PAM-1.0 auth包括password-auth 帐户包括密码验证
对于macOS,请使用
login
而不是
password-auth
。
PAM文件格式在某些系统上可能有所不同。 例如,在Ubuntu和其他基于Debian的系统上,请改用以下文件内容:
@include common-auth @include普通帐户 @include common-session-noninteractive
使用与操作系统用户名相同的用户名创建一个MySQL帐户,并使用PAM插件和
mysql-unix
PAM服务
对其进行身份验证
:
创建用户'antonio'@'localhost' 通过authentication_pam识别 AS'mysql-unix'; 授予所有特权 在mydb。* TO'antonio'@'localhost';
此处,身份验证字符串仅包含PAM服务名称
mysql-unix
,该
服务名称
验证Unix密码。
使用
mysql
命令行客户端连接到MySQL服务器
antonio
。
例如:
shell>mysql --user=antonio --password --enable-cleartext-plugin
输入密码:
antonio_password
服务器应该允许连接,以下查询应该返回输出,如下所示:
MySQL的> SELECT USER(), CURRENT_USER(), @@proxy_user;
+ ------------------- ------------------- + --------- + ----- +
| USER()| CURRENT_USER()| @@ proxy_user |
+ ------------------- ------------------- + --------- + ----- +
| antonio @ localhost | antonio @ localhost | NULL |
+ ------------------- ------------------- + --------- + ----- +
这表明
antonio
操作系统用户已通过身份验证,具有授予
antonio
MySQL用户
的权限
,并且未发生代理。
客户端
mysql_clear_password
身份验证插件保持密码不变,因此客户端程序将其作为明文发送到MySQL服务器。
这使得密码可以原样传递给PAM。
使用服务器端PAM库需要使用明文密码,但在某些配置中可能存在安全问题。
这些措施将风险降至最低:
为了
mysql_clear_password
不太可能
无意中使用
插件,MySQL客户端必须明确启用它(例如,使用该
--enable-cleartext-plugin
选项)。
请参见
第6.4.1.4节“客户端明文可插拔认证”
。
为避免在
mysql_clear_password
启用插件时
密码暴露
,MySQL客户端应使用加密连接连接到MySQL服务器。
请参见
第6.3.1节“配置MySQL以使用加密连接”
。
此身份验证方案使用PAM检查根据操作系统用户名和LDAP密码定义的外部用户,而无需代理。 允许连接到MySQL服务器的每个这样的外部用户都应该具有匹配的MySQL帐户,该帐户被定义为通过LDAP使用PAM身份验证。
要对MySQL使用PAM LDAP可插入身份验证,必须满足以下先决条件:
必须有LDAP服务器才能与PAM LDAP服务进行通信。
要由MySQL进行身份验证的LDAP用户必须存在于LDAP服务器管理的目录中。
使用LDAP进行MySQL用户身份验证的另一种方法是使用特定于LDAP的身份验证插件。 请参见 第6.4.1.7节“LDAP可插入认证” 。
为PAM LDAP身份验证配置MySQL,如下所示:
验证Unix身份验证是否允许使用用户名
antonio
和密码
登录操作系统
antonio_password
。
设置PAM以使用LDAP通过创建
mysql-ldap
名为
的
PAM服务文件
来验证MySQL连接
/etc/pam.d/mysql-ldap
。
文件内容与系统有关,因此请检查目录中现有的与登录相关的文件,
/etc/pam.d
以查看它们的外观。
在Linux上,该
mysql-ldap
文件可能如下所示:
#%PAM-1.0 auth需要pam_ldap.so 需要帐户pam_ldap.so
如果PAM对象文件的后缀与
.so
系统上
的后缀不同
,请替换正确的后缀。
PAM文件格式在某些系统上可能有所不同。
使用与操作系统用户名相同的用户名创建一个MySQL帐户,并使用PAM插件和
mysql-ldap
PAM服务
对其进行身份验证
:
创建用户'antonio'@'localhost' 通过authentication_pam识别 AS'mysql-ldap'; 授予所有特权 在mydb。* TO'antonio'@'localhost';
此处,身份验证字符串仅包含PAM服务名称
mysql-ldap
,该
服务名称
使用LDAP进行身份验证。
连接到服务器与 没有代理用户的Unix密码验证中 描述的相同 。
此处描述的身份验证方案使用代理和PAM组映射将使用PAM进行身份验证的连接MySQL用户映射到定义不同权限集的其他MySQL帐户。 用户不直接通过定义权限的帐户进行连接。 相反,它们通过使用PAM进行身份验证的默认代理用户进行连接,以便将所有外部用户映射到拥有权限的MySQL帐户。 任何连接的用户都映射到其中一个MySQL帐户,其权限决定了外部用户允许的数据库操作。
此处显示的过程使用Unix密码验证。 要使用LDAP,请参阅 没有代理用户 的 LDAP身份验证 的早期步骤 。
使用该
/etc/shadow
文件
检查传统的Unix密码
。
有关与此文件相关的可能问题的信息,请参阅
对Unix密码存储的PAM身份验证访问
。
验证Unix身份验证是否允许使用用户名
antonio
和密码
登录操作系统
antonio_password
。
验证
antonio
是的成员
root
或
users
PAM基。
设置PAM以
mysql-unix
通过创建名为的文件来通过操作系统用户
对
PAM服务
进行身份验证
/etc/pam.d/mysql-unix
。
文件内容与系统有关,因此请检查目录中现有的与登录相关的文件,
/etc/pam.d
以查看它们的外观。
在Linux上,该
mysql-unix
文件可能如下所示:
#%PAM-1.0 auth包括password-auth 帐户包括密码验证
对于macOS,请使用
login
而不是
password-auth
。
PAM文件格式在某些系统上可能有所不同。 例如,在Ubuntu和其他基于Debian的系统上,请改用以下文件内容:
@include common-auth @include普通帐户 @include common-session-noninteractive
创建一个默认代理用户(
''@''
),将外部PAM用户映射到代理帐户:
创建用户 ''@'' 通过authentication_pam识别 AS'mysql-unix,root = developer,users = data_entry';
这里,身份验证字符串包含PAM服务名称
mysql-unix
,用于验证Unix密码。
身份验证字符串还将
root
和
users
PAM组中的
外部用户分别映射
到
developer
和
data_entry
MySQL用户名。
设置代理用户时,需要PAM服务名称后面的PAM组映射列表。 否则,插件无法告诉如何执行从外部用户名到正确代理的MySQL用户名的映射。
如果您的MySQL安装具有匿名用户,则可能与默认代理用户冲突。 有关此问题的更多信息以及处理它的方法,请参阅 默认代理用户和匿名用户冲突 。
创建具有MySQL访问所需权限的代理帐户:
创建用户'开发者'@'localhost' 识别''very secret password
'; 创建用户'data_entry'@'localhost' 识别'very secret password
'; 授予所有特权 在mydevdb上。* 致''开发'''localhost'; 授予所有特权 在mydb。* TO'data_entry'@'localhost';
如果您不让任何人知道这些帐户的密码,客户端就无法使用它们直接连接到MySQL服务器。
相反,预计使用PAM进行身份验证的用户将
根据其PAM组
使用
developer
或
data_entry
代理帐户。
确保代理帐户无法直接使用的其他方法:
ACCOUNT LOCK
创建帐户时
包括该
选项。
请参见
第13.7.1.3节“创建用户语法”
。
将帐户与
mysql_no_login
身份验证插件相关联。
请参见
第6.4.1.8节“无登录可插入认证”
。
将
PROXY
权限
授予
每个代理帐户的代理帐户:
授予代理权 ON'开发者'@'localhost' 至 ''@''; 授予代理权 ON'data_entry'@'localhost' 至 ''@'';
使用
mysql
命令行客户端连接到MySQL服务器
antonio
。
shell>mysql --user=antonio --password --enable-cleartext-plugin
输入密码:
antonio_password
服务器使用
''@''
代理帐户
验证连接
。
由此产生的权限
antonio
取决于哪些PAM组
antonio
是其成员。
如果
antonio
是
root
PAM组
的成员
,则PAM插件将映射
root
到
developer
MySQL用户名并将该名称返回给服务器。
服务器验证是否
''@''
具有该
PROXY
权限
developer
并允许连接。
以下查询应返回输出,如下所示:
MySQL的> SELECT USER(), CURRENT_USER(), @@proxy_user;
+ ------------------- + --------------------- + ------- ------- +
| USER()| CURRENT_USER()| @@ proxy_user |
+ ------------------- + --------------------- + ------- ------- +
| antonio @ localhost | developer @ localhost | ''@''|
+ ------------------- + --------------------- + ------- ------- +
这表明
antonio
操作系统用户已通过身份验证,具有授予
developer
MySQL用户
的权限
,并且代理通过默认代理帐户进行。
如果
antonio
不是
root
PAM组的成员但是PAM组的成员,
users
则会发生类似的过程,但插件将
user
PAM组成员身份
映射
到
data_entry
MySQL用户名并将该名称返回给服务器:
MySQL的> SELECT USER(), CURRENT_USER(), @@proxy_user;
+ ------------------- + ---------------------- + ------ -------- +
| USER()| CURRENT_USER()| @@ proxy_user |
+ ------------------- + ---------------------- + ------ -------- +
| antonio @ localhost | data_entry @ localhost | ''@''|
+ ------------------- + ---------------------- + ------ -------- +
这表明
antonio
操作系统用户已通过身份验证,具有
data_entry
MySQL用户
的权限
,并且代理通过默认代理帐户进行。
客户端
mysql_clear_password
身份验证插件保持密码不变,因此客户端程序将其作为明文发送到MySQL服务器。
这使得密码可以原样传递给PAM。
使用服务器端PAM库需要使用明文密码,但在某些配置中可能存在安全问题。
这些措施将风险降至最低:
为了
mysql_clear_password
不太可能
无意中使用
插件,MySQL客户端必须明确启用它(例如,使用该
--enable-cleartext-plugin
选项)。
请参见
第6.4.1.4节“客户端明文可插拔认证”
。
为避免在
mysql_clear_password
启用插件时
密码暴露
,MySQL客户端应使用加密连接连接到MySQL服务器。
请参见
第6.3.1节“配置MySQL以使用加密连接”
。
在某些系统上,Unix身份验证使用密码存储,例如
/etc/shadow
通常具有受限访问权限的文件。
这可能导致基于MySQL的MySQL身份验证失败。
不幸的是,PAM实现不允许区分
“
密码无法检查
”
(例如,由于无法读取
/etc/shadow
)
“
密码不匹配。
“
如果您使用Unix密码存储进行PAM身份验证,则可以使用以下方法之一从MySQL启用对它的访问:
假设MySQL服务器是从
mysql
操作系统帐户
运行的,请将该
帐户放入
shadow
具有
/etc/shadow
访问权限
的
组中
:
在中创建一个
shadow
组
/etc/group
。
将
mysql
操作系统用户
添加
到
shadow
组中
/etc/group
。
分配
/etc/group
给
shadow
组并启用组读取权限:
chgrp shadow / etc / shadow chmod g + r / etc / shadow
重启MySQL服务器。
如果您使用的是
pam_unix
模块和
unix_chkpwd
实用程序,请启用密码存储访问,如下所示:
chmod us / usr / sbin / unix_chkpwd setcap cap_dac_read_search + ep / usr / sbin / unix_chkpwd
根据平台的需要 调整 unix_chkpwd 的路径 。
PAM身份验证插件在初始化时检查
AUTHENTICATION_PAM_LOG
环境值
是否
已设置(值无关紧要)。
如果是这样,该插件可以将诊断消息记录到标准输出。
这些消息可能有助于调试插件执行身份验证时发生的与PAM相关的问题。
有些消息包括对PAM插件源文件和行号的引用,这使得插件操作可以更紧密地与代码中的位置绑定。
调试连接失败和确定连接尝试期间发生的事情的另一种技术是配置PAM身份验证以允许所有连接,然后检查系统日志文件。 此技术应仅在 临时 基础上使用,而不应在生产服务器上使用。
配置
/etc/pam.d/mysql-any-password
以这些内容
命名的PAM服务文件
(某些系统上的格式可能不同):
#%PAM-1.0 auth需要pam_permit.so 需要帐户pam_permit.so
创建一个使用PAM插件的帐户并命名
mysql-any-password
PAM服务:
创建用户'testuser'@'localhost' 通过authentication_pam识别 AS'mysql-any-password';
该
mysql-any-password
服务文件导致的任何身份验证尝试返回true,即使是不正确的密码。
如果身份验证尝试失败,则会告诉您配置问题是在MySQL端。
否则,问题出在操作系统/ PAM端。
要了解可能发生的,请检查系统日志文件,如
/var/log/secure
,
/var/log/audit.log
,
/var/log/syslog
,或
/var/log/messages
。
确定问题所在后,删除
mysql-any-password
PAM服务文件以禁用任何密码访问。
Windows可插入身份验证是MySQL企业版(一种商业产品)中包含的扩展。 要了解有关商业产品的更多信息,请访问 https://www.mysql.com/products/ 。
MySQL Enterprise Edition for Windows支持在Windows上执行外部身份验证的身份验证方法,使MySQL Server能够使用本机Windows服务对客户端连接进行身份验证。 已登录Windows的用户可以根据其环境中的信息从MySQL客户端程序连接到服务器,而无需指定其他密码。
客户端和服务器在身份验证握手中交换数据包。 作为此交换的结果,服务器创建一个安全上下文对象,该对象表示Windows操作系统中客户端的标识。 此标识包括客户帐户的名称。 Windows可插入身份验证使用客户端的标识来检查它是给定帐户还是组成员。 默认情况下,协商使用Kerberos进行身份验证,如果Kerberos不可用,则使用NTLM。
Windows可插入身份验证提供以下功能:
外部身份验证:Windows身份验证使MySQL Server能够接受已登录到Windows的MySQL授权表外部定义的用户的连接。
代理用户支持:Windows身份验证可以向MySQL返回与客户端程序传递的外部用户名不同的用户名。
这意味着该插件可以返回MySQL用户,该用户定义外部Windows身份验证用户应具有的权限。
例如,名为的Windows用户
joe
可以连接并拥有名为的MySQL用户的权限
developer
。
下表显示了插件和库文件名。
该文件必须位于
plugin_dir
系统变量
指定的目录中
。
表6.18 Windows身份验证的插件和库名称
插件或文件 | 插件或文件名 |
---|---|
服务器端插件 | authentication_windows |
客户端插件 | authentication_windows_client |
库文件 | authentication_windows.dll |
库文件仅包含服务器端插件。
客户端插件内置于
libmysqlclient
客户端库中。
服务器端Windows身份验证插件仅包含在MySQL Enterprise Edition中。 它不包含在MySQL社区发行版中。 客户端插件包含在所有发行版中,包括社区发行版。 这允许来自任何分发的客户端连接到加载了服务器端插件的服务器。
MySQL 8.0支持的任何Windows版本都支持Windows身份验证插件(请参阅 https://www.mysql.com/support/supportedplatforms/database.html )。
以下部分提供了特定于Windows可插入身份验证的安装和使用信息:
有关MySQL中可插入身份验证的一般信息,请参见 第6.2.17节“可插入身份验证” 。 有关代理用户信息,请参见 第6.2.18节“代理用户” 。
本节介绍如何安装Windows身份验证插件。 有关安装插件的一般信息,请参见 第5.6.1节“安装和卸载插件” 。
要使服务器可以使用,插件库文件必须位于MySQL插件目录(
plugin_dir
系统变量
指定的目录
)中。
如有必要,通过设置
plugin_dir
服务器启动时
的值来配置插件目录位置
。
要在服务器启动时加载插件,请使用该
--plugin-load-add
选项命名包含它的库文件。
使用此插件加载方法,每次服务器启动时都必须提供该选项。
例如,将这些行放在服务器
my.cnf
文件中:
的[mysqld] 插件的负载加= authentication_windows.dll
修改后
my.cnf
,重新启动服务器以使新设置生效。
或者,要在运行时注册插件,请使用以下语句:
INSTALL PLUGIN authentication_windows SONAME'authentication_windows.dll';
INSTALL
PLUGIN
立即加载插件,并将其注册到
mysql.plugins
系统表中,以使服务器为每个后续的正常启动加载它。
要验证插件安装,请检查
INFORMATION_SCHEMA.PLUGINS
表或使用该
SHOW PLUGINS
语句(请参见
第5.6.2节“获取服务器插件信息”
)。
例如:
MySQL的>SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE '%windows%';
+ ------------------------ + --------------- + | PLUGIN_NAME | PLUGIN_STATUS | + ------------------------ + --------------- + | authentication_windows | ACTIVE | + ------------------------ + --------------- +
如果插件无法初始化,请检查服务器错误日志以获取诊断消息。
要将MySQL帐户与Windows身份验证插件关联,请参阅 使用Windows可插入身份验证 。
用于卸载Windows身份验证插件的方法取决于您的安装方式:
如果您在服务器启动时使用
--plugin-load-add
选项
安装了插件,请在
没有该选项的情况下重新启动服务器。
如果您在运行时使用安装插件
INSTALL PLUGIN
,它将在服务器重新启动
时
保持安装。
要卸载它,请使用
UNINSTALL PLUGIN
:
UNINSTALL PLUGIN authentication_windows;
此外,删除任何设置Windows插件相关系统变量的启动选项。
Windows身份验证插件支持使用MySQL帐户,以便登录到Windows的用户可以连接到MySQL服务器,而无需指定其他密码。 假设服务器在启用服务器端插件的情况下运行,如 安装Windows可插入身份验证中所述 。 一旦DBA启用了服务器端插件并设置帐户以使用它,客户端就可以使用这些帐户进行连接,而无需其他设置。
要在
语句
的
IDENTIFIED WITH
子句中
引用Windows身份验证插件
CREATE
USER
,请使用该名称
authentication_windows
。
假设Windows用户
Rafal
,并
Tasha
应允许连接到MySQL,以及任何用户的
Administrators
或
Power
Users
组。
要进行此设置,请创建一个名为
sql_admin
使用Windows插件进行身份验证
的MySQL帐户
:
CREATE USER sql_admin 通过authentication_windows识别 AS'Rafal,Tasha,管理员,“超级用户”';
插件名称是
authentication_windows
。
AS
关键字
后面的字符串
是身份验证字符串。
它指定Windows用户命名
Rafal
或
Tasha
允许以MySQL用户身份向服务器进行身份验证,该
sql_admin
用户
Administrators
或
Power
Users
组
中的任何Windows用户也是如此
。
后一组名称包含空格,因此必须使用双引号字符引用。
创建
sql_admin
帐户后,登录到Windows的用户可以尝试使用该帐户连接到服务器:
C:\> mysql --user=sql_admin
这里不需要密码。
该
authentication_windows
插件使用Windows安全API来检查哪个Windows用户正在连接。
如果该用户被命名为
Rafal
或
Tasha
,或者是的成员
Administrators
或
Power
Users
组,服务器授予访问权限和客户端进行身份验证为
sql_admin
,有什么权限授予
sql_admin
帐户。
否则,服务器拒绝访问。
Windows身份验证插件的身份验证字符串语法遵循以下规则:
该字符串由一个或多个用逗号分隔的用户映射组成。
每个用户映射将Windows用户或组名与MySQL用户名相关联:
win_user_or_group_name=mysql_user_name
win_user_or_group_name
对于后一种语法,没有
mysql_user_name
给出值,隐式值是由
CREATE USER
语句
创建的MySQL用户
。
因此,这些陈述是等价的:
CREATE USER sql_admin 通过authentication_windows识别 AS'Rafal,Tasha,管理员,“超级用户”'; CREATE USER sql_admin 通过authentication_windows识别 AS'Rafal = sql_admin,Tasha = sql_admin,Administrators = sql_admin, “Power Users”= sql_admin';
值中的每个反斜杠(
'\'
)必须加倍,因为反斜杠是MySQL字符串中的转义字符。
不在双引号内的前导和尾随空格将被忽略。
不带引号
win_user_or_group_name
和
mysql_user_name
值可以包含除等号,逗号或空格之外的任何内容。
如果
使用双引号引用
a
win_user_or_group_name
和or
mysql_user_name
值,则引号之间的所有内容都是值的一部分。
例如,如果名称包含空格字符,则这是必需的。
除双引号和反斜杠外,双引号内的所有字符都是合法的。
要包含任一字符,请使用反斜杠转义它。
win_user_or_group_name
值使用Windows主体的常规语法,无论是本地还是域。
示例(注意反斜杠加倍):
域\\用户 。\\用户 域\\组 。\\组 BUILTIN \\ WellKnownGroup
当服务器调用以验证客户端时,插件会从左到右扫描身份验证字符串,以便用户或组匹配Windows用户。
如果匹配,则插件返回与
mysql_user_name
MySQL服务器
对应的对应项
。
如果没有匹配,则身份验证失败。
用户名匹配优先于组名匹配。
假设命名的Windows用户
win_user
是其成员,
win_group
并且身份验证字符串如下所示:
'win_group = sql_user1,win_user = sql_user2'
当
win_user
连接到MySQL服务器时,to
win_group
和to
都匹配
win_user
。
该插件对用户进行身份验证,
sql_user2
因为更具体的用户匹配优先于组匹配,即使该组首先列在身份验证字符串中。
Windows身份验证始终适用于运行服务器的同一台计算机上的连接。 对于跨计算机连接,两台计算机都必须在Windows Active Directory中注册。 如果它们位于同一Windows域中,则无需指定域名。 也可以允许来自不同域的连接,如下例所示:
CREATE USER sql_accounting 通过authentication_windows识别 AS'SomeDomain \\ Accounting';
这
SomeDomain
是其他域名。
反斜杠字符加倍,因为它是字符串中的MySQL转义字符。
MySQL支持代理用户的概念,客户端可以使用一个帐户连接和验证MySQL服务器,但连接时具有另一个帐户的权限(请参见 第6.2.18节“代理用户” )。 假设您希望Windows用户使用单个用户名进行连接,但是根据其Windows用户和组名称将其映射到特定的MySQL帐户,如下所示:
在
local_user
与
MyDomain\domain_user
本地和域Windows用户应该映射到
local_wlad
MySQL账户。
MyDomain\Developers
域组
中的用户
应映射到
local_dev
MySQL帐户。
本地计算机管理员应映射到
local_admin
MySQL帐户。
要使用此功能,为Windows用户创建连接到代理帐户,并配置该帐户,使用户和用户组映射到相应的MySQL账户(
local_wlad
,
local_dev
,
local_admin
)。
此外,为MySQL帐户授予适合其需要执行的操作的权限。
下面的说明使用
win_proxy
的代理帐户,和
local_wlad
,
local_dev
和
local_admin
为代理账户。
创建代理MySQL帐户:
CREATE USER win_proxy 通过authentication_windows识别 AS'local_user = local_wlad, MyDomain \\ domain_user = local_wlad, MyDomain \\ Developers = local_dev, BUILTIN \\ Administrators = local_admin';
如果您的MySQL安装具有匿名用户,则可能与默认代理用户冲突。 有关此问题的更多信息以及处理它的方法,请参阅 默认代理用户和匿名用户冲突 。
要使代理工作,代理帐户必须存在,因此创建它们:
CREATE USER local_wlad IDENTIFIED BY'wlad_pass'; CREATE USER local_dev IDENTIFIED BY'dev_pass'; CREATE USER local_admin IDENTIFIED BY'admin_pass';
如果您不让任何人知道这些帐户的密码,则其他用户无法使用它们直接连接到MySQL服务器。
您还应该发出
GRANT
声明(未显示),为每个代理帐户授予其所需的权限。
代理帐户必须具有
PROXY
每个代理帐户
的
权限:
授予on_wlad TO win_proxy; 在local_dev上授予代理权限win_proxy; 在local_admin上授予代理权到WIN_proxy;
现在的Windows用户
local_user
,并
MyDomain\domain_user
可以连接到MySQL服务器
win_proxy
和身份验证时,必须在验证字符串,在这种情况下,考虑到帐户的权限,
local_wlad
。
MyDomain\Developers
连接
的
组中
的用户
win_proxy
具有该
local_dev
帐户
的权限
。
BUILTIN\Administrators
组中的
用户
具有该
local_admin
帐户
的权限
。
要配置身份验证,以便所有没有自己的MySQL帐户的Windows用户都通过代理帐户,请
在前面的说明中
替换默认代理用户(
''@''
)
win_proxy
。
有关默认代理用户的信息,请参见
第6.2.18节“代理用户”
。
要在Connector / NET 6.4.4和更高版本中 使用 带有Connector / NET连接字符串 的Windows身份验证插件 ,请参阅 使用Windows本地身份验证插件 。
Windows身份验证插件的附加控制由
authentication_windows_use_principal_name
和
authentication_windows_log_level
系统变量提供。
请参见
第5.1.8节“服务器系统变量”
。
LDAP可插入身份验证是MySQL Enterprise Edition(一种商业产品)中包含的扩展。 要了解有关商业产品的更多信息,请访问 https://www.mysql.com/products/ 。
MySQL企业版支持一种身份验证方法,使MySQL服务器能够使用LDAP(轻量级目录访问协议)通过访问X.500等目录服务来验证MySQL用户。 MySQL使用LDAP来获取用户,凭证和组信息。
LDAP可插入身份验证提供以下功能:
外部身份验证:LDAP身份验证使MySQL Server能够接受来自LDAP目录中MySQL授权表之外定义的用户的连接。
代理用户支持:LDAP身份验证可以根据外部用户所属的LDAP组,向MySQL返回与客户端程序传递的外部用户名不同的用户名。
这意味着LDAP插件可以返回MySQL用户,该用户定义外部LDAP身份验证用户应具有的权限。
例如,名为的LDAP用户
joe
可以连接并有一个名为MySQL用户的权限
developer
,如果用于LDAP组
joe
是
developer
。
安全性:使用TLS,与LDAP服务器的连接可以是安全的。
下表显示了插件和库文件名。
文件名后缀可能与您的系统不同。
这些文件必须位于由
plugin_dir
系统变量
。
表6.19 LDAP身份验证的插件和库名称
插件或文件 | 插件或文件名 |
---|---|
服务器端插件名称 | authentication_ldap_sasl
,
authentication_ldap_simple
|
客户端插件名称 | authentication_ldap_sasl_client
,
mysql_clear_password
|
库文件名 | authentication_ldap_sasl.so
,
authentication_ldap_sasl_client.so
,
authentication_ldap_simple.so
|
库文件仅包含
身份验证插件。
客户端
插件内置于
客户端库中。
authentication_ldap_
XXX
mysql_clear_password
libmysqlclient
两个服务器端LDAP插件均使用特定的客户端插件:
服务器端
authentication_ldap_simple
插件执行简单的LDAP身份验证。
对于使用此插件的帐户的连接,客户端程序使用客户端
mysql_clear_password
插件,该插件将密码作为明文发送到服务器。
没有使用密码散列或加密,因此建议在MySQL客户端和服务器之间建立安全连接以防止密码泄露。
服务器端
authentication_ldap_sasl
插件执行基于SASL的LDAP身份验证。
对于使用此插件的帐户的连接,客户端程序使用客户端
authentication_ldap_sasl_client
插件。
客户端和服务器端SASL LDAP插件使用SASL消息在LDAP协议中安全传输凭据,以避免在MySQL客户端和服务器之间发送明文密码。
以下部分提供特定于LDAP可插入身份验证的安装和使用信息:
有关MySQL中可插入身份验证的一般信息,请参见
第6.2.17节“可插入身份验证”
。
有关
mysql_clear_password
插件的
信息
,请参见
第6.4.1.4节“客户端明文可插入认证”
。
有关代理用户信息,请参见
第6.2.18节“代理用户”
。
如果您的系统支持PAM并允许LDAP作为PAM身份验证方法,则使用LDAP进行MySQL用户身份验证的另一种方法是使用服务器端
authentication_pam
插件。
请参见
第6.4.1.5节“PAM可插拔认证”
。
要对MySQL使用LDAP可插入身份验证,必须满足以下先决条件:
必须有LDAP服务器才能与LDAP身份验证插件进行通信。
要由MySQL进行身份验证的LDAP用户必须存在于LDAP服务器管理的目录中。
LDAP客户端库必须在使用服务器端
authentication_ldap_sasl
或
authentication_ldap_simple
插件的
系统上可用
。
目前,受支持的库是Windows本机LDAP库,或非Windows系统上的OpenLDAP库。
要使用基于SASL的LDAP身份验证:
必须将LDAP服务器配置为与SASL服务器通信。
必须在使用客户端
authentication_ldap_sasl_client
插件的
系统上提供SASL客户端库
。
目前,唯一受支持的库是Cyrus SASL库。
本节概述了MySQL和LDAP如何协同工作以验证MySQL用户。 有关如何设置MySQL帐户以使用特定LDAP身份验证插件的示例,请参阅 使用LDAP可插入身份验证 。
客户端连接到MySQL服务器,提供MySQL客户端用户名和LDAP密码:
对于简单的LDAP身份验证,客户端和服务器端插件将密码作为明文进行通信。
对于基于SASL的LDAP身份验证,客户端和服务器端插件使用SASL消息在LDAP协议中安全传输凭据,以避免在MySQL客户端和服务器之间发送明文密码。
如果客户端用户名和主机名不匹配MySQL帐户,则拒绝连接。
如果存在匹配的MySQL帐户,则会发生针对LDAP的身份验证。 LDAP服务器查找与用户匹配的条目,并根据LDAP密码对条目进行身份验证:
如果MySQL帐户命名LDAP用户可分辨名称(DN),则LDAP身份验证使用该值和客户端提供的LDAP密码。
(要将LDAP用户DN与MySQL帐户关联,请
BY
在
CREATE
USER
创建帐户
的
语句中
包含
指定身份验证字符串
的
子句
。)
如果MySQL帐户没有命名LDAP用户DN,则LDAP身份验证使用客户端提供的用户名和LDAP密码。 在这种情况下,身份验证插件首先使用根DN和密码作为凭据绑定到LDAP服务器,以根据客户端用户名查找用户DN,然后根据LDAP密码对该用户DN进行身份验证。 如果根DN和密码设置为不正确的值,或者为空(未设置)且LDAP服务器不允许匿名连接,则使用根凭据进行此绑定将失败。
如果LDAP服务器未找到匹配项或多个匹配项,则身份验证将失败并拒绝客户端连接。
如果LDAP服务器找到单个匹配项,则LDAP身份验证成功(假设密码正确),LDAP服务器返回LDAP条目,并且身份验证插件根据该条目确定经过身份验证的用户的名称:
如果LDAP条目具有组属性(默认情况下为该
cn
属性),则插件将其值作为经过身份验证的用户名返回。
如果LDAP条目没有组属性,则身份验证插件将客户端用户名作为经过身份验证的用户名返回。
MySQL服务器将客户端用户名与经过身份验证的用户名进行比较,以确定是否为客户端会话进行了代理:
如果名称相同,则不会发生代理:与客户端用户名匹配的MySQL帐户用于权限检查。
如果名称不同,则会发生代理:MySQL查找与经过身份验证的用户名匹配的帐户。 该帐户成为代理用户,用于进行权限检查。 与客户端用户名匹配的MySQL帐户被视为外部代理用户。
本节介绍如何安装LDAP身份验证插件。 有关安装插件的一般信息,请参见 第5.6.1节“安装和卸载插件” 。
要使服务器可以使用,插件库文件必须位于MySQL插件目录(
plugin_dir
系统变量
指定的目录
)中。
如有必要,通过设置
plugin_dir
服务器启动时
的值来配置插件目录位置
。
服务器端插件库文件基名是
authentication_ldap_sasl
和
authentication_ldap_simple
。
文件名后缀因平台
.so
而异
(例如,
对于Unix和类Unix系统,
.dll
对于Windows)。
要在服务器启动时加载插件,请使用
--plugin-load-add
选项命名包含它们的库文件。
使用此插件加载方法,每次服务器启动时都必须提供选项。
另外,为要配置的任何插件提供的系统变量指定值。
每个服务器端LDAP插件都公开一组系统变量,以便配置其操作。 设置其中大部分是可选的,但您必须设置指定LDAP服务器主机的变量(以便插件知道连接的位置)和LDAP绑定操作的基本专有名称(以限制搜索范围并获得更快的搜索)。 有关所有LDAP系统变量的详细信息,请参见 第6.4.1.11节“可插入的认证系统变量” 。
要加载插件并为LDAP绑定操作设置LDAP服务器主机和基本专有名称,请在
my.cnf
文件中
放置这些行
(
.so
根据需要
调整
平台
的
后缀):
的[mysqld] 插件的负载加= authentication_ldap_sasl.so authentication_ldap_sasl_server_host = 127.0.0.1 authentication_ldap_sasl_bind_base_dn = “DC =例如,DC = COM” 插件的负载加= authentication_ldap_simple.so authentication_ldap_simple_server_host = 127.0.0.1 authentication_ldap_simple_bind_base_dn = “DC =例如,DC = COM”
修改后
my.cnf
,重新启动服务器以使新设置生效。
或者,要在运行时注册插件,请使用这些语句(
.so
根据需要
调整
后缀):
INSTALL PLUGIN authentication_ldap_sasl SONAME'authentication_ldap_sasl.so'; INSTALL PLUGIN authentication_ldap_simple SONAME'authentication_ldap_simple.so';
INSTALL
PLUGIN
立即加载插件,并将其注册到
mysql.plugins
系统表中,以使服务器为每个后续的正常启动加载它。
在运行时安装插件后,它们的系统变量可用,您可以将它们的设置添加到
my.cnf
文件中,以配置插件以便后续重新启动。
例如:
的[mysqld] authentication_ldap_sasl_server_host = 127.0.0.1 authentication_ldap_sasl_bind_base_dn = “DC =例如,DC = COM” authentication_ldap_simple_server_host = 127.0.0.1 authentication_ldap_simple_bind_base_dn = “DC =例如,DC = COM”
修改后
my.cnf
,重新启动服务器以使新设置生效。
或者,要在运行时设置和持久化值,请使用以下语句:
SET PERSIST authentication_ldap_sasl_server_host ='127.0.0.1'; SET PERSIST authentication_ldap_sasl_bind_base_dn ='dc = example,dc = com'; SET PERSIST authentication_ldap_simple_server_host ='127.0.0.1'; SET PERSIST authentication_ldap_simple_bind_base_dn ='dc = example,dc = com';
SET
PERSIST
设置正在运行的MySQL实例的值。
它还会保存该值,使其用于后续服务器重新启动。
要更改正在运行的MySQL实例的值而不保存它以便后续重新启动,请使用
GLOBAL
关键字而不是
PERSIST
。
请参见
第13.7.5.1节“变量赋值的SET语法”
。
要验证插件安装,请检查
INFORMATION_SCHEMA.PLUGINS
表或使用该
SHOW PLUGINS
语句(请参见
第5.6.2节“获取服务器插件信息”
)。
例如:
MySQL的>SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE '%ldap%';
+ ---------------------------- + -------- + | PLUGIN_NAME | PLUGIN_STATUS | + ---------------------------- + -------- + | authentication_ldap_sasl | ACTIVE | | authentication_ldap_simple | ACTIVE | + ---------------------------- + -------- +
如果插件无法初始化,请检查服务器错误日志以获取诊断消息。
要将MySQL帐户与LDAP插件关联,请参阅 使用LDAP可插入身份验证 。
在运行启用了SELinux的EL6或EL的系统上,需要更改SELinux策略以使MySQL LDAP插件能够与LDAP服务通信:
创建
mysqlldap.te
包含以下内容
的文件
:
模块mysqlldap 1.0; 要求{ 输入ldap_port_t; 输入mysqld_t; class tcp_socket name_connect; } #============= mysqld_t ============== 允许mysqld_t ldap_port_t:tcp_socket name_connect;
将安全策略模块编译为二进制表示:
checkmodule -M -m mysqlldap.te -o mysqlldap.mod
创建SELinux策略模块包:
semodule_package -m mysqlldap.mod -o mysqlldap.pp
安装模块包:
semodule -i mysqlldap.pp
完成SELinux策略更改后,重新启动MySQL服务器:
service mysqld restart
用于卸载LDAP身份验证插件的方法取决于您安装它们的方式:
如果您在服务器启动时使用
--plugin-load-add
选项
安装了插件
,请重新启动没有这些选项的服务器。
如果您在运行时使用安装插件
INSTALL PLUGIN
,它们将在服务器重新启动
时
保持安装状态。
要卸载它们,请使用
UNINSTALL PLUGIN
:
UNINSTALL PLUGIN authentication_ldap_sasl; UNINSTALL PLUGIN authentication_ldap_simple;
此外,从
my.cnf
文件中
删除
任何设置LDAP插件相关系统变量的启动选项。
如果您曾经
SET
PERSIST
保留LDAP系统变量,请使用
RESET PERSIST
删除设置。
本节介绍如何使用LDAP可插入身份验证启用MySQL帐户连接到MySQL服务器。 假设服务器正在运行,并启用了相应的服务器端插件,如 安装LDAP可插入身份验证中所述 ,并且客户端主机上提供了相应的客户端插件。
本节不介绍LDAP配置或管理。 假设您熟悉这些主题。
两个服务器端LDAP插件均使用特定的客户端插件:
服务器端
authentication_ldap_simple
插件执行简单的LDAP身份验证。
对于使用此插件的帐户的连接,客户端程序使用客户端
mysql_clear_password
插件,该插件将密码作为明文发送到服务器。
没有使用密码散列或加密,因此建议在MySQL客户端和服务器之间建立安全连接以防止密码泄露。
服务器端
authentication_ldap_sasl
插件执行基于SASL的LDAP身份验证。
对于使用此插件的帐户的连接,客户端程序使用客户端
authentication_ldap_sasl_client
插件。
客户端和服务器端SASL LDAP插件使用SASL消息在LDAP协议中安全传输凭据,以避免在MySQL客户端和服务器之间发送明文密码。
MySQL用户的LDAP身份验证的总体要求:
必须有每个要进行身份验证的用户的LDAP目录条目。
必须有一个MySQL用户帐户,该帐户指定服务器端LDAP身份验证插件,并可选择指定关联的LDAP用户可分辨名称(DN)。
(要将LDAP用户DN与MySQL帐户相关联,请
BY
在
CREATE USER
创建帐户
的
语句中
包含一个
子句
。)如果帐户未指定LDAP字符串,则LDAP身份验证使用客户端指定的用户名来查找LDAP条目。
客户端程序使用适用于MySQL帐户使用的服务器端身份验证插件的连接方法进行连接。
对于LDAP身份验证,连接需要MySQL用户名和LDAP密码。
此外,对于使用服务器端
authentication_ldap_simple
插件的
帐户,可以使用
--enable-cleartext-plugin
启用客户端
mysql_clear_password
插件
的
选项
调用客户端程序
。
这里的说明假设以下情形:
MySQL用户
betsy
和
分别
boris
对
betsy_ldap
和/或
LDAP条目进行身份验证
boris_ldap
。
(MySQL和LDAP用户名没有必要不同。在本讨论中使用不同的名称有助于阐明操作上下文是MySQL还是LDAP。)
LDAP条目使用该
uid
属性指定用户名。
这可能因LDAP服务器而异。
某些LDAP服务器将该
cn
属性用于用户名而不是
uid
。
要更改属性,请相应地修改
authentication_ldap_simple_user_search_attr
或
authentication_ldap_sasl_user_search_attr
系统变量。
这些LDAP条目在LDAP服务器管理的目录中可用,以提供唯一标识每个用户的可分辨名称值:
UID = betsy_ldap,OU =人民,DC =例如,DC = COM UID = boris_ldap,OU =人民,DC =例如,DC = COM
CREATE
USER
创建MySQL帐户的语句在
BY
子句中
命名为LDAP用户
,以指示MySQL帐户对哪个LDAP条目进行身份验证。
设置使用LDAP身份验证的帐户的说明取决于使用的服务器端LDAP插件。
要为简单LDAP身份验证配置MySQL帐户,该
CREATE
USER
语句指定
authentication_ldap_simple
插件,并可选择命名LDAP用户可分辨名称(DN):
创建用户user
使用authentication_ldap_simple进行身份识别 [BY'LDAP user DN
'];
假设MySQL用户
betsy
在LDAP目录中有此条目:
UID = betsy_ldap,OU =人民,DC =例如,DC = COM
然后创建MySQL帐户的语句
betsy
如下所示:
创建用户'betsy'@'localhost' 使用authentication_ldap_simple进行身份识别 BY'uid = betsy_ldap,ou = People,dc = example,dc = com';
BY
子句中
指定的身份验证字符串
不包含LDAP密码。
这必须由客户端用户在连接时提供。
客户端通过提供MySQL用户名和LDAP密码以及启用客户端
mysql_clear_password
插件
来连接到MySQL服务器
:
shell>mysql --user=betsy --password --enable-cleartext-plugin
输入密码:
betsy_password
(betsy_ldap LDAP password)
客户端
mysql_clear_password
身份验证插件保持密码不变,因此客户端程序将其作为明文发送到MySQL服务器。
这使密码可以原样传递给LDAP服务器。
在没有SASL的情况下使用服务器端LDAP库需要使用明文密码,但在某些配置中可能存在安全问题。
这些措施将风险降至最低:
为了
mysql_clear_password
不太可能
无意中使用
插件,MySQL客户端必须明确启用它(例如,使用该
--enable-cleartext-plugin
选项)。
请参见
第6.4.1.4节“客户端明文可插拔认证”
。
为避免在
mysql_clear_password
启用插件时
密码暴露
,MySQL客户端应使用加密连接连接到MySQL服务器。
请参见
第6.3.1节“配置MySQL以使用加密连接”
。
身份验证过程如下:
该客户端插件将
betsy
和
betsy_password
作为到MySQL服务器的客户端的用户名和密码,LDAP。
连接尝试与
'betsy'@'localhost'
帐户
匹配
。
服务器端LDAP插件发现此帐户具有
'uid=betsy_ldap,ou=People,dc=example,dc=com'
用于命名LDAP用户DN
的身份验证字符串
。
该插件将此字符串和LDAP密码发送到LDAP服务器。
LDAP服务器查找LDAP条目
betsy_ldap
并且密码匹配,因此LDAP身份验证成功。
LDAP条目没有组属性,因此服务器端插件将客户端用户名(
betsy
)作为经过身份验证的用户返回。
这是客户端提供的相同用户名,因此不会发生代理,客户端会话使用该
'betsy'@'localhost'
帐户进行权限检查。
如果匹配的LDAP条目包含组属性,则该属性值将是经过身份验证的用户名,如果值不同
betsy
,则会发生代理。
有关使用组属性的示例,请参阅
使用代理进行LDAP身份验证
。
如果该
CREATE
USER
语句不包含
BY
指定
betsy_ldap
LDAP专有名称的
子句
,则认证尝试将使用客户端提供的用户名(在本例中
betsy
)。
如果没有LDAP条目
betsy
,则身份验证将失败。
要为SASL LDAP身份验证配置MySQL帐户,该
CREATE
USER
语句指定
authentication_ldap_sasl
插件,并可选择命名LDAP用户可分辨名称(DN):
创建用户user
使用authentication_ldap_sasl识别 [BY'LDAP user DN
'];
假设MySQL用户
boris
在LDAP目录中有此条目:
UID = boris_ldap,OU =人民,DC =例如,DC = COM
然后创建MySQL帐户的语句
boris
如下所示:
创建用户'boris'@'localhost' 使用authentication_ldap_sasl识别 BY'uid = boris_ldap,ou = People,dc = example,dc = com';
BY
子句中
指定的身份验证字符串
不包含LDAP密码。
这必须由客户端用户在连接时提供。
客户端通过提供MySQL用户名和LDAP密码连接到MySQL服务器:
shell>mysql --user=boris --password
输入密码:
boris_password
(boris_ldap LDAP password)
对于服务器端
authentication_ldap_sasl
插件,客户端使用客户端
authentication_ldap_sasl_client
插件。
如果客户端程序找不到客户端插件,请指定一个
--plugin-dir
选项,
该
选项命名安装插件库文件的目录。
除了客户端和服务器端SASL LDAP插件使用SASL消息在LDAP协议中安全传输凭据之外,
身份验证过程
boris
类似于之前针对
betsy
简单LDAP身份验证
所描述
的身份验证过程
,以避免在两者之间发送明文密码。 MySQL客户端和服务器。
LDAP身份验证插件允许提供用户DN信息的身份验证字符串以
+
前缀字符
开头
:
如果没有
+
字符,则认证字符串值将被视为未经修改。
如果身份验证字符串以此开头
+
,则插件会根据客户端发送的用户名以及身份验证字符串中指定的DN(已
+
删除)
构造完整的用户DN值
。
在构造的DN中,客户端用户名将成为指定LDAP用户名的属性的值。
这是
uid
默认情况下;
要更改属性,请相应地修改
authentication_ldap_simple_user_search_attr
或
authentication_ldap_sasl_user_search_attr
系统变量。
身份验证字符串存储为
mysql.user
系统表,在认证之前即时构建完整的用户DN。
此帐户身份验证字符串
+
在开头没有,因此它被视为完整用户DN:
创建用户'baldwin' 使用authentication_ldap_simple进行身份识别 BY'uid = admin,ou = People,dc = example,dc = com';
客户端使用帐户(
baldwin
)中
指定的用户名进行连接
。
在这种情况下,不使用该名称,因为身份验证字符串没有前缀,因此完全指定了用户DN。
此帐户身份验证字符串
+
在开头有,因此它只是用户DN的一部分:
创建用户'会计' 使用authentication_ldap_simple进行身份识别 BY'+ ou = People,dc = example,dc = com';
客户端使用account(
accounting
)中
指定的用户名连接
,在这种情况下
,该用户名
uid
与身份验证字符串一起
用作
构造用户DN
的
属性:
uid=accounting,ou=People,dc=example,dc=com
前面示例中的帐户具有非空用户名,因此客户端始终使用帐户定义中指定的相同名称连接到MySQL服务器。
如果帐户具有空的用户名,例如
LDAP验证和代理中
''@'%'
描述
的通用匿名
代理帐户
,则客户端可能会使用不同的用户名连接到MySQL服务器。
但原理是相同的:如果
认证字符串以此
开头
,则插件使用客户端发送的用户名和认证字符串来构造用户DN。
+
LDAP身份验证插件支持代理,使用户能够以一个用户身份连接到MySQL服务器,但却拥有不同用户的权限。 本节介绍基本的LDAP插件代理支持。 LDAP插件还支持组首选项和代理用户映射的规范; 请参阅 LDAP身份验证组首选项和映射规范 。
此处描述的身份验证方案使用基于映射LDAP组属性值的代理连接将使用LDAP进行身份验证的MySQL用户连接到定义不同权限集的其他MySQL帐户。 用户不直接通过定义权限的帐户进行连接。 相反,它们通过使用LDAP进行身份验证的默认代理用户进行连接,以便将所有外部登录映射到拥有权限的MySQL帐户。 任何连接的用户都映射到其中一个MySQL帐户,其权限决定了外部用户允许的数据库操作。
这里的说明假设以下情形:
LDAP条目分别使用
uid
和
cn
属性指定用户名和组值。
要使用不同的用户和组属性名称,请设置适当的系统变量以配置插件:
用于
authentication_ldap_simple
:设置
authentication_ldap_simple_user_search_attr
和
authentication_ldap_simple_group_search_attr
。
用于
authentication_ldap_sasl
:设置
authentication_ldap_sasl_user_search_attr
和
authentication_ldap_sasl_group_search_attr
。
这些LDAP条目在LDAP服务器管理的目录中可用,以提供唯一标识每个用户的可分辨名称值:
UID =芭莎,OU =人民,DC =例如,DC = COM,CN =会计 UID =罗勒,OU =人民,DC =例如,DC = COM,CN = front_office
组属性值将成为经过身份验证的用户名,因此他们将
代理
accounting
和
front_office
代理帐户
命名
。
这些示例假定使用SASL LDAP身份验证。 对简单的LDAP身份验证进行适当的调整。
创建默认代理MySQL帐户:
创建用户 ''@'%' 通过authentication_ldap_simple识别;
代理帐户定义没有
用于命名LDAP用户DN的子句。
从而:
BY
'
auth_string
'
客户端连接时,客户端用户名将用作要搜索的LDAP用户名。
匹配的LDAP条目应包括一个组属性,用于命名代理的MySQL帐户,该帐户定义客户端应具有的权限。
如果您的MySQL安装具有匿名用户,则可能与默认代理用户冲突。 有关此问题的更多信息以及处理它的方法,请参阅 默认代理用户和匿名用户冲突 。
创建代理帐户并授予其权限:
CREATE USER'accounting'@'localhost'ACCOUNT LOCK; CREATE USER'front_office'@'localhost'ACCOUNT LOCK; 授予所有特权 在accountingdb。* ''accounting'@'localhost'; 授予所有特权 在frontdb。* TO'front_office'@'localhost';
将
PROXY
权限
授予
每个代理帐户的代理帐户:
授予代理权 ON'accounting'@'localhost' 至 ''@'%'; 授予代理权 ON'front_office'@'localhost' 至 ''@'%';
使用
mysql
命令行客户端连接到MySQL服务器
basha
。
shell>mysql --user=basha --password
输入密码:
basha_password
(basha LDAP password)
身份验证发生如下:
''@'%'
对于客户端用户,
服务器使用该
帐户
验证连接
basha
。
匹配的LDAP条目是:
UID =芭莎,OU =人民,DC =例如,DC = COM,CN =会计
匹配的LDAP条目具有组属性
cn=accounting
,因此
accounting
成为经过身份验证的用户。
经过身份验证的用户与客户端用户名不同
basha
,其结果
basha
被视为代理
accounting
,并
basha
承担
accounting
帐户
的权限
。
以下查询应返回输出,如下所示:
MySQL的> SELECT USER(), CURRENT_USER(), @@proxy_user;
+ ----------------- + ---------------------- + -------- ------ +
| USER()| CURRENT_USER()| @@ proxy_user |
+ ----------------- + ---------------------- + -------- ------ +
| basha @ localhost | accounting @ localhost | ''@'%'|
+ ----------------- + ---------------------- + -------- ------ +
这表明
basha
使用授予
accounting
MySQL帐户
的权限
,并且代理通过默认代理用户帐户发生。
现在连接
basil
:
shell>mysql --user=basil --password
输入密码:
basil_password
(basil LDAP password)
身份验证过程
basil
与之前描述的类似
basha
:
''@'%'
对于客户端用户,
服务器使用该
帐户
验证连接
basil
。
匹配的LDAP条目是:
UID =罗勒,OU =人民,DC =例如,DC = COM,CN = front_office
匹配的LDAP条目具有组属性
cn=front_office
,因此
front_office
成为经过身份验证的用户。
经过身份验证的用户与客户端用户名不同
basil
,其结果
basil
被视为代理
front_office
,并
basil
承担
front_office
帐户
的权限
。
以下查询应返回输出,如下所示:
MySQL的> SELECT USER(), CURRENT_USER(), @@proxy_user;
+ ----------------- + ------------------------ + ------ -------- +
| USER()| CURRENT_USER()| @@ proxy_user |
+ ----------------- + ------------------------ + ------ -------- +
| 罗勒@ localhost | front_office @ localhost | ''@'%'|
+ ----------------- + ------------------------ + ------ -------- +
这表明
basil
使用授予
front_office
MySQL帐户
的权限
,并且代理通过默认代理用户帐户发生。
如 使用代理的LDAP身份验证中 所述 ,基本LDAP身份验证代理的工作原理是插件使用LDAP服务器返回的第一个组名作为MySQL代理用户帐户名。 如果LDAP服务器返回多个名称,或者除组名称以外的任何名称作为代理用户名,则此简单功能不允许指定要使用的组名称的任何首选项。
从MySQL 8.0.14开始,对于使用LDAP身份验证的MySQL帐户,身份验证字符串可以指定以下信息以实现更大的代理灵活性:
按优先顺序排列的组列表,以便插件使用列表中与LDAP服务器返回的组匹配的第一个组名。
从组名到代理用户名的映射,这样匹配时的组名可以提供指定的名称以用作代理用户。 这提供了使用组名作为代理用户的替代方法。
请考虑以下MySQL代理帐户定义:
创建用户 ''@'%' 使用authentication_ldap_sasl识别 BY'+ ou = People,dc = example,dc = com#grp1 = usera,grp2,grp3 = userc';
身份验证字符串具有
ou=People,dc=example,dc=com
以
+
字符
为前缀
的用户DN后缀
。
因此,如
LDAP身份验证用户DN后缀
中所述,完整用户DN是根据指定的用户DN后缀以及客户端用户名作为
uid
属性
构造的
。
身份验证字符串的剩余部分以开头
#
,表示组首选项和映射信息的开头。
验证字符串的这一部分列出组名的顺序
grp1
,
grp2
,
grp3
。
LDAP插件将该列表与LDAP服务器返回的组名称集进行比较,以列表顺序查找与返回的名称匹配的列表。
插件使用第一个匹配,或者如果没有匹配,则认证失败。
假设LDAP服务器返回组
grp3
,
grp2
和
grp7
。
LDAP插件使用
grp2
是因为它是认证字符串中匹配的第一个组,即使它不是LDAP服务器返回的第一个组。
如果LDAP服务器返回
grp4
,
grp2
和
grp1
,插件使用
grp1
即使
grp2
也匹配。
grp1
优先级高于
grp2
认证字符串前面列出
的优先级
。
假设插件找到了组名匹配,它会执行从该组名到MySQL代理用户名的映射(如果有)。 对于示例代理帐户,映射如下所示:
如果匹配的组名是
grp1
或
grp3
,则它们在认证字符串中
分别
与用户名
usera
和
userc
。
该插件使用相应的关联用户名作为代理用户名。
如果匹配的组名称是
grp2
,则认证字符串中没有关联的用户名。
该插件
grp2
用作代理用户名。
如果LDAP服务器以DN格式返回组,则LDAP插件会解析组DN以从中提取组名称。
要指定LDAP组首选项和映射信息,这些原则适用:
开始组首选项并使用
#
前缀字符
映射身份验证字符串的一部分
。
组首选项和映射规范是一个或多个项目的列表,以逗号分隔。
每个项目都有表格
或
。
项目应按组名称首选项顺序列出。
对于插件选择的组名称作为LDAP服务器返回的组名称集合,这两种语法的效果如下:
group_name
=user_name
group_name
对于指定为
(具有用户名)的项目,组名称映射到用户名,该用户名用作MySQL代理用户名。
group_name
=user_name
对于指定为
group_name
(没有用户名)的项目,组名称用作MySQL代理用户名。
要引用包含特殊字符(如空格)的组或用户名,请用双引号(
"
)字符将其括起来。
例如,如果项目的组和用户名为
my group
name
和
my user name
,则必须使用引号将其写入组映射中:
“我的群组名称”=“我的用户名”
如果项目的组和用户名称
my_group_name
和
my_user_name
(其中不包含特殊字符),它可能但不一定使用引号写入。
以下任何一项都是有效的:
my_group_name = my_user_name my_group_name = “my_user_name” “my_group_name”= my_user_name “my_group_name”= “my_user_name”
要转义字符,请在其前面加一个反斜杠(
\
)。
这特别适用于包含文字双引号或反斜杠,否则不包括字面意思。
验证字符串中不需要存在用户DN,但如果存在,则它必须位于组首选项和映射部分之前。
用户DN可以是完整用户DN,也可以是带有
+
前缀字符
的用户DN后缀
。
在
mysql_no_login
服务器端身份验证插件阻止所有客户端连接到使用它的任何账户。
此类插件的用例包括代理帐户,这些帐户永远不允许直接登录,但只能通过代理帐户和帐户访问,这些帐户和帐户必须能够以提升的权限执行存储的程序和视图,而不会将这些权限暴露给普通用户。
下表显示了插件和库文件名。
文件名后缀可能与您的系统不同。
该文件必须位于
plugin_dir
系统变量
指定的目录中
。
以下部分提供了特定于无登录可插入身份验证的安装和使用信息:
有关MySQL中可插入身份验证的一般信息,请参见 第6.2.17节“可插入身份验证” 。 有关代理用户信息,请参见 第6.2.18节“代理用户” 。
本节介绍如何安装无登录身份验证插件。 有关安装插件的一般信息,请参见 第5.6.1节“安装和卸载插件” 。
要使服务器可以使用,插件库文件必须位于MySQL插件目录(
plugin_dir
系统变量
指定的目录
)中。
如有必要,通过设置
plugin_dir
服务器启动时
的值来配置插件目录位置
。
插件库文件基本名称是
mysql_no_login
。
文件名后缀因平台
.so
而异
(例如,
对于Unix和类Unix系统,
.dll
对于Windows)。
要在服务器启动时加载插件,请使用该
--plugin-load-add
选项命名包含它的库文件。
使用此插件加载方法,每次服务器启动时都必须提供该选项。
例如,将这些行放在服务器
my.cnf
文件中(
.so
根据需要
调整
平台
的
后缀):
的[mysqld] 插件的负载加= mysql_no_login.so
修改后
my.cnf
,重新启动服务器以使新设置生效。
或者,要在运行时注册插件,请使用此语句(
.so
根据需要
调整
后缀):
INSTALL PLUGIN mysql_no_login SONAME'mysql_no_login.so';
INSTALL
PLUGIN
立即加载插件,并将其注册到
mysql.plugins
系统表中,以使服务器为每个后续的正常启动加载它。
要验证插件安装,请检查
INFORMATION_SCHEMA.PLUGINS
表或使用该
SHOW PLUGINS
语句(请参见
第5.6.2节“获取服务器插件信息”
)。
例如:
MySQL的>SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE '%login%';
+ ---------------- + --------------- + | PLUGIN_NAME | PLUGIN_STATUS | + ---------------- + --------------- + | mysql_no_login | ACTIVE | + ---------------- + --------------- +
如果插件无法初始化,请检查服务器错误日志以获取诊断消息。
要将MySQL帐户与no-login插件关联,请参阅 使用无登录可插入身份验证 。
用于卸载无登录身份验证插件的方法取决于您的安装方式:
如果您在服务器启动时使用
--plugin-load-add
选项
安装了插件,请在
没有该选项的情况下重新启动服务器。
如果您在运行时使用安装插件
INSTALL PLUGIN
,它将在服务器重新启动
时
保持安装。
要卸载它,请使用
UNINSTALL PLUGIN
:
UNINSTALL PLUGIN mysql_no_login;
本节介绍如何使用禁用登录身份验证插件来阻止从MySQL客户端程序到服务器的连接。 假设服务器在启用服务器端插件的情况下运行,如 安装无登录可插入身份验证中所述 。
要在
语句
的
IDENTIFIED WITH
子句中
引用无登录身份验证插件
CREATE
USER
,请使用该名称
mysql_no_login
。
使用身份验证的帐户
mysql_no_login
可以用作
DEFINER
存储的程序和视图对象。
如果此类对象定义还包括
SQL SECURITY DEFINER
,则使用该帐户的权限执行。
DBA可以使用此行为来提供对仅通过良好控制的接口公开的机密或敏感数据的访问。
以下示例简要说明了这些原则。
它定义了一个不允许客户端连接的帐户,并将与之关联的视图仅公开
mysql.user
系统表的
某些列
:
创建数据库nologindb; 创建用户'nologin'@'localhost' 用mysql_no_login识别; 全部授权nologindb。* TO'nologin'@'localhost'; 在mysql.user上选择GRANT TO'nologin'@'localhost'; CREATE DEFINER ='nologin'@'localhost' SQL安全定义器 查看nologindb.myview AS SELECT用户,主机FROM mysql.user;
要为普通用户提供对视图的受保护访问,请执行以下操作:
在nologindb.myview上选择GRANT 到'普通用户'@'localhost';
现在,普通用户可以使用该视图访问它所呈现的有限信息:
SELECT * FROM nologindb.myview;
用户尝试访问除视图公开的列以外的列会导致错误,所有尝试从未授予对其访问权限的用户中选择视图也是如此。
由于
nologin
无法直接使用
该
帐户,因此设置其使用的对象所需的操作必须由
root
具有创建对象和设置
DEFINER
值
所需特权的帐户或类似帐户
执行
。
使用身份验证的帐户
mysql_no_login
可以用作代理帐户的代理基本用户:
- 创建代理帐户 创建用户'proxy_base'@'localhost' 用mysql_no_login识别; - 授予代理帐户的权限 格兰特...... 上 ... 到'proxy_base'@'localhost'; - 允许real_user成为代理帐户的代理帐户 授予代理权 在'proxy_base'@'localhost' 到'real_user'@'localhost';
这使客户端能够通过代理帐户(
real_user
)
访问MySQL,
但不能通过直接连接代理用户(
proxy_base
)
来绕过代理机制
。
服务器端
auth_socket
身份验证插件对通过Unix套接字文件从本地主机连接的客户
端进行
身份验证。
该插件使用
SO_PEERCRED
套接字选项来获取有关运行客户端程序的用户的信息。
因此,该插件只能用于支持该
SO_PEERCRED
选项的
系统
,例如Linux。
可以将此插件的源代码作为一个相对简单的示例进行检查,演示如何编写可加载的身份验证插件。
下表显示了插件和库文件名。
该文件必须位于
plugin_dir
系统变量
指定的目录中
。
以下部分提供了特定于套接字可插入身份验证的安装和使用信息:
有关MySQL中可插入身份验证的一般信息,请参见 第6.2.17节“可插入身份验证” 。
本节介绍如何安装套接字认证插件。 有关安装插件的一般信息,请参见 第5.6.1节“安装和卸载插件” 。
要使服务器可以使用,插件库文件必须位于MySQL插件目录(
plugin_dir
系统变量
指定的目录
)中。
如有必要,通过设置
plugin_dir
服务器启动时
的值来配置插件目录位置
。
要在服务器启动时加载插件,请使用该
--plugin-load-add
选项命名包含它的库文件。
使用此插件加载方法,每次服务器启动时都必须提供该选项。
例如,将这些行放在服务器
my.cnf
文件中:
的[mysqld] 插件的负载加= auth_socket.so
修改后
my.cnf
,重新启动服务器以使新设置生效。
或者,要在运行时注册插件,请使用以下语句:
INSTALL PLUGIN auth_socket SONAME'auth_socket.so';
INSTALL
PLUGIN
立即加载插件,并将其注册到
mysql.plugins
系统表中,以使服务器为每个后续的正常启动加载它。
要验证插件安装,请检查
INFORMATION_SCHEMA.PLUGINS
表或使用该
SHOW PLUGINS
语句(请参见
第5.6.2节“获取服务器插件信息”
)。
例如:
MySQL的>SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE '%socket%';
+ ------------- + --------------- + | PLUGIN_NAME | PLUGIN_STATUS | + ------------- + --------------- + | auth_socket | ACTIVE | + ------------- + --------------- +
如果插件无法初始化,请检查服务器错误日志以获取诊断消息。
要将MySQL帐户与套接字插件关联,请参阅 使用套接字可插入身份验证 。
用于卸载套接字认证插件的方法取决于您的安装方式:
如果您在服务器启动时使用
--plugin-load-add
选项
安装了插件,请在
没有该选项的情况下重新启动服务器。
如果您在运行时使用安装插件
INSTALL PLUGIN
,它将在服务器重新启动
时
保持安装。
要卸载它,请使用
UNINSTALL PLUGIN
:
UNINSTALL PLUGIN auth_socket;
套接字插件检查套接字用户名(操作系统用户名)是否与客户端程序为服务器指定的MySQL用户名匹配。
如果名称不匹配,插件将检查套接字用户名是否
authentication_string
与
mysql.user
系统表行
的
列中
指定的名称匹配
。
如果找到匹配项,则插件允许连接。
authentication_string
可以使用
IDENTIFIED ...AS
带
CREATE
USER
或
的
子句
指定
该
值
ALTER
USER
。
假设为一个操作系统用户创建了一个MySQL帐户,该用户将
valerie
通过
auth_socket
插件对本地主机通过套接字文件进行连接
进行身份验证
:
创建用户'valerie'@'localhost'用auth_socket识别;
如果本地主机上具有登录名
的用户使用通过套接字文件连接
的选项
stefanie
调用
mysql
--user=valerie
,则服务器将使用该服务器
auth_socket
对客户端进行身份验证。
插件确定
--user
选项value(
valerie
)与客户端用户的名称(
stephanie
)不同并拒绝连接。
如果名为的用户
valerie
尝试相同的操作,则插件会发现用户名和MySQL用户名都是
valerie
并且允许连接。
但是,即使
valerie
连接是使用不同的协议(如TCP / IP)进行
连接,插件也会拒绝连接
。
要允许
valerie
和
stephanie
操作系统用户通过使用该帐户的套接字文件连接访问MySQL,可以通过两种方式完成:
在帐户创建时为一个用户命名,一个跟随
CREATE USER
,另一个在认证字符串中:
创建用户'valerie'@'localhost'用auth_socket AS'stephanie'识别;
如果您已经习惯
CREATE
USER
为单个用户创建帐户,请使用
ALTER
USER
添加第二个用户:
创建用户'valerie'@'localhost'用auth_socket识别; ALTER USER'valerie'@'localhost'用auth_socket AS'stephanie'识别;
要访问帐户都
valerie
与
stephanie
指定
--user=valerie
在连接时。
MySQL包含一个测试插件,用于检查帐户凭据并将成功或失败记录到服务器错误日志中。 这是一个可加载的插件(未内置),必须在使用前安装。
测试插件源代码与服务器源分开,与内置本机插件不同,因此可以将其作为一个相对简单的示例进行检查,演示如何编写可加载的身份验证插件。
此插件用于测试和开发目的,不适用于生产环境或公共网络上的服务器。
下表显示了插件和库文件名。
文件名后缀可能与您的系统不同。
该文件必须位于
plugin_dir
系统变量
指定的目录中
。
表6.22测试验证的插件和库名称
插件或文件 | 插件或文件名 |
---|---|
服务器端插件 | test_plugin_server |
客户端插件 | auth_test_plugin |
库文件 | auth_test_plugin.so |
以下部分提供了特定于测试可插入身份验证的安装和使用信息:
有关MySQL中可插入身份验证的一般信息,请参见 第6.2.17节“可插入身份验证” 。
本节介绍如何安装测试身份验证插件。 有关安装插件的一般信息,请参见 第5.6.1节“安装和卸载插件” 。
要使服务器可以使用,插件库文件必须位于MySQL插件目录(
plugin_dir
系统变量
指定的目录
)中。
如有必要,通过设置
plugin_dir
服务器启动时
的值来配置插件目录位置
。
要在服务器启动时加载插件,请使用该
--plugin-load-add
选项命名包含它的库文件。
使用此插件加载方法,每次服务器启动时都必须提供该选项。
例如,将这些行放在服务器
my.cnf
文件中(
.so
根据需要
调整
平台
的
后缀):
的[mysqld] 插件的负载加= auth_test_plugin.so
修改后
my.cnf
,重新启动服务器以使新设置生效。
或者,要在运行时注册插件,请使用此语句(
.so
根据需要
调整
后缀):
INSTALL PLUGIN test_plugin_server SONAME'auth_test_plugin.so';
INSTALL
PLUGIN
立即加载插件,并将其注册到
mysql.plugins
系统表中,以使服务器为每个后续的正常启动加载它。
要验证插件安装,请检查
INFORMATION_SCHEMA.PLUGINS
表或使用该
SHOW PLUGINS
语句(请参见
第5.6.2节“获取服务器插件信息”
)。
例如:
MySQL的>SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE '%test_plugin%';
+ -------------------- + --------------- + | PLUGIN_NAME | PLUGIN_STATUS | + -------------------- + --------------- + | test_plugin_server | ACTIVE | + -------------------- + --------------- +
如果插件无法初始化,请检查服务器错误日志以获取诊断消息。
要将MySQL帐户与测试插件相关联,请参阅 使用测试可插入身份验证 。
用于卸载测试身份验证插件的方法取决于您的安装方式:
如果您在服务器启动时使用
--plugin-load-add
选项
安装了插件,请在
没有该选项的情况下重新启动服务器。
如果您在运行时使用安装插件
INSTALL PLUGIN
,它将在服务器重新启动
时
保持安装。
要卸载它,请使用
UNINSTALL PLUGIN
:
UNINSTALL PLUGIN test_plugin_server;
要使用测试身份验证插件,请在
IDENTIFIED WITH
子句中
创建一个帐户并命名该插件
:
创建用户'testuser'@'localhost'
使用test_plugin_server识别
BY' testpassword
';
然后
在连接到服务器时为该帐户
提供
--user
和
--password
选项。
例如:
shell>mysql --user=testuser --password
输入密码:
testpassword
插件从客户端获取密码,并将其与
系统表中
authentication_string
帐户行列中
存储的值进行比较
mysql.user
。
如果两个值匹配,则插件将该
authentication_string
值作为新的有效用户ID返回。
您可以在服务器错误日志中查找指示验证是否成功的消息(请注意密码是否报告为 “ 用户 ” ):
[注意]插件test_plugin_server报告:
'成功验证用户testpassword
'
除非安装了适当的服务器端插件,否则这些变量不可用:
authentication_ldap_sasl
对于具有表单名称的系统变量
authentication_ldap_sasl_
xxx
authentication_ldap_simple
对于具有表单名称的系统变量
authentication_ldap_simple_
xxx
表6.23身份验证插件系统变量摘要
authentication_ldap_sasl_auth_method_name
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-sasl-auth-method-name=value |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_sasl_auth_method_name |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
默认值 | SCRAM-SHA-1 |
对于SASL LDAP身份验证,请使用身份验证方法名称。 认证插件和LDAP服务器之间的通信根据此认证方法进行。 允许使用以下身份验证方法值:
SCRAM-SHA-1
:身份验证使用SASL质询 - 响应机制来确保密码安全性。
客户端
authentication_ldap_sasl_client
插件与SASL服务器通信,使用密码创建质询并获取SASL请求缓冲区,然后将此缓冲区传递给服务器端
authentication_ldap_sasl
插件。
客户端和服务器端SASL
LDAP插件使用SASL消息在LDAP协议中安全传输凭据,以避免在MySQL客户端和服务器之间发送明文密码。
authentication_ldap_sasl_bind_base_dn
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-sasl-bind-base-dn=value |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_sasl_bind_base_dn |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
默认值 | NULL |
对于SASL LDAP身份验证,基本专有名称(DN)。 此变量可用于通过将搜索范围锚定在 搜索树 中的特定位置( “ 基础 ” ) 来限制搜索范围 。
假设一组LDAP用户条目的成员都具有以下形式:
uid = user_name
,ou = People,dc = example,dc = com
另一组LDAP用户条目的成员每个都有这种形式:
uid = user_name
,ou = Admin,dc = example,dc = com
然后搜索工作类似于不同的基本DN值:
如果基本DN为
ou=People,dc=example,dc=com
:搜索仅在第一组中查找用户条目。
如果基本DN为
ou=Admin,dc=example,dc=com
:搜索仅在第二组中查找用户条目。
如果基本DN是
ou=dc=example,dc=com
:搜索在第一组或第二组中查找用户条目。
通常,更具体的基本DN值会导致更快的搜索,因为它们会更多地限制搜索范围。
authentication_ldap_sasl_bind_root_dn
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-sasl-bind-root-dn=value |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_sasl_bind_root_dn |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
默认值 | NULL |
对于SASL LDAP身份验证,根据可分辨名称(DN)。
此变量与
authentication_ldap_sasl_bind_root_pwd
作为用于对LDAP服务器进行身份验证的凭据
结合使用
,以执行搜索。
身份验证使用一个或两个LDAP绑定操作,具体取决于MySQL帐户是否为LDAP用户DN命名:
如果帐户未命名用户DN:
authentication_ldap_sasl
使用
authentication_ldap_sasl_bind_root_dn
和
执行初始LDAP绑定
authentication_ldap_sasl_bind_root_pwd
。
(默认情况下这些都是空的,因此如果未设置它们,LDAP服务器必须允许匿名连接。)生成的绑定LDAP句柄用于根据客户端用户名搜索用户DN。
authentication_ldap_sasl
使用用户DN和客户端提供的密码执行第二次绑定。
如果该帐户确实为用户DN命名:在这种情况下,不需要第一次绑定操作。
authentication_ldap_sasl
使用用户DN和客户端提供的密码执行单个绑定。
这比MySQL帐户未指定LDAP用户DN更快。
authentication_ldap_sasl_bind_root_pwd
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-sasl-bind-root-pwd=value |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_sasl_bind_root_pwd |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
默认值 | NULL |
对于SASL LDAP身份验证,为根专有名称的密码。
此变量与
authentication_ldap_sasl_bind_root_dn
。
一起使用
。
请参阅该变量的说明。
authentication_ldap_sasl_ca_path
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-sasl-ca-path=value |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_sasl_ca_path |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
默认值 | NULL |
对于SASL LDAP身份验证,证书颁发机构文件的绝对路径。 如果希望身份验证插件执行LDAP服务器证书的验证,请指定此文件。
除了将
authentication_ldap_sasl_ca_path
变量
设置为
文件名之外,还必须将相应的证书颁发机构证书添加到文件中并启用
authentication_ldap_sasl_tls
系统变量。
authentication_ldap_sasl_group_search_attr
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-sasl-group-search-attr=value |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_sasl_group_search_attr |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
默认值 | cn |
对于SASL LDAP身份验证,指定LDAP目录条目中的组名称的属性的名称。
如果
authentication_ldap_sasl_group_search_attr
其默认值为
cn
,则搜索将
cn
值作为组名
返回
。
例如,如果有一个LDAP项
uid
的值
user1
具有
cn
的属性
mygroup
,搜索
user1
返回
mygroup
的组名。
如果不需要组或代理身份验证,则此变量应为空字符串。
如果是组搜索属性
isMemberOf
,则LDAP身份验证直接检索用户属性
isMemberOf
值并将其指定为组信息。
如果组搜索属性不是
isMemberOf
,则LDAP身份验证将搜索用户所属的所有组。
(后者是默认行为。)此行为基于如何以两种方式存储LDAP组信息:1)组条目可以具有名为
memberUid
或
member
具有用户名的值
的属性
;
2)用户条目可以具有以
isMemberOf
组名称
命名的属性
。
authentication_ldap_sasl_group_search_filter
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-sasl-group-search-filter=value |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_sasl_group_search_filter |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
默认值 | (|(&(objectClass=posixGroup)(memberUid=%s))(&(objectClass=group)(member=%s))) |
对于SASL LDAP身份验证,自定义组搜索筛选器。
搜索过滤器值可以包含
{UA}
和
{UD}
表示用户名和完整用户DN。
例如,
{UA}
用诸如的用户名
替换
"admin"
,而
{UD}
替换为使用完整的DN,例如
"uid=admin,ou=People,dc=example,dc=com"
。
以下值是默认值,它支持OpenLDAP和Active Directory:
(|(&(objectClass的= posixGroup)(memberUid = {UA})) (&(objectClass的=基团)(成员= {} UD)))
在某些情况下,对于用户场景,
memberOf
是一个不包含组信息的简单用户属性。
为了提高灵活性,可选
{GA}
前缀可与组搜索属性一起使用。
具有{GA}前缀的任何组属性都被视为具有组名的用户属性。
例如,值为
{GA}MemberOf
,如果组值是DN,则返回组DN中的第一个属性值作为组名。
authentication_ldap_sasl_init_pool_size
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-sasl-init-pool-size=# |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_sasl_init_pool_size |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 10 |
最低价值 | 0 |
最大价值 | 32767 |
对于SASL LDAP身份验证,LDAP服务器连接池的初始大小。 根据LDAP服务器的平均并发身份验证请求数选择此变量的值。
该插件使用
authentication_ldap_sasl_init_pool_size
和
authentication_ldap_sasl_max_pool_size
一起进行连接池管理:
当身份验证插件初始化时,它会创建
authentication_ldap_sasl_init_pool_size
连接,除非
authentication_ldap_sasl_max_pool_size=0
禁用池。
如果插件在当前连接池中没有空闲连接时收到验证请求,则插件可以创建新连接,最多可达到最大连接池大小
authentication_ldap_sasl_max_pool_size
。
如果插件在池大小已达到最大值并且没有空闲连接时收到请求,则身份验证将失败。
当插件卸载时,它会关闭所有池连接。
对插件系统变量设置的更改可能对池中已有的连接没有影响。 例如,修改LDAP服务器主机,端口或TLS设置不会影响现有连接。 但是,如果原始变量值无效且无法初始化连接池,则插件会尝试为下一个LDAP请求重新初始化池。 在这种情况下,新的系统变量值用于重新初始化尝试。
如果
authentication_ldap_sasl_max_pool_size=0
要禁用池,则插件打开的每个LDAP连接都使用系统变量当时具有的值。
authentication_ldap_sasl_log_status
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-sasl-log-status=# |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_sasl_log_status |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 1 |
最低价值 | 1 |
最大价值 | 5 |
对于SASL LDAP身份验证,请记录级别。 下表显示了允许的级别值及其含义。
表6.24 authentication_ldap_sasl_log_status的日志级别
期权价值 | 记录的消息类型 |
---|---|
1 |
没有消息 |
2 |
错误消息 |
3 |
错误和警告消息 |
4 |
错误,警告和信息消息 |
5 |
所有消息 |
在客户端,可以通过设置
AUTHENTICATION_LDAP_CLIENT_LOG
环境变量
将消息记录到标准输出
。
允许值和默认值与for相同
authentication_ldap_sasl_log_status
。
该
AUTHENTICATION_LDAP_CLIENT_LOG
环境变量仅适用于SASL LDAP认证。
它对简单的LDAP身份验证没有影响,因为在这种情况下客户端插件是
mysql_clear_password
,它对LDAP操作一无所知。
authentication_ldap_sasl_max_pool_size
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-sasl-max-pool-size=# |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_sasl_max_pool_size |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 1000 |
最低价值 | 0 |
最大价值 | 32767 |
对于SASL LDAP身份验证,LDAP服务器连接池的最大大小。 要禁用连接池,请将此变量设置为0。
此变量与
authentication_ldap_sasl_init_pool_size
。
一起使用
。
请参阅该变量的说明。
authentication_ldap_sasl_server_host
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-sasl-server-host=host_name |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_sasl_server_host |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
对于SASL LDAP身份验证,LDAP服务器主机。 此变量的允许值取决于身份验证方法:
对于
authentication_ldap_sasl_auth_method_name=SCRAM-SHA-1
:LDAP服务器主机可以是主机名或IP地址。
authentication_ldap_sasl_server_port
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-sasl-server-port=port_num |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_sasl_server_port |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 389 |
最低价值 | 1 |
最大价值 | 32376 |
对于SASL LDAP身份验证,LDAP服务器TCP / IP端口号。
从MySQL 8.0.14开始,如果LDAP端口号配置为636或3269,则插件使用LDAPS(LDAP over SSL)而不是LDAP。
(LDAPS与
startTLS
。
不同
。)
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-sasl-tls[={OFF|ON}] |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_sasl_tls |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 布尔 |
默认值 | OFF |
对于SASL LDAP身份验证,插件与LDAP服务器的连接是否安全。
如果启用此变量,则插件使用TLS安全地连接到LDAP服务器。
如果启用此变量,您可能还希望设置
authentication_ldap_sasl_ca_path
变量。
MySQL LDAP插件支持StartTLS方法,该方法在普通LDAP连接之上初始化TLS。
该
ldaps
方法已弃用,MySQL不支持它。
authentication_ldap_sasl_user_search_attr
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-sasl-user-search-attr=value |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_sasl_user_search_attr |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
默认值 | uid |
对于SASL LDAP身份验证,指定LDAP目录条目中的用户名的属性的名称。
如果未提供用户专有名称,则认证插件将使用此属性搜索名称。
例如,如果
authentication_ldap_sasl_user_search_attr
值为
uid
,则搜索用户名会
user1
查找
uid
值为的
条目
user1
。
authentication_ldap_simple_auth_method_name
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-simple-auth-method-name=value |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_simple_auth_method_name |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
默认值 | SIMPLE |
对于简单LDAP身份验证,身份验证方法名称。 认证插件和LDAP服务器之间的通信根据此认证方法进行。 允许使用以下身份验证方法值:
SIMPLE
:此身份验证方法使用一个或两个LDAP绑定操作,具体取决于MySQL帐户是否命名LDAP用户可分辨名称。
请参阅说明
authentication_ldap_simple_bind_root_dn
。
AD-FOREST
:
authentication_ldap_simple
搜索Active Directory林中的所有域,对每个Active
Directory域执行LDAP绑定,直到在某个域中找到该用户。
对于简单的LDAP身份验证,建议还要将TLS参数设置为要求与LDAP服务器的通信通过安全连接进行。
authentication_ldap_simple_bind_base_dn
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-simple-bind-base-dn=value |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_simple_bind_base_dn |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
默认值 | NULL |
对于简单LDAP身份验证,基本专有名称(DN)。 此变量可用于通过将搜索范围锚定在 搜索树 中的特定位置( “ 基础 ” ) 来限制搜索范围 。
假设一组LDAP用户条目的成员都具有以下形式:
uid = user_name
,ou = People,dc = example,dc = com
另一组LDAP用户条目的成员每个都有这种形式:
uid = user_name
,ou = Admin,dc = example,dc = com
然后搜索工作类似于不同的基本DN值:
如果基本DN为
ou=People,dc=example,dc=com
:搜索仅在第一组中查找用户条目。
如果基本DN为
ou=Admin,dc=example,dc=com
:搜索仅在第二组中查找用户条目。
如果基本DN是
ou=dc=example,dc=com
:搜索在第一组或第二组中查找用户条目。
通常,更具体的基本DN值会导致更快的搜索,因为它们会更多地限制搜索范围。
authentication_ldap_simple_bind_root_dn
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-simple-bind-root-dn=value |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_simple_bind_root_dn |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
默认值 | NULL |
对于简单LDAP身份验证,根专有名称(DN)。
此变量与
authentication_ldap_simple_bind_root_pwd
作为用于对LDAP服务器进行身份验证的凭据
结合使用
,以执行搜索。
身份验证使用一个或两个LDAP绑定操作,具体取决于MySQL帐户是否为LDAP用户DN命名:
如果帐户未命名用户DN:
authentication_ldap_simple
使用
authentication_ldap_simple_bind_root_dn
和
执行初始LDAP绑定
authentication_ldap_simple_bind_root_pwd
。
(默认情况下这些都是空的,因此如果未设置它们,LDAP服务器必须允许匿名连接。)生成的绑定LDAP句柄用于根据客户端用户名搜索用户DN。
authentication_ldap_simple
使用用户DN和客户端提供的密码执行第二次绑定。
如果该帐户确实为用户DN命名:在这种情况下,不需要第一次绑定操作。
authentication_ldap_simple
使用用户DN和客户端提供的密码执行单个绑定。
这比MySQL帐户未指定LDAP用户DN更快。
authentication_ldap_simple_bind_root_pwd
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-simple-bind-root-pwd=value |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_simple_bind_root_pwd |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
默认值 | NULL |
对于简单LDAP身份验证,根专有名称的密码。
此变量与
authentication_ldap_simple_bind_root_dn
。
一起使用
。
请参阅该变量的说明。
authentication_ldap_simple_ca_path
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-simple-ca-path=value |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_simple_ca_path |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
默认值 | NULL |
对于简单LDAP身份验证,证书颁发机构文件的绝对路径。 如果希望身份验证插件执行LDAP服务器证书的验证,请指定此文件。
除了将
authentication_ldap_simple_ca_path
变量
设置为
文件名之外,还必须将相应的证书颁发机构证书添加到文件中并启用
authentication_ldap_simple_tls
系统变量。
authentication_ldap_simple_group_search_attr
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-simple-group-search-attr=value |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_simple_group_search_attr |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
默认值 | cn |
对于简单LDAP身份验证,指定LDAP目录条目中的组名称的属性的名称。
如果
authentication_ldap_simple_group_search_attr
其默认值为
cn
,则搜索将
cn
值作为组名
返回
。
例如,如果有一个LDAP项
uid
的值
user1
具有
cn
的属性
mygroup
,搜索
user1
返回
mygroup
的组名。
如果是组搜索属性
isMemberOf
,则LDAP身份验证直接检索用户属性
isMemberOf
值并将其指定为组信息。
如果组搜索属性不是
isMemberOf
,则LDAP身份验证将搜索用户所属的所有组。
(后者是默认行为。)此行为基于如何以两种方式存储LDAP组信息:1)组条目可以具有名为
memberUid
或
member
具有用户名的值
的属性
;
2)用户条目可以具有以
isMemberOf
组名称
命名的属性
。
authentication_ldap_simple_group_search_filter
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-simple-group-search-filter=value |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_simple_group_search_filter |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
默认值 | (|(&(objectClass=posixGroup)(memberUid=%s))(&(objectClass=group)(member=%s))) |
对于简单的LDAP身份验证,自定义组搜索过滤器。
搜索过滤器值可以包含
{UA}
和
{UD}
表示用户名和完整用户DN。
例如,
{UA}
用诸如的用户名
替换
"admin"
,而
{UD}
替换为使用完整的DN,例如
"uid=admin,ou=People,dc=example,dc=com"
。
以下值是默认值,它支持OpenLDAP和Active Directory:
(|(&(objectClass的= posixGroup)(memberUid = {UA})) (&(objectClass的=基团)(成员= {} UD)))
在某些情况下,对于用户场景,
memberOf
是一个不包含组信息的简单用户属性。
为了提高灵活性,可选
{GA}
前缀可与组搜索属性一起使用。
具有{GA}前缀的任何组属性都被视为具有组名的用户属性。
例如,值为
{GA}MemberOf
,如果组值是DN,则返回组DN中的第一个属性值作为组名。
authentication_ldap_simple_init_pool_size
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-simple-init-pool-size=# |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_simple_init_pool_size |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 10 |
最低价值 | 0 |
最大价值 | 32767 |
对于简单LDAP身份验证,LDAP服务器连接池的初始大小。 根据LDAP服务器的平均并发身份验证请求数选择此变量的值。
该插件使用
authentication_ldap_simple_init_pool_size
和
authentication_ldap_simple_max_pool_size
一起进行连接池管理:
当身份验证插件初始化时,它会创建
authentication_ldap_simple_init_pool_size
连接,除非
authentication_ldap_simple_max_pool_size=0
禁用池。
如果插件在当前连接池中没有空闲连接时收到验证请求,则插件可以创建新连接,最多可达到最大连接池大小
authentication_ldap_simple_max_pool_size
。
如果插件在池大小已达到最大值并且没有空闲连接时收到请求,则身份验证将失败。
当插件卸载时,它会关闭所有池连接。
对插件系统变量设置的更改可能对池中已有的连接没有影响。 例如,修改LDAP服务器主机,端口或TLS设置不会影响现有连接。 但是,如果原始变量值无效且无法初始化连接池,则插件会尝试为下一个LDAP请求重新初始化池。 在这种情况下,新的系统变量值用于重新初始化尝试。
如果
authentication_ldap_simple_max_pool_size=0
要禁用池,则插件打开的每个LDAP连接都使用系统变量当时具有的值。
authentication_ldap_simple_log_status
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-simple-log-status=# |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_simple_log_status |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 1 |
最低价值 | 1 |
最大价值 | 5 |
对于简单的LDAP身份验证,请记录级别。 下表显示了允许的级别值及其含义。
表6.25 authentication_ldap_simple_log_status的日志级别
期权价值 | 记录的消息类型 |
---|---|
1 |
没有消息 |
2 |
错误消息 |
3 |
错误和警告消息 |
4 |
错误,警告和信息消息 |
5 |
所有消息 |
authentication_ldap_simple_max_pool_size
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-simple-max-pool-size=# |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_simple_max_pool_size |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 1000 |
最低价值 | 0 |
最大价值 | 32767 |
对于简单LDAP身份验证,LDAP服务器连接池的最大大小。 要禁用连接池,请将此变量设置为0。
此变量与
authentication_ldap_simple_init_pool_size
。
一起使用
。
请参阅该变量的说明。
authentication_ldap_simple_server_host
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-simple-server-host=host_name |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_simple_server_host |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
对于简单的LDAP身份验证,LDAP服务器主机。 此变量的允许值取决于身份验证方法:
对于
authentication_ldap_simple_auth_method_name=SIMPLE
:LDAP服务器主机可以是主机名或IP地址。
为了
authentication_ldap_simple_auth_method_name=AD-FOREST
。
LDAP服务器主机可以是Active Directory域名。
例如,对于LDAP服务器URL
ldap://example.mem.local:389
,服务器名称可以是
mem.local
。
Active Directory林设置可以具有多个域(LDAP服务器IP),可以使用DNS发现这些域。 在Unix和类Unix系统上,可能需要一些额外的设置来配置DNS服务器,其中SRV记录指定Active Directory域的LDAP服务器。 假设您的配置具有以下属性:
提供有关Active Directory域的信息的名称服务器具有IP地址
10.172.166.100
。
该LDAP服务器都有名称
ldap1.mem.local
通过
ldap3.mem.local
和IP地址
10.172.166.101
通过
10.172.166.103
。
您希望使用SRV搜索可以发现LDAP服务器。 例如,在命令行中,这样的命令应该列出LDAP服务器:
host -t SRV _ldap._tcp.mem.local
执行DNS配置,如下所示:
添加一行以
/etc/resolv.conf
指定提供有关Active Directory域的信息的名称服务器:
名称服务器10.172.166.100
使用LDAP服务器的SRV记录为名称服务器配置相应的区域文件:
_ldap._tcp.mem.local。86400 IN SRV 0 100 389 ldap1.mem.local。 _ldap._tcp.mem.local。86400 IN SRV 0 100 389 ldap2.mem.local。 _ldap._tcp.mem.local。86400 IN SRV 0 100 389 ldap3.mem.local。
/etc/hosts
如果无法解析服务器主机
,
则
可能还需要为LDAP服务器指定IP地址
。
例如,将这样的行添加到文件中:
10.172.166.101 ldap1.mem.local 10.172.166.102 ldap2.mem.local 10.172.166.103 ldap3.mem.local
通过如上所述配置DNS,服务器端LDAP插件可以发现LDAP服务器,并将尝试在所有域中进行身份验证,直到身份验证成功或没有其他服务器。
Windows不需要如上所述的此类设置。
给定值中的LDAP服务器主机
authentication_ldap_simple_server_host
,Windows LDAP库将搜索所有域并尝试进行身份验证。
authentication_ldap_simple_server_port
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-simple-server-port=port_num |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_simple_server_port |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 389 |
最低价值 | 1 |
最大价值 | 32376 |
对于简单LDAP身份验证,LDAP服务器TCP / IP端口号。
从MySQL 8.0.14开始,如果LDAP端口号配置为636或3269,则插件使用LDAPS(LDAP over SSL)而不是LDAP。
(LDAPS与
startTLS
。
不同
。)
authentication_ldap_simple_tls
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-simple-tls[={OFF|ON}] |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_simple_tls |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 布尔 |
默认值 | OFF |
对于简单的LDAP身份验证,插件与LDAP服务器的连接是否安全。
如果启用此变量,则插件使用TLS安全地连接到LDAP服务器。
如果启用此变量,您可能还希望设置
authentication_ldap_simple_ca_path
变量。
MySQL LDAP插件支持StartTLS方法,该方法在普通LDAP连接之上初始化TLS。
该
ldaps
方法已弃用,MySQL不支持它。
authentication_ldap_simple_user_search_attr
属性 | 值 |
---|---|
命令行格式 | --authentication-ldap-simple-user-search-attr=value |
介绍 | 8.0.11 |
系统变量 | authentication_ldap_simple_user_search_attr |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
默认值 | uid |
对于简单LDAP身份验证,指定LDAP目录条目中的用户名的属性的名称。
如果未提供用户专有名称,则认证插件将使用此属性搜索名称。
例如,如果
authentication_ldap_simple_user_search_attr
值为
uid
,则搜索用户名会
user1
查找
uid
值为的
条目
user1
。
MySQL Server包含一个插件库,使管理员能够在连续几次连接尝试失败后,将服务器响应的延迟时间增加到客户端。 此功能提供了一种威慑力,可以减缓尝试访问MySQL用户帐户的暴力攻击。 插件库包含两个插件:
CONNECTION_CONTROL
检查传入连接并根据需要向服务器响应添加延迟。
此插件还公开了可以配置其操作的系统变量以及提供基本监视信息的状态变量。
该
CONNECTION_CONTROL
插件使用审计插件接口(请参见
第29.2.4.8节“编写审计插件”
)。
为了收集信息,它订阅
MYSQL_AUDIT_CONNECTION_CLASSMASK
事件类,进程
MYSQL_AUDIT_CONNECTION_CONNECT
和子
MYSQL_AUDIT_CONNECTION_CHANGE_USER
事件以检查服务器是否应该在响应客户端连接尝试之前引入延迟。
CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS
实现一个
INFORMATION_SCHEMA
表,为失败的连接尝试公开更详细的监视信息。
以下部分提供有关连接控件插件安装和配置的信息。
有关该
CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS
表的
信息
,请参见
第25.41.1节“INFORMATION_SCHEMA CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS表”
。
本节介绍如何安装连接控制插件,
CONNECTION_CONTROL
以及
CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS
。
有关安装插件的一般信息,请参见
第5.6.1节“安装和卸载插件”
。
要使服务器可以使用,插件库文件必须位于MySQL插件目录(
plugin_dir
系统变量
指定的目录
)中。
如有必要,通过设置
plugin_dir
服务器启动时
的值来配置插件目录位置
。
插件库文件基本名称是
connection_control
。
文件名后缀因平台
.so
而异
(例如,
对于Unix和类Unix系统,
.dll
对于Windows)。
要在服务器启动时加载插件,请使用该
--plugin-load-add
选项命名包含它们的库文件。
使用此插件加载方法,每次服务器启动时都必须提供该选项。
例如,将这些行放在服务器
my.cnf
文件中(
.so
根据需要
调整
平台
的
后缀):
的[mysqld] 插件的负载加= connection_control.so
修改后
my.cnf
,重新启动服务器以使新设置生效。
或者,要在运行时注册插件,请使用这些语句(
.so
根据需要
调整
后缀):
安装PLUGIN CONNECTION_CONTROL SONAME'connection_control.so'; 安装PLUGIN CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS SONAME'connection_control.so';
INSTALL
PLUGIN
立即加载插件,并将其注册到
mysql.plugins
系统表中,以使服务器为每个后续的正常启动加载它。
要验证插件安装,请检查
INFORMATION_SCHEMA.PLUGINS
表或使用该
SHOW PLUGINS
语句(请参见
第5.6.2节“获取服务器插件信息”
)。
例如:
MySQL的>SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE 'connection%';
------------------------------------------ + ------ + --------- + | PLUGIN_NAME | PLUGIN_STATUS | ------------------------------------------ + ------ + --------- + | CONNECTION_CONTROL | ACTIVE | | CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS | ACTIVE | ------------------------------------------ + ------ + --------- +
如果插件无法初始化,请检查服务器错误日志以获取诊断消息。
如果插件先前已注册
INSTALL PLUGIN
或已加载
--plugin-load-add
,则可以使用
服务器启动时
的
--connection-control
和
--connection-control-failed-login-attempts
选项来控制插件激活。
例如,要在启动时加载插件并防止它们在运行时被删除,请使用以下选项:
的[mysqld] 插件的负载加= connection_control.so 连接控制= FORCE_PLUS_PERMANENT 连接控制失败的登录者试图= FORCE_PLUS_PERMANENT
如果希望在没有给定连接控件插件的情况下阻止服务器运行,请使用选项值of
FORCE
或
FORCE_PLUS_PERMANENT
强制服务器启动失败,如果插件未成功初始化。
可以安装一个插件而不安装另一个插件,但必须安装这两个插件才能实现完全的连接控制功能。
特别是,仅安装
CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS
插件几乎没用,因为没有
CONNECTION_CONTROL
插件提供填充
CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS
表
的数据,从
表中检索将始终为空。
为了使您能够配置其操作,
CONNECTION_CONTROL
插件公开了几个系统变量:
connection_control_failed_connections_threshold
:在服务器为后续连接尝试添加延迟之前允许客户端连续失败的连接尝试次数。
connection_control_min_connection_delay
:每次连续失败超过阈值时添加的延迟量。
connection_control_max_connection_delay
:添加的最大延迟。
要完全禁用检查失败的连接尝试,请设置
connection_control_failed_connections_threshold
为零。
如果
connection_control_failed_connections_threshold
非零,则通过许多连续失败的连接尝试,延迟量为零。
此后,延迟量是高于阈值的失败尝试次数乘以
connection_control_min_connection_delay
毫秒。
例如,使用默认值
connection_control_failed_connections_threshold
和
connection_control_min_connection_delay
值分别为3和1000,客户端连续尝试连接失败前三次没有延迟,第四次失败尝试延迟1000毫秒,第五次失败尝试延迟2000毫秒,依此类推允许的最大延迟
connection_control_max_connection_delay
。
您可以
CONNECTION_CONTROL
在服务器启动或运行时
设置
系统变量。
假设您希望在服务器开始延迟其响应之前允许连续四次失败的连接尝试,并在此之后将每次额外失败的延迟增加1500毫秒。
要在服务器启动时设置相关变量,请将这些行放在服务器
my.cnf
文件中:
的[mysqld] 插件的负载加= connection_control.so connection_control_failed_connections_threshold = 4 connection_control_min_connection_delay = 1500
要在运行时设置和保持变量,请使用以下语句:
SET PERSIST connection_control_failed_connections_threshold = 4; SET PERSIST connection_control_min_connection_delay = 1500;
SET
PERSIST
设置正在运行的MySQL实例的值。
它还会保存该值,使其用于后续服务器重新启动。
要更改正在运行的MySQL实例的值而不保存它以便后续重新启动,请使用
GLOBAL
关键字而不是
PERSIST
。
请参见
第13.7.5.1节“变量赋值的SET语法”
。
的
connection_control_min_connection_delay
和
connection_control_max_connection_delay
系统变量具有固定的最小和的分别在1000和2147483647,最大值。
此外,每个变量的允许值范围还取决于另一个变量的当前值:
因此,要进行某些配置所需的更改,您可能需要按特定顺序设置变量。
假设当前最小和最大延迟为1000和2000,并且您要将它们设置为3000和5000.您不能先设置
connection_control_min_connection_delay
为3000,因为它大于当前
connection_control_max_connection_delay
值2000.而是设置
connection_control_max_connection_delay
为5000,然后设置
connection_control_min_connection_delay
到3000。
当
CONNECTION_CONTROL
安装插件,它会检查连接尝试,并跟踪他们是否成功或失败。
为此,失败的连接尝试是客户端用户和主机与已知的MySQL帐户匹配但是提供的凭据不正确或与任何已知帐户不匹配的连接尝试。
失败连接计数基于每次连接尝试的用户/主机组合。 确定适用的用户名和主机名需要考虑代理并发生如下:
如果客户端用户代理另一个用户,则使用代理用户的信息。
例如,如果
external_user@example.com
代理
proxy_user@example.com
,连接计数使用代理用户
external_user@example.com
,而不是代理用户
proxy_user@example.com
。
两者都
必须在
系统表中
具有有效条目,
external_user@example.com
并且
proxy_user@example.com
必须在
mysql.user
系统表中定义它们之间的代理关系
mysql.proxies_priv
(请参见
第6.2.18节“代理用户”
)。
如果客户端用户不代理另一个用户,但确实匹配
mysql.user
条目,则计数使用
CURRENT_USER()
与该条目对应
的
值。
例如,如果
user1
从主机连接
的用户
host1.example.com
与
user1@host1.example.com
条目
匹配
,则计数使用
user1@host1.example.com
。
如果用户相匹配的
user1@%.example.com
,
user1@%.com
或
user1@%
进入相反,统计用途
user1@%.example.com
,
user1@%.com
或者
user1@%
分别。
对于刚才描述的情况,连接尝试与某些
mysql.user
条目
匹配
,请求是成功还是失败取决于客户端是否提供正确的身份验证凭据。
例如,如果客户端提供的密码不正确,则连接尝试失败。
如果连接尝试不匹配任何
mysql.user
条目,则尝试失败。
在这种情况下,没有
CURRENT_USER()
值可用,连接失败计数使用客户端和客户端主机提供的用户名,由服务器确定。
例如,如果客户端尝试
user2
从主机
host2.example.com
以用户
身份进行连接
,则客户端请求中将提供用户名部分,服务器将确定主机信息。
用于计数的用户/主机组合是
user2@host2.example.com
。
服务器维护有关哪些客户端主机可能连接到服务器的信息(实质上是
mysql.user
条目
的主机值的并集
)。
如果客户端尝试从任何其他主机进行连接,则服务器会在连接设置的早期阶段拒绝该尝试:
ERROR 1130(HY000):主持人' host_name
'不是
允许连接到这个MySQL服务器
因为这种类型的拒绝很早就发生了,所以
CONNECTION_CONTROL
没有看到它,也不计算它。
要监视失败的连接,请使用以下信息源:
该
Connection_control_delay_generated
状态变量表示的次数增加服务器的延迟到其失败的连接尝试的响应。
这不计算在达到
connection_control_failed_connections_threshold
系统变量
定义的阈值之前发生的尝试
。
该
INFORMATION_SCHEMA
CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS
表提供有关每个客户端用户/主机组合的当前连续失败连接尝试次数的信息。
这会计算所有失败的尝试,无论它们是否被延迟。
connection_control_failed_connections_threshold
在运行时
为值分配将
所有累积的失败连接计数器重置为零,这具有以下可见效果:
该
Connection_control_delay_generated
状态变量被重置为零。
本节介绍
CONNECTION_CONTROL
插件提供
的系统和状态变量,
以使其配置和监视其操作。
如果
CONNECTION_CONTROL
安装
了
插件,它会公开这些系统变量:
connection_control_failed_connections_threshold
属性 | 值 |
---|---|
命令行格式 | --connection-control-failed-connections-threshold=# |
介绍 | 8.0.1 |
系统变量 | connection_control_failed_connections_threshold |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 3 |
最低价值 | 0 |
最大价值 | 2147483647 |
在服务器为后续连接尝试添加延迟之前允许客户端连续失败的连接尝试次数:
如果变量具有非零值
N
,则服务器会添加从连续失败尝试
N
+1
开始的延迟
。
如果客户端已达到连接响应延迟的点,则下一次后续成功连接也会发生延迟。
将此变量设置为零将禁用失败连接计数。 在这种情况下,服务器永远不会增加延迟。
有关如何
connection_control_failed_connections_threshold
与其他连接控制系统和状态变量进行交互的
信息
,请参见
第6.4.2.1节“连接控制插件安装”
。
connection_control_max_connection_delay
属性 | 值 |
---|---|
命令行格式 | --connection-control-max-connection-delay=# |
介绍 | 8.0.1 |
系统变量 | connection_control_max_connection_delay |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 2147483647 |
最低价值 | 1000 |
最大价值 | 2147483647 |
服务器响应连接尝试失败的最大延迟(以毫秒为单位),如果
connection_control_failed_connections_threshold
大于零。
有关如何
connection_control_max_connection_delay
与其他连接控制系统和状态变量进行交互的
信息
,请参见
第6.4.2.1节“连接控制插件安装”
。
connection_control_min_connection_delay
属性 | 值 |
---|---|
命令行格式 | --connection-control-min-connection-delay=# |
介绍 | 8.0.1 |
系统变量 | connection_control_min_connection_delay |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 1000 |
最低价值 | 1000 |
最大价值 | 2147483647 |
服务器响应连接尝试失败的最小延迟(以毫秒为单位),如果
connection_control_failed_connections_threshold
大于零。
这也是服务器一旦开始延迟就增加连续连续故障延迟的数量。
有关如何
connection_control_min_connection_delay
与其他连接控制系统和状态变量进行交互的
信息
,请参见
第6.4.2.1节“连接控制插件安装”
。
如果
CONNECTION_CONTROL
安装
了
插件,则会公开此状态变量:
Connection_control_delay_generated
服务器对失败的连接尝试的响应添加延迟的次数。
这不会计算在达到由此定义的阈值之前发生的尝试
connection_control_failed_connections_threshold
系统变量
。
此变量提供简单的计数器。
有关更详细的连接控制监视信息,请检查
INFORMATION_SCHEMA
CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS
表格;
请参见
第25.41.1节“INFORMATION_SCHEMA
CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS表”
。
connection_control_failed_connections_threshold
在运行时
为值分配
重置
Connection_control_delay_generated
为零。
该
validate_password
组件用于测试密码并提高安全性。
此组件公开系统变量,使您可以定义密码策略和组件监视的状态变量。
在MySQL 8.0.4中,
validate_password
插件重新实现为
validate_password
组件。
以下说明介绍了如何使用组件,而不是插件。
有关使用该插件的说明,请参阅
密码验证插件
中
的MySQL 5.7参考手册
。
插件形式
validate_password
仍然可用,但已弃用,将在未来的MySQL版本中删除。
使用该插件的MySQL安装应该转换为使用该组件。
请参见
第6.4.3.3节“转换到密码验证组件”
。
该
validate_password
组件实现了这些功能:
在分配作为明文值提供的密码的SQL语句中,组件根据当前密码策略检查密码,如果密码较弱则拒绝密码(语句返回
ER_NOT_VALID_PASSWORD
错误)。
这适用于
ALTER
USER
,
CREATE
USER
,
GRANT
,和
SET PASSWORD
语句。
在
VALIDATE_PASSWORD_STRENGTH()
SQL函数评估潜在的密码强度。
该函数接受一个密码参数,并返回一个从0(弱)到100(强)的整数。
例如,
validate_password
检查以下语句中的明文密码。
在默认密码策略下,密码要求密码长度至少为8个字符,密码很弱,并且语句产生错误:
MySQL的> ALTER USER USER() IDENTIFIED BY 'abc';
ERROR 1819(HY000):您的密码不符合当前要求
政策要求
未检查指定为散列值的密码,因为原始密码值不可用于检查:
MySQL的>ALTER USER 'jeffrey'@'localhost'
IDENTIFIED WITH mysql_native_password
AS '*0D3CED9BEC10A777AEC23CCC353A8C08A633045E';
查询OK,0行受影响(0.01秒)
要配置密码检查,请修改具有表单名称的系统变量
;
这些是控制密码策略的参数。
请参见
第6.4.3.2节“密码验证选项和变量”
。
validate_password.
xxx
如果
validate_password
未安装,则
系统变量不可用,不检查语句中的密码,并且
函数始终返回0.例如,如果未安装插件,则可以为帐户分配短于8个字符的密码。
validate_password.
xxx
VALIDATE_PASSWORD_STRENGTH()
假设
validate_password
安装后,它会执行三个级别口令检查的:
LOW
,
MEDIUM
,和
STRONG
。
默认是
MEDIUM
;
要改变这一点,修改值
validate_password.policy
。
策略实施越来越严格的密码测试。
以下描述涉及默认参数值,可以通过更改相应的系统变量来修改这些值。
LOW
策略仅测试密码长度。
密码长度必须至少为8个字符。
要更改此长度,请修改
validate_password.length
。
MEDIUM
policy添加密码必须包含的条件,至少包含1个数字字符,1个小写字符,1个大写字符和1个特殊(非字母数字)字符。
要改变这些值,修改
validate_password.number_count
,
validate_password.mixed_case_count
和
validate_password.special_char_count
。
STRONG
policy添加条件,长度为4或更长的密码子字符串不得与字典文件中的单词匹配(如果已指定)。
要指定字典文件,请修改
validate_password.dictionary_file
。
此外,还
validate_password
支持拒绝与当前会话的有效用户帐户的用户名部分匹配的密码(正向或反向)。
要提供对此功能的控制,请
validate_password
公开一个
validate_password.check_user_name
默认启用
的
系统变量。
本节介绍如何安装和卸载
validate_password
密码验证组件。
有关安装和卸载组件的一般信息,请参见
第5.5节“MySQL服务器组件”
。
如果您使用
MySQL Yum存储库
,
MySQL SLES存储库
或
Oracle提供的RPM软件包
安装MySQL 8.0
,那么
validate_password
在首次启动MySQL服务器后
组件将默认启用。
使用Yum或RPM软件包从5.7升级到MySQL 8.0会使
validate_password
插件保持原位。
要从
validate_password
插件转换到
validate_password
组件,请参见
第6.4.3.3节“转换到密码验证组件”
。
要使服务器可以使用,组件库文件必须位于MySQL插件目录(
plugin_dir
系统变量
指定的目录
)中。
如有必要,通过设置
plugin_dir
服务器启动时
的值来配置插件目录位置
。
要安装
validate_password
组件,请使用以下语句:
INSTALL COMPONENT'file:// component_validate_password';
组件安装是一次性操作,无需在每个服务器启动时完成。
INSTALL
COMPONENT
加载组件,并将其注册到
mysql.component
系统表中,以便在后续服务器启动期间加载它。
卸载
validate_password
组件,请使用以下语句:
UNINSTALL COMPONENT'file:// component_validate_password';
UNINSTALL COMPONENT
卸载组件,并从
mysql.component
系统表中
取消注册,
以使其在后续服务器启动期间不被加载。
本节介绍
validate_password
用于配置和监视其操作
的系统和状态变量
。
如果
validate_password
组件已启用,则会公开几个允许配置密码检查的系统变量:
MySQL的> SHOW VARIABLES LIKE 'validate_password.%';
+ -------------------------------------- + -------- +
| Variable_name | 价值|
+ -------------------------------------- + -------- +
| validate_password.check_user_name | ON |
| validate_password.dictionary_file | |
| validate_password.length | 8 |
| validate_password.mixed_case_count | 1 |
| validate_password.number_count | 1 |
| validate_password.policy | MEDIUM |
| validate_password.special_char_count | 1 |
+ -------------------------------------- + -------- +
要更改密码的检查方式,可以在服务器启动时或运行时设置这些系统变量。 以下列表描述了每个变量的含义。
validate_password.check_user_name
属性 | 值 |
---|---|
命令行格式 | --validate-password.check-user-name[={OFF|ON}] |
介绍 | 8.0.4 |
系统变量 | validate_password.check_user_name |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 布尔 |
默认值 | ON |
是否
validate_password
将密码与当前会话的有效用户帐户的用户名部分进行比较,如果匹配则拒绝它们。
除非
validate_password
已安装,
否则此变量不可用
。
默认情况下,
validate_password.check_user_name
已启用。
此变量控制用户名匹配,与值无关
validate_password.policy
。
当
validate_password.check_user_name
启用时,它具有以下作用:
检查发生在
validate_password
调用的
所有上下文中
,包括使用诸如
ALTER USER
或
SET PASSWORD
更改当前用户密码
的语句
,以及调用诸如的函数
VALIDATE_PASSWORD_STRENGTH()
。
用于比较的用户名取自
当前会话
的值
USER()
和
CURRENT_USER()
函数
的值
。
这意味着具有足够权限来设置其他用户密码的用户可以将密码设置为该用户的名称,并且不能将该用户的密码设置为执行该语句的用户的名称。
例如,
'root'@'localhost'
可以设定密码
'jeffrey'@'localhost'
来
'jeffrey'
,但不能设置密码
'root
。
仅使用
USER()
和
CURRENT_USER()
函数值
的用户名部分,
而
不是主机名部分。
如果用户名为空,则不进行比较。
如果密码与用户名或其反向相同,则会发生匹配并拒绝密码。
用户名匹配区分大小写。 密码和用户名值在逐个字节的基础上作为二进制字符串进行比较。
如果密码与用户名匹配,则
VALIDATE_PASSWORD_STRENGTH()
无论如何
validate_password
设置
其他
系统变量,都
返回0
。
validate_password.dictionary_file
属性 | 值 |
---|---|
命令行格式 | --validate-password.dictionary-file=file_name |
介绍 | 8.0.4 |
系统变量 | validate_password.dictionary_file |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 文件名 |
validate_password
用于检查密码
的字典文件的路径名
。
除非
validate_password
已安装,
否则此变量不可用
。
默认情况下,此变量具有空值,不执行字典检查。
要进行字典检查,变量值必须为非空。
如果文件被命名为相对路径,则相对于服务器数据目录进行解释。
文件内容应为小写,每行一个字。
内容被视为具有字符集
utf8
。
允许的最大文件大小为1MB。
对于密码检查期间使用的字典文件,密码策略必须设置为2(
STRONG
);
请参阅
validate_password.policy
系统变量
的说明
。
假设这是真的,将长度为4到100的密码的每个子字符串与字典文件中的字进行比较。
任何匹配都会导致密码被拒绝。
比较不区分大小写。
因为
VALIDATE_PASSWORD_STRENGTH()
,根据所有策略检查密码,包括
STRONG
,因此强度评估包括字典检查,无论
validate_password.policy
值
如何
。
validate_password.dictionary_file
可以在运行时设置,并且分配值会导致在不重新启动服务器的情况下读取指定的文件。
属性 | 值 |
---|---|
命令行格式 | --validate-password.length=# |
介绍 | 8.0.4 |
系统变量 | validate_password.length |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 8 |
最低价值 | 0 |
validate_password
需要密码
的最小字符数
。
除非
validate_password
已安装,
否则此变量不可用
。
该
validate_password.length
最小值是其他几个相关的系统变量的函数。
该值不能设置为小于此表达式的值:
validate_password.number_count + validate_password.special_char_count +(2 * validate_password.mixed_case_count)
如果
validate_password
调整
validate_password.length
由于前面的约束而导致
的值
,则会将消息写入错误日志。
validate_password.mixed_case_count
属性 | 值 |
---|---|
命令行格式 | --validate-password.mixed-case-count=# |
介绍 | 8.0.4 |
系统变量 | validate_password.mixed_case_count |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 1 |
最低价值 | 0 |
validate_password
如果密码策略是
MEDIUM
强或更强
,则
需要密码
的小写和大写字符的最小数量
。
除非
validate_password
已安装,
否则此变量不可用
。
对于给定
validate_password.mixed_case_count
值,密码必须包含许多小写字符和许多大写字符。
validate_password.number_count
属性 | 值 |
---|---|
命令行格式 | --validate-password.number-count=# |
介绍 | 8.0.4 |
系统变量 | validate_password.number_count |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 1 |
最低价值 | 0 |
validate_password
密码策略为
MEDIUM
或更强时
,
需要密码
的最小数字(数字)字符数
。
除非
validate_password
已安装,
否则此变量不可用
。
属性 | 值 |
---|---|
命令行格式 | --validate-password.policy=value |
介绍 | 8.0.4 |
系统变量 | validate_password.policy |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 列举 |
默认值 | 1 |
有效值 |
|
密码策略强制执行
validate_password
。
除非
validate_password
已安装,
否则此变量不可用
。
validate_password.policy
影响如何
validate_password
使用其他策略设置系统变量,除了检查用户名的密码,由用户名独立控制
validate_password.check_user_name
。
的
validate_password.policy
可使用的数值0,1,2,或相应的符号值来指定值
LOW
,
MEDIUM
,
STRONG
。
下表描述了为每个策略执行的测试。
对于长度测试,所需长度是
validate_password.length
系统变量
的值
。
同样,其他测试所需的值由其他
变量
给出
。
validate_password.
xxx
政策 | 测试已执行 |
---|---|
0
要么
LOW
|
长度 |
1
要么
MEDIUM
|
长度; 数字,小写/大写和特殊字符 |
2
要么
STRONG
|
长度; 数字,小写/大写和特殊字符; 字典文件 |
validate_password.special_char_count
属性 | 值 |
---|---|
命令行格式 | --validate-password.special-char-count=# |
介绍 | 8.0.4 |
系统变量 | validate_password.special_char_count |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 1 |
最低价值 | 0 |
validate_password
如果密码策略是
MEDIUM
强或更强
,则
需要密码
的非字母数字字符的最小数量
。
除非
validate_password
已安装,
否则此变量不可用
。
如果
validate_password
组件已启用,则会公开提供操作信息的状态变量:
MySQL的> SHOW STATUS LIKE 'validate_password.%';
+ ----------------------------------------------- + - -------------------- +
| Variable_name | 价值|
+ ----------------------------------------------- + - -------------------- +
| validate_password.dictionary_file_last_parsed | 2018-01-15 08:33:49 |
| validate_password.dictionary_file_words_count | 1902年|
+ ----------------------------------------------- + - -------------------- +
以下列表描述了每个状态变量的含义。
validate_password.dictionary_file_last_parsed
上次解析字典文件时。
除非
validate_password
已安装,
否则此变量不可用
。
validate_password.dictionary_file_words_count
从字典文件中读取的字数。
除非
validate_password
已安装,
否则此变量不可用
。
在MySQL 8.0.4中,
validate_password
插件重新实现为
validate_password
组件。
该
validate_password
插件已弃用,将在未来的MySQL版本中删除。
因此,其选项也已弃用,将被删除。
使用该插件的MySQL安装应该转换为使用该组件。
请参见
第6.4.3.3节“转换到密码验证组件”
。
要控制
validate_password
插件的
激活
,请使用此选项:
属性 | 值 |
---|---|
命令行格式 | --validate-password[=value] |
类型 | 列举 |
默认值 | ON |
有效值 |
|
此选项控制服务器
validate_password
在启动时
加载已弃用的
插件的方式。
该值应该是可用于插件加载选项的值之一,如
第5.6.1节“安装和卸载插件”中所述
。
例如,
--validate-password=FORCE_PLUS_PERMANENT
告诉服务器在启动时加载插件并防止在服务器运行时删除它。
仅当
validate_password
插件先前已注册
INSTALL
PLUGIN
或已加载时,
此选项才可
用
--plugin-load-add
。
请参见
第6.4.3.1节“密码验证组件安装和卸载”
。
在MySQL 8.0.4中,
validate_password
插件重新实现为
validate_password
组件。
该
validate_password
插件已弃用,将在未来的MySQL版本中删除。
因此,它的系统变量也已弃用,将被删除。
使用
validate_password
组件
的相应系统变量
;
请参阅
密码验证组件系统变量
。
使用该插件的MySQL安装应该转换为使用该组件。
请参见
第6.4.3.3节“转换到密码验证组件”
。
validate_password_check_user_name
属性 | 值 |
---|---|
命令行格式 | --validate-password-check-user-name[={OFF|ON}] |
系统变量 | validate_password_check_user_name |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 布尔 |
默认值 | ON |
此
validate_password
插件系统变量已弃用,将在未来的MySQL版本中删除。
请改用
组件
的相应
validate_password.check_user_name
系统变量
validate_password
。
validate_password_dictionary_file
属性 | 值 |
---|---|
命令行格式 | --validate-password-dictionary-file=file_name |
系统变量 | validate_password_dictionary_file |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 文件名 |
此
validate_password
插件系统变量已弃用,将在未来的MySQL版本中删除。
请改用
组件
的相应
validate_password.dictionary_file
系统变量
validate_password
。
属性 | 值 |
---|---|
命令行格式 | --validate-password-length=# |
系统变量 | validate_password_length |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 8 |
最低价值 | 0 |
此
validate_password
插件系统变量已弃用,将在未来的MySQL版本中删除。
请改用
组件
的相应
validate_password.length
系统变量
validate_password
。
validate_password_mixed_case_count
属性 | 值 |
---|---|
命令行格式 | --validate-password-mixed-case-count=# |
系统变量 | validate_password_mixed_case_count |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 1 |
最低价值 | 0 |
此
validate_password
插件系统变量已弃用,将在未来的MySQL版本中删除。
请改用
组件
的相应
validate_password.mixed_case_count
系统变量
validate_password
。
validate_password_number_count
属性 | 值 |
---|---|
命令行格式 | --validate-password-number-count=# |
系统变量 | validate_password_number_count |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 1 |
最低价值 | 0 |
此
validate_password
插件系统变量已弃用,将在未来的MySQL版本中删除。
请改用
组件
的相应
validate_password.number_count
系统变量
validate_password
。
属性 | 值 |
---|---|
命令行格式 | --validate-password-policy=value |
系统变量 | validate_password_policy |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 列举 |
默认值 | 1 |
有效值 |
|
此
validate_password
插件系统变量已弃用,将在未来的MySQL版本中删除。
请改用
组件
的相应
validate_password.policy
系统变量
validate_password
。
validate_password_special_char_count
属性 | 值 |
---|---|
命令行格式 | --validate-password-special-char-count=# |
系统变量 | validate_password_special_char_count |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 1 |
最低价值 | 0 |
此
validate_password
插件系统变量已弃用,将在未来的MySQL版本中删除。
请改用
组件
的相应
validate_password.special_char_count
系统变量
validate_password
。
在MySQL 8.0.4中,
validate_password
插件重新实现为
validate_password
组件。
该
validate_password
插件已弃用,将在未来的MySQL版本中删除。
因此,其状态变量也已弃用,将被删除。
使用
validate_password
组件
的相应状态变量
;
请参阅
密码验证组件状态变量
。
使用该插件的MySQL安装应该转换为使用该组件。
请参见
第6.4.3.3节“转换到密码验证组件”
。
validate_password_dictionary_file_last_parsed
此
validate_password
插件状态变量已弃用,将在MySQL的未来版本中删除。
请改用
组件
的相应
validate_password.dictionary_file_last_parsed
状态变量
validate_password
。
validate_password_dictionary_file_words_count
此
validate_password
插件状态变量已弃用,将在MySQL的未来版本中删除。
请改用
组件
的相应
validate_password.dictionary_file_words_count
状态变量
validate_password
。
在MySQL 8.0.4中,
validate_password
插件重新实现为
validate_password
组件。
该
validate_password
插件已弃用,将在未来的MySQL版本中删除。
当前使用该
validate_password
插件的
MySQL安装
应该转换为使用该
validate_password
组件。
为此,请使用以下过程。
该过程在卸载插件之前安装组件,以避免出现没有密码验证的时间窗口。
(组件和插件可以同时安装。在这种情况下,服务器会尝试使用该组件,如果组件不可用,则回退到插件。)
安装
validate_password
组件:
INSTALL COMPONENT'file:// component_validate_password';
测试
validate_password
组件以确保它按预期工作。
如果需要设置任何
系统变量,可以在运行时使用
。
(必须在下一步中执行必须进行的任何选项文件更改。)
validate_password.
xxx
SET
GLOBAL
调整对插件系统和状态变量的任何引用,以引用相应的组件系统和状态变量。 假设您在启动时使用如下选项文件配置插件:
的[mysqld] 验证密码= FORCE_PLUS_PERMANENT validate_password_dictionary_file =的/ usr /共享/字典/字 validate_password_length = 10 validate_password_number_count = 2
要调整选项文件,请省略该
--validate-password
选项(它仅适用于插件,而不是组件),并修改系统变量引用:
的[mysqld] validate_password.dictionary_file =的/ usr /共享/字典/字 validate_password.length = 10 validate_password.number_count = 2
对于在运行时引用
validate_password
插件系统和状态变量的
应用程序,需要进行类似的调整
。
卸载
validate_password
插件:
UNINSTALL PLUGIN validate_password;
如果
validate_password
使用
--plugin-load
或
--plugin-load-add
选项
在服务器启动时加载插件
,请从服务器启动过程中省略该选项。
例如,如果该选项列在服务器选项文件中,请将其从文件中删除。
重启服务器。
MySQL服务器支持密钥环,使内部服务器组件和插件能够安全地存储敏感信息,以便以后检索。 该实现是基于插件的:
该
keyring_file
插件将密钥环数据存储在服务器主机本地的文件中。
此插件适用于所有MySQL发行版,包括Community Edition和Enterprise Edition。
请参见
第6.4.4.2节“使用keyring_file基于文件的插件”
。
该
keyring_encrypted_file
插件将密钥环数据存储在服务器主机本地的加密文件中。
此插件在MySQL Enterprise Edition发行版中提供。
请参见
第6.4.4.3节“使用keyring_encrypted_file密钥环插件”
。
keyring_okv
是一个KMIP 1.1插件,用于与KMIP兼容的后端密钥环存储产品,如Oracle Key Vault和Gemalto SafeNet
KeySecure Appliance。
此插件在MySQL Enterprise Edition发行版中提供。
请参见
第6.4.4.4节“使用keyring_okv KMIP插件”
。
该
keyring_aws
插件与Amazon Web Services密钥管理服务进行通信以生成密钥,并使用本地文件进行密钥存储。
此插件在MySQL Enterprise Edition发行版中提供。
请参见
第6.4.4.5节“使用keyring_aws Amazon Web Services密钥环插件”
。
MySQL服务器操作模式允许在底层密钥环密钥库之间迁移密钥。 这使DBA能够将MySQL安装从一个密钥环插件切换到另一个密钥环插件。 请参见 第6.4.4.6节“在密钥环密钥库之间迁移密钥” 。
用于密钥环密钥管理的SQL接口实现为一组用户定义的函数(UDF)。 请参见 第6.4.4.8节“通用密钥环密钥管理功能” 。
从MySQL 8.0.16开始,该
keyring_keys
表公开了密钥环中密钥的元数据。
关键元数据包括密钥ID,密钥所有者和后端密钥ID。
该
keyring_keys
表不公开任何敏感密钥环数据,如密钥内容。
请参见
第26.12.17.2节“keyring_keys表”
。
该
keyring_file
和
keyring_encrypted_file
加密密钥管理插件不打算作为一个合规性解决方案。
PCI,FIPS等安全标准要求使用密钥管理系统来保护,管理和保护密钥保险库或硬件安全模块(HSM)中的加密密钥。
MySQL中密钥环的用途包括:
该
InnoDB
存储引擎使用密钥环存储它的表空间加密密钥。
InnoDB
可以使用任何支持的密钥环插件。
MySQL Enterprise Audit使用密钥环存储审核日志文件加密密码。 审核日志插件可以使用任何支持的密钥环插件。
为MySQL服务器激活二进制日志加密时(通过设置)
binlog_encryption=ON
),用于加密二进制日志文件和中继日志文件的文件密码的二进制日志加密密钥存储在密钥环中。
任何支持的密钥环插件都可用于存储二进制日志加密密钥。
只要服务器上有使用它们加密的文件,就会保留二进制日志加密密钥。
手动轮换二进制日志主密钥时,将从密钥环中清除不再应用于任何保留的二进制日志文件或中继日志文件的所有二进制日志加密密钥。
如果无法初始化保留的二进制日志文件或中继日志文件以进行重新加密,则不会删除相关的二进制日志加密密钥,以防将来恢复文件。
例如,
如果二进制日志索引文件中列出的文件当前不可读,或者通道初始化失败,则可能出现这种情况。
有关更多信息,请参阅
第17.3.10节“加密二进制日志文件和中继日志文件”
。
有关一般密钥环安装说明,请参见 第6.4.4.1节“密钥环插件安装” 。 有关给定密钥环插件的特定信息,请参阅描述该插件的部分。
有关使用密钥环UDF的信息,请参见 第6.4.4.8节“通用密钥环密钥管理功能” 。
密钥环插件和UDF访问密钥环服务,该服务为密钥环提供服务器组件的接口。 有关访问密钥环插件服务和编写密钥环插件的信息,请参见 第29.3.2节“密钥环服务” 和 第29.2.4.12节“编写密钥环插件” 。
密钥环服务消费者需要安装密钥环插件。 MySQL提供以下插件选择:
keyring_file
:一个插件,用于将密钥环数据存储在服务器主机本地的文件中。
适用于所有MySQL发行版。
keyring_encrypted_file
:一个插件,用于将密钥环数据存储在服务器主机本地的加密文件中。
可在MySQL Enterprise Edition发行版中使用。
keyring_okv
:使用与KMIP兼容的后端密钥环存储产品(如Oracle Key Vault和Gemalto SafeNet KeySecure
Appliance)的插件。
可在MySQL Enterprise Edition发行版中使用。
keyring_aws
:与Amazon Web Services密钥管理服务通信的插件,作为密钥生成的后端,并使用本地文件进行密钥存储。
可在MySQL Enterprise Edition发行版中使用。
本节介绍如何安装您选择的密钥环插件。 有关安装插件的一般信息,请参见 第5.6.1节“安装和卸载插件” 。
如果您打算将密钥环用户定义函数(UDF)与密钥环插件结合使用,请使用 第6.4.4.8节“通用密钥环密钥管理功能”中 的说明在安装密钥环之后安装UDF 。
要使服务器可以使用,插件库文件必须位于MySQL插件目录(
plugin_dir
系统变量
指定的目录
)中。
如有必要,通过设置
plugin_dir
服务器启动时
的值来配置插件目录位置
。
每个密钥环插件的安装类似。
以下说明使用
keyring_file
。
不同密钥环插件的用户可以替换其名称
keyring_file
。
该
keyring_file
插件的库文件基本名称是
keyring_file
。
文件名后缀因平台
.so
而异
(例如,
对于Unix和类Unix系统,
.dll
对于Windows)。
一次只能启用一个密钥环插件。 不支持启用多个密钥环插件,结果可能与预期不符。
必须在服务器启动序列期间尽早加载密钥环插件,以便服务器组件可以在自己的初始化期间根据需要访问它。
例如,
InnoDB
存储引擎使用密钥环进行表空间加密,因此必须在
InnoDB
初始化
之前加载密钥环插件并使其可用
。
要加载插件,请使用该
--early-plugin-load
选项命名包含它的插件库文件。
例如,在插件库文件后缀为的平台上
.so
,在服务器
my.cnf
文件中
使用这些行
(
.so
根据需要
调整
平台
的
后缀):
的[mysqld] 早期插件负荷= keyring_file.so
在启动服务器之前,请检查所选密钥环插件的注释,以查看它是否允许或需要其他配置:
对于
keyring_file
:
第6.4.4.2节“使用keyring_file基于文件的插件”
。
对于
keyring_okv
:
第6.4.4.4节“使用keyring_okv KMIP插件”
。
对于
keyring_aws
:
第6.4.4.5节“使用keyring_aws Amazon Web Services Keyring插件”
执行任何特定于插件的配置后,请验证插件安装。
在MySQL服务器运行时,检查
INFORMATION_SCHEMA.PLUGINS
表或使用该
SHOW PLUGINS
语句(请参见
第5.6.2节“获取服务器插件信息”
)。
例如:
MySQL的>SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE 'keyring%';
+ -------------- + --------------- + | PLUGIN_NAME | PLUGIN_STATUS | + -------------- + --------------- + | keyring_file | ACTIVE | + -------------- + --------------- +
如果插件无法初始化,请检查服务器错误日志以获取诊断消息。
如果服务器组件尝试访问密钥环服务时没有密钥环插件可用,则该组件不能使用该服务。
因此,组件可能无法初始化或可能使用有限的功能进行初始化。
例如,如果
InnoDB
在初始化时发现存在加密表空间,则会尝试访问密钥环。
如果密钥环不可用,则
InnoDB
只能访问未加密的表空间。
要确保也
InnoDB
可以访问加密的表空间,请使用
--early-plugin-load
加载密钥环插件。
插件可以通过其他方法加载,例如
--plugin-load
或
--plugin-load-add
选项或
INSTALL PLUGIN
语句。
但是,对于某些服务器组件,使用这些方法加载的密钥环插件可能在服务器启动顺序中可用得太晚,例如
InnoDB
:
插件加载使用
--plugin-load
或
初始化
--plugin-load-add
后发生
InnoDB
。
使用的插件
INSTALL
PLUGIN
在
mysql.plugin
系统表
中注册
并自动加载,以便后续重新启动服务器。
但是,因为
mysql.plugin
是一个
InnoDB
表,所以在启动期间只能在
InnoDB
初始化
之后加载其中指定的任何插件
。
该
keyring_file
插件是一个密钥环插件,用于将密钥环数据存储在服务器主机本地的文件中。
keyring_file
用于加密密钥管理
的
插件不是作为法规遵从性解决方案。
PCI,FIPS等安全标准要求使用密钥管理系统来保护,管理和保护密钥保险库或硬件安全模块(HSM)中的加密密钥。
要安装
keyring_file
插件,请使用
第6.4.4.1节“密钥环插件安装”中
的常规密钥环安装说明
以及
keyring_file
此处的
特定配置信息
。
要在服务器启动过程中使用,
keyring_file
必须使用该
--early-plugin-load
选项
加载
。
所述
keyring_file_data
系统变量任选配置由所使用的文件的位置
keyring_file
的插件用于数据存储。
默认值是特定于平台的。
要显式配置文件位置,请在启动时设置变量值。
例如,在服务器
my.cnf
文件中
使用这些行
(
.so
根据需要
调整平台的
后缀和文件位置):
的[mysqld] 早期插件负荷= keyring_file.so keyring_file_data =的/ usr /本地/ MySQL的/ MySQL的-钥匙圈/钥匙圈
密钥环操作是事务性的:
keyring_file
插件在写入操作期间使用备份文件,以确保在操作失败时它可以回滚到原始文件。
备份文件的名称与
keyring_file_data
系统变量
的值相同
,后缀为
.backup
。
有关其他信息
keyring_file_data
,请参见
第6.4.4.11节“密钥环系统变量”
。
要确保仅在存在正确的密钥环存储文件时刷新
keyring_file
密钥,请在文件中存储
密钥环
的SHA-256校验和。
在更新文件之前,插件会验证它是否包含预期的校验和。
该
keyring_file
插件支持组成标准密钥环服务接口的功能。
这些功能执行的密钥环操作可在两个级别访问:
SQL接口:在SQL语句中,调用 第6.4.4.8节“通用密钥环密钥管理功能”中 描述的用户定义函数(UDF) 。
C接口:在C语言代码中,调用 第29.3.2节“密钥环服务”中 描述的密钥环服务功能 。
示例(使用UDF):
SELECT keyring_key_generate('MyKey','AES',32); SELECT keyring_key_remove('MyKey');
允许的密钥类型
keyring_file
在
第6.4.4.7节“支持的密钥环密钥类型”中描述
。
该
keyring_encrypted_file
插件是MySQL企业版(一种商业产品)中包含的扩展。
要了解有关商业产品的更多信息,请访问
https://www.mysql.com/products/
。
该
keyring_encrypted_file
插件是一个密钥环插件,用于将密钥环数据存储在服务器主机本地的加密文件中。
这个插件从MySQL 5.7.21开始提供。
keyring_encrypted_file
用于加密密钥管理
的
插件不是作为法规遵从性解决方案。
PCI,FIPS等安全标准要求使用密钥管理系统来保护,管理和保护密钥保险库或硬件安全模块(HSM)中的加密密钥。
要安装
keyring_encrypted_file
插件,请使用
第6.4.4.1节“密钥环插件安装”中
的常规密钥环安装说明
以及
keyring_encrypted_file
此处的
特定配置信息
。
要在服务器启动过程中使用,
keyring_encrypted_file
必须使用该
--early-plugin-load
选项
加载
。
要指定加密密钥环数据文件的密码,请设置
keyring_encrypted_file_password
系统变量。
(密码是必需的;如果在服务器启动时未指定,则
keyring_encrypted_file
初始化失败。)
keyring_encrypted_file_data
系统变量可选地配置
keyring_encrypted_file
插件用于数据存储
的文件的位置
。
默认值是特定于平台的。
要显式配置文件位置,请在启动时设置变量值。
例如,在服务器
my.cnf
文件中
使用这些行
(调整
.so
根据需要为您的平台添加后缀和文件位置,并替换您选择的密码):
的[mysqld]
早期插件负荷= keyring_encrypted_file.so
keyring_encrypted_file_data =的/ usr /本地/ MySQL的/ MySQL的-钥匙圈/钥匙圈加密
keyring_encrypted_file_password =password
因为
my.cnf
文件在写入时存储密码,所以它应该具有限制模式,并且只能用于运行MySQL服务器的帐户。
密钥环操作是事务性的:
keyring_encrypted_file
插件在写入操作期间使用备份文件,以确保在操作失败时它可以回滚到原始文件。
备份文件的名称与
keyring_encrypted_file_data
系统变量
的值相同
,后缀为
.backup
。
有关用于配置
keyring_encrypted_file
插件
的系统变量的其他信息
,请参见
第6.4.4.11节“密钥环系统变量”
。
要确保仅在存在正确的密钥环存储文件时刷新
keyring_encrypted_file
密钥,请在文件中存储
密钥环
的SHA-256校验和。
在更新文件之前,插件会验证它是否包含预期的校验和。
另外,
keyring_encrypted_file
在写入文件之前使用AES加密文件内容,并在读取文件之后解密文件内容。
该
keyring_encrypted_file
插件支持组成标准密钥环服务接口的功能。
这些功能执行的密钥环操作可在两个级别访问:
SQL接口:在SQL语句中,调用 第6.4.4.8节“通用密钥环密钥管理功能”中 描述的用户定义函数(UDF) 。
C接口:在C语言代码中,调用 第29.3.2节“密钥环服务”中 描述的密钥环服务功能 。
示例(使用UDF):
SELECT keyring_key_generate('MyKey','AES',32); SELECT keyring_key_remove('MyKey');
允许的密钥类型
keyring_encrypted_file
在
第6.4.4.7节“支持的密钥环密钥类型”中描述
。
该
keyring_okv
插件是MySQL企业版(一种商业产品)中包含的扩展。
要了解有关商业产品的更多信息,请访问
https://www.mysql.com/products/
。
密钥管理互操作性协议(KMIP)支持密钥管理服务器与其客户端之间的加密密钥通信。
的
keyring_okv
密钥环插件使用KMIP 1.1协议作为一个KMIP后端的一个客户端安全地通信。
钥匙圈材料仅由后端产生,而不是由后端产生
keyring_okv
。
该插件适用于这些与KMIP兼容的产品:
Oracle Key Vault
金雅拓SafeNet KeySecure设备
该
keyring_okv
插件支持组成标准密钥环服务接口的功能。
这些功能执行的密钥环操作可在两个级别访问:
SQL接口:在SQL语句中,调用 第6.4.4.8节“通用密钥环密钥管理功能”中 描述的用户定义函数(UDF) 。
C接口:在C语言代码中,调用 第29.3.2节“密钥环服务”中 描述的密钥环服务功能 。
示例(使用UDF):
SELECT keyring_key_generate('MyKey','AES',32); SELECT keyring_key_remove('MyKey');
允许的密钥类型
keyring_okv
在
第6.4.4.7节“支持的密钥环密钥类型”中描述
。
要安装
keyring_okv
插件,请使用
第6.4.4.1节“密钥环插件安装”中
的常规密钥环安装说明
以及
keyring_okv
此处的
特定配置信息
。
无论
keyring_okv
插件使用
哪个KMIP后端
进行密钥环存储,
keyring_okv_conf_dir
系统变量都会
keyring_okv
为其支持文件
配置所用目录的位置
。
默认值为空,因此在插件可以与KMIP后端通信之前,必须将变量设置为命名正确配置的目录。
除非您这样做,否则
keyring_okv
在服务器启动期间向错误日志写入一条消息,它无法通信:
[警告]插件keyring_okv报告:'对于keyring_okv来说 初始化后,请将keyring_okv_conf_dir变量指向一个目录 包含Oracle Key Vault配置文件和ssl材料'
该
keyring_okv_conf_dir
变量必须命名包含以下项目的目录:
okvclient.ora
:包含
keyring_okv
将与之通信
的KMIP后端的详细信息的文件
。
ssl
:包含证书,并建立与KMIP后端的安全连接所需的密钥文件的目录
CA.pem
,
cert.pem
和
key.pem
。
如果密钥文件受密码保护,则该
ssl
目录可以包含名为
password.txt
包含解密密钥文件所需密码
的单行文本
文件。
具有证书和密钥文件
的
okvclient.ora
文件和
ssl
目录都是
keyring_okv
正常工作
所必需的
。
用于使用这些文件填充配置目录的过程取决于与其一起使用的KMIP后端
keyring_okv
,如其他地方所述。
keyring_okv
作为其支持文件的位置
使用的配置目录
应具有限制模式,并且只能由用于运行MySQL服务器的帐户访问。
例如,在Unix和类Unix系统上,要使用该
/usr/local/mysql/mysql-keyring-okv
目录,以下命令(执行为
root
)创建目录并设置其模式和所有权:
cd / usr / local / mysql mkdir mysql-keyring-okv chmod 750 mysql-keyring-okv chown mysql mysql-keyring-okv chgrp mysql mysql-keyring-okv
要在服务器启动过程中使用,
keyring_okv
必须使用该
--early-plugin-load
选项
加载
。
另外,设置
keyring_okv_conf_dir
系统变量以告知
keyring_okv
在哪里可以找到其配置目录。
例如,在服务器
my.cnf
文件中
使用这些行
(
.so
根据需要
调整平台的
后缀和目录位置):
的[mysqld] 早期插件负荷= keyring_okv.so keyring_okv_conf_dir =的/ usr /本地/ MySQL的/ MySQL的-钥匙圈 - OKV
有关其他信息
keyring_okv_conf_dir
,请参见
第6.4.4.11节“密钥环系统变量”
。
此处的讨论假定您熟悉Oracle Key Vault。 一些相关的信息来源:
在Oracle Key Vault术语中,使用Oracle Key Vault存储和检索安全对象的客户端称为端点。 要与Oracle Key Vault通信,必须注册为端点并通过下载和安装端点支持文件进行注册。
以下过程简要总结了设置
keyring_okv
与Oracle Key Vault一起使用
的过程
:
为
keyring_okv
要使用
的
插件
创建配置目录
。
使用Oracle Key Vault注册端点以获取注册令牌。
使用注册令牌获取
okvclient.jar
客户端软件下载。
安装客户端软件以填充
keyring_okv
包含Oracle Key Vault支持文件
的
配置目录。
使用以下过程配置
keyring_okv
Oracle Key Vault以协同工作。
此说明仅总结了如何与Oracle Key Vault交互。
有关详细信息,请访问
Oracle Key Vault
站点并查阅Oracle Key Vault管理员指南。
创建将包含Oracle Key Vault支持文件的配置目录,并确保将
keyring_okv_conf_dir
系统变量设置为命名该目录(有关详细信息,请参阅
常规keyring_okv配置
)。
以具有系统管理员角色的用户身份登录Oracle Key Vault管理控制台。
选择Endpoints选项卡以到达Endpoints页面。 在“端点”页面上,单击“添加”。
提供所需的端点信息,然后单击“注册” 端点类型应为Other。 成功注册会产生注册令牌。
从Oracle Key Vault服务器注销。
再次连接到Oracle Key Vault服务器,这次没有登录。使用端点注册令牌注册并请求
okvclient.jar
软件下载。
将此文件保存到您的系统。
okvclient.jar
使用以下命令
安装
文件(您必须具有JDK 1.4或更高版本):
java -jar okvclient.jar -d dir_name
[-v]
该
-d
选项
后面的目录名称
是安装解压缩文件的位置。
-v
如果给定
该
选项,则会生成日志信息,如果命令失败,则可能会有用。
当命令要求提供Oracle Key Vault端点密码时,请不要提供密码。 而是,按Enter键。 (结果是端点连接到Oracle Key Vault时不需要密码。)
上面的命令生成一个
okvclient.ora
文件,该文件应
-d
位于前面的
java -jar
命令中
选项所
指定的目录下的此位置
:
INSTALL_DIR / CONF / okvclient.ora
文件内容包括如下所示的行:
SERVER =host_ip
:port_num
STANDBY_SERVER =host_ip
:port_num
该
keyring_okv
插件试图与服务器通过指定的主机上运行的沟通
SERVER
变回退到
STANDBY_SERVER
如果失败:
对于
SERVER
变量,
okvclient.ora
文件中
的设置
是必需的。
对于
STANDBY_SERVER
变量,
okvclient.ora
文件中
的设置
是可选的。
转到Oracle Key Vault安装程序目录并通过运行以下命令测试设置:
okvutil / bin / okvutil list
输出应该如下所示:
唯一ID类型标识符 255AB8DE-C97F-482C-E053-0100007F28B9对称键 - 264BF6E0-A20E-7C42-E053-0100007FB29C对称密钥 -
对于新的Oracle Key Vault服务器(没有任何密钥的服务器),输出看起来像这样,表示Vault中没有密钥:
找不到任何物体
使用此命令
ssl
从
okvclient.jar
文件中
提取
包含SSL材料的
目录:
jar xf okvclient.jar ssl
将Oracle Key Vault支持文件(
okvclient.ora
文件和
ssl
目录)
复制
到配置目录中。
(可选)如果要对密钥文件进行密码保护,请使用 密码保护keyring_okv密钥文件中的说明 。
完成上述步骤后,重启MySQL服务器。
它加载
keyring_okv
插件并
keyring_okv
使用其配置目录中的文件与Oracle Key Vault进行通信。
金雅拓SafeNet KeySecure设备使用KMIP协议(版本1.1或1.2)。
的
keyring_okv
密钥环插件(它支持KMIP 1.1)可以使用KeySecure作为钥匙圈存储其KMIP后端。
使用以下过程配置
keyring_okv
和KeySecure一起工作。
该描述仅总结了如何与KeySecure进行交互。
有关详细信息,请参阅“
KeySecure用户指南”中的“
添加KMIP服务器
”一节
。
创建将包含KeySecure支持文件的配置目录,并确保将
keyring_okv_conf_dir
系统变量设置为命名该目录(有关详细信息,请参阅
常规keyring_okv配置
)。
在配置目录中,创建一个名为“
ssl
用于存储所需SSL证书和密钥文件”
的子目录
。
在配置目录中,创建一个名为的文件
okvclient.ora
。
它应该具有以下格式:
SERVER =host_ip
:port_num
STANDBY_SERVER =host_ip
:port_num
例如,如果KeySecure在主机198.51.100.20上运行并侦听端口9002,则
okvclient.ora
文件如下所示:
SERVER = 198.51.100.20:9002 STANDBY_SERVER = 198.51.100.20:9002
以管理员身份连接到KeySecure管理控制台,并具有证书颁发机构访问权限的凭据。
导航到安全>>本地CA并创建本地证书颁发机构(CA)。
转到可信CA列表。 选择Default,然后单击Properties。 然后选择“编辑可信证书颁发机构列表”并添加刚刚创建的CA.
下载CA并将其
ssl
作为名为的文件
保存在
目录中
CA.pem
。
导航到安全>>证书请求并创建证书。 然后,您将能够下载 包含证书PEM文件 的压缩 tar 文件。
从下载的文件中提取PEM文件。
例如,如果文件名是
csr_w_pk_pkcs8.gz
,则使用以下命令对其进行解压缩和解压缩:
tar zxvf csr_w_pk_pkcs8.gz
提取操作产生两个文件:
certificate_request.pem
和
private_key_pkcs8.pem
。
使用此
openssl
命令解密私钥并创建名为的文件
key.pem
:
openssl pkcs8 -in private_key_pkcs8.pem -out key.pem
将
key.pem
文件
复制
到
ssl
目录中。
将证书请求复制
certificate_request.pem
到剪贴板中。
导航到安全>>本地CA.
选择您之前创建的CA(您下载的用于创建
CA.pem
文件的
CA
),然后单击“签名请求”。
从剪贴板粘贴证书请求,选择客户端的证书目的(密钥环是KeySecure的客户端),然后单击“签名请求”。
结果是在新页面中使用所选CA签名的证书。
签名的证书复制到剪贴板,然后将剪贴板中的内容保存为一个文件名为
cert.pem
在
ssl
目录中。
(可选)如果要对密钥文件进行密码保护,请使用 密码保护keyring_okv密钥文件中的说明 。
完成上述步骤后,重启MySQL服务器。
它加载
keyring_okv
插件并
keyring_okv
使用其配置目录中的文件与KeySecure进行通信。
您可以选择使用密码保护密钥文件,并提供包含密码的文件以使密钥文件能够被解密。
为此,请将位置更改为
ssl
目录并执行以下步骤:
加密
key.pem
密钥文件。
例如,使用这样的命令,并在提示符处输入加密密码:
外壳> openssl rsa -des3 -in key.pem -out key.pem.new
输入PEM密码短语:
验证 - 输入PEM密码短语:
将加密密码保存
password.txt
在
ssl
目录中
指定的单行文本文件
中
。
验证是否可以使用以下命令解密加密的密钥文件。 解密的文件应显示在控制台上:
外壳> openssl rsa -in key.pem.new -passin file:password.txt
删除原始
key.pem
文件并重命名
key.pem.new
为
key.pem
。
根据需要更改新
key.pem
文件和
password.txt
文件
的所有权和访问模式,
以确保它们与
ssl
目录中的
其他文件具有相同的限制
。
该
keyring_aws
插件是MySQL企业版(一种商业产品)中包含的扩展。
要了解有关商业产品的更多信息,请访问
https://www.mysql.com/products/
。
该
keyring_aws
插件是一个密钥环插件,它与Amazon Web Services密钥管理服务(AWS
KMS)通信,作为密钥生成的后端,并使用本地文件进行密钥存储。
所有密钥环材料都由AWS服务器专门生成,而不是由
keyring_aws
。
keyring_aws
可在以下平台上使用:
Debian 8
EL7
macOS 10.13和10.14
SLES 12
Ubuntu 14.04和16.04
视窗
此处的讨论假设您熟悉AWS,特别是KMS。 一些相关的信息来源:
以下部分提供
keyring_aws
密钥环插件的
配置和使用信息
:
要安装
keyring_aws
插件,请使用
第6.4.4.1节“密钥环插件安装”中
的常规安装说明
以及此处的插件特定配置信息。
插件库文件包含
keyring_aws
插件和两个用户定义的函数(UDF),
keyring_aws_rotate_cmk()
以及
keyring_aws_rotate_keys()
。
要进行配置
keyring_aws
,您必须获取秘密访问密钥,该密钥提供与AWS KMS通信的凭据并将其写入配置文件:
创建AWS KMS帐户。
使用AWS KMS创建秘密访问密钥ID和秘密访问密钥。 访问密钥用于验证您和您的应用程序的身份。
使用AWS KMS帐户创建客户主密钥(CMK)ID。
在MySQL启动时,将
keyring_aws_cmk_id
系统变量设置为CMK ID值。
此变量是必需的,没有默认值。
(如果需要,可以在运行时更改其值
SET
GLOBAL
。)
如有必要,请创建配置文件所在的目录。
该目录应具有限制模式,并且只能用于运行MySQL服务器的帐户。
例如,在Unix和类Unix系统上,要
/usr/local/mysql/mysql-keyring/keyring_aws_conf
用作文件名,以下命令(执行为
root
)创建其父目录并设置目录模式和所有权:
shell>cd /usr/local/mysql
shell>mkdir mysql-keyring
shell>chmod 750 mysql-keyring
shell>chown mysql mysql-keyring
shell>chgrp mysql mysql-keyring
在MySQL启动时,将
keyring_aws_conf_file
系统变量
设置
为
/usr/local/mysql/mysql-keyring/keyring_aws_conf
以指示服务器的配置文件位置。
准备
keyring_aws
配置文件,该文件应包含两行:
第1行:秘密访问密钥ID
第2行:秘密访问密钥
例如,如果密钥ID是
wwwwwwwwwwwwwEXAMPLE
密钥
xxxxxxxxxxxxx/yyyyyyy/zzzzzzzzEXAMPLEKEY
,则配置文件如下所示:
wwwwwwwwwwwwwEXAMPLE XXXXXXXXXXXXX / YYYYYYY / zzzzzzzzEXAMPLEKEY
要在服务器启动过程中使用,
keyring_aws
必须使用该
--early-plugin-load
选项
加载
。
所述
keyring_aws_cmk_id
系统变量是强制性的,构成从AWS KMS服务器获得的顾客主密钥(CMK)的标识。
的
keyring_aws_conf_file
和
keyring_aws_data_file
系统变量有选择地配置由所使用的文件的位置
keyring_aws
插件配置信息和数据的存储。
文件位置变量默认值是特定于平台的。
要显式配置位置,请在启动时设置变量值。
例如,在服务器
my.cnf
文件中
使用这些行
(调整
.so
必要时,为您的平台添加后缀和文件位置):
的[mysqld] 早期插件负荷= keyring_aws.so keyring_aws_cmk_id = '阿尔恩:AWS:公里:美西2:111122223333:键/ ABCD1234-ef56-AB12-CD34-ef56abcd1234' keyring_aws_conf_file =的/ usr /本地/ MySQL的/ MySQL的-钥匙圈/ keyring_aws_conf keyring_aws_data_file =的/ usr /本地/ MySQL的/ MySQL的-钥匙圈/ keyring_aws_data
要使
keyring_aws
插件成功启动,配置文件必须存在并包含有效的秘密访问密钥信息,如前所述进行初始化。
存储文件不需要存在。
如果没有,
keyring_aws
尝试创建它(如果需要,还可以创建其父目录)。
有关用于配置
keyring_aws
插件
的系统变量的其他信息
,请参见
第6.4.4.11节“密钥环系统变量”
。
启动MySQL服务器并安装与
keyring_aws
插件
关联的UDF
。
这是一次性操作,通过执行以下语句执行(
.so
根据需要
调整
平台
的
后缀):
创建功能keyring_aws_rotate_cmk RETURNS INTEGER SONAME'keyring_aws.so'; 创建功能keyring_aws_rotate_keys返回INTEGER SONAME'keyring_aws.so';
在插件启动时,
keyring_aws
插件从其配置文件中读取AWS秘密访问密钥ID和密钥。
它还将其存储文件中包含的任何加密密钥读入其内存缓存中。
在操作期间,
keyring_aws
在内存缓存中维护加密密钥,并将存储文件用作本地永久存储。
每个密钥环操作都是事务性的:
keyring_aws
要么成功地更改内存中的密钥缓存和密钥环存储文件,要么操作失败并且密钥环状态保持不变。
要确保仅在存在正确的密钥环存储文件时刷新
keyring_aws
密钥,请在文件中存储
密钥环
的SHA-256校验和。
在更新文件之前,插件会验证它是否包含预期的校验和。
该
keyring_aws
插件支持组成标准密钥环服务接口的功能。
这些功能执行的密钥环操作可在两个级别访问:
C接口:在C语言代码中,调用 第29.3.2节“密钥环服务”中 描述的密钥环服务功能 。
SQL接口:在SQL语句中,调用 第6.4.4.8节“通用密钥环密钥管理功能”中 描述的用户定义函数(UDF) 。
示例(使用UDF):
SELECT keyring_key_generate('MyKey','AES',32); SELECT keyring_key_remove('MyKey');
此外,
UDF
keyring_aws_rotate_cmk()
和“
keyring_aws_rotate_keys()
UDF
”“
扩展
”
密钥环插件接口,以提供标准密钥环服务接口未涵盖的AWS相关功能。
只有通过调用UDF才能访问这些功能。
没有相应的C语言密钥服务功能。
允许的密钥类型
keyring_aws
在
第6.4.4.7节“支持的密钥环密钥类型”中描述
。
假设
keyring_aws
插件在服务器启动时已正确初始化,则可以更改用于与AWS KMS通信的凭据:
使用AWS KMS创建新的秘密访问密钥ID和秘密访问密钥。
将新凭据存储在配置文件(
keyring_aws_conf_file
系统变量
指定的文件
)中。
文件格式如前所述。
重新初始化
keyring_aws
插件,以便重新读取配置文件。
假设新凭据有效,插件应该成功初始化。
有两种方法可以重新初始化插件:
重启服务器。 这样更简单,没有副作用,但不适合需要最少服务器停机且尽可能少重启的安装。
通过执行以下语句重新初始化插件而不重新启动服务器(
.so
根据需要
调整
平台
的
后缀):
UNINSTALL PLUGIN keyring_aws; 安装PLUGIN keyring_aws SONAME'keyring_aws.so';
除了在运行时加载插件外,
INSTALL PLUGIN
还有将插件注册到
mysql.plugin
系统表
中的副作用
。
因此,如果您决定停止使用
keyring_aws
,
--early-plugin-load
则从用于启动服务器的选项集中
删除该
选项
是不够
的。
这会阻止插件提前加载,但是当服务器到达启动序列中加载注册插件的点时,服务器仍会尝试加载它
mysql.plugin
。
因此,如果您执行
刚刚描述
的
UNINSTALL PLUGIN
加号
INSTALL PLUGIN
序列来更改AWS KMS凭据,然后停止使用
keyring_aws
,则
UNINSTALL
PLUGIN
除了删除
--early-plugin-load
选项
之外
,还需要
再次
执行
以取消注册该插件
。
MySQL服务器支持一种操作模式,可以在底层密钥环密钥库之间迁移密钥。 这使DBA能够将MySQL安装从一个密钥环插件切换到另一个密钥环插件。 迁移服务器(即,以密钥迁移模式启动的服务器)不接受客户端连接。 相反,它只运行足够长的时间来迁移密钥,然后退出。 迁移服务器向控制台报告错误(标准错误输出)。
可以执行脱机或在线密钥迁移:
如果您确定本地主机上没有正在运行的服务器正在使用源或目标密钥库,则可以进行脱机迁移。 在这种情况下,迁移服务器可以修改密钥库,而无法在迁移期间运行服务器修改密钥库内容。
如果本地主机上正在运行的服务器正在使用源或目标密钥库,则必须执行联机迁移。 在这种情况下,迁移服务器连接到正在运行的服务器,并指示它在密钥迁移过程中暂停密钥环操作。
密钥迁移操作的结果是目标密钥库包含迁移之前的密钥以及源密钥库中的密钥。 源密钥库在迁移之前和之后是相同的,因为密钥是复制的,而不是移动的。 如果要复制的密钥已存在于目标密钥库中,则会发生错误,并且目标密钥库将还原到其预迁移状态。
在密钥迁移模式下调用服务器的用户不能是
root
操作系统用户,并且必须具有读取和写入密钥环文件的权限。
要执行密钥迁移操作,请确定需要哪些密钥迁移选项。 迁移选项指示涉及哪些密钥环插件,以及是否执行脱机或在线迁移:
要指示源和目标密钥环插件,请指定以下选项:
--keyring-migration-source
:源密钥环插件,用于管理要迁移的密钥。
--keyring-migration-destination
:要将迁移的密钥复制到的目标密钥环插件。
这些选项告诉服务器以密钥迁移模式运行。 所有关键迁移操作都必须使用这两个选项。 源插件和目标插件必须不同,迁移服务器必须支持这两个插件。
对于脱机迁移,不需要其他密钥迁移选项。
不要执行涉及正在运行的服务器正在使用的密钥库的脱机迁移。
对于联机迁移,某些正在运行的服务器当前正在使用源或目标密钥库。 指定指示如何连接到正在运行的服务器的密钥迁移选项。 这是必要的,以便迁移服务器可以连接到正在运行的服务器并告诉它在迁移操作期间暂停密钥环的使用。
使用以下任何选项表示在线迁移:
--keyring-migration-host
:正在运行的服务器所在的主机。
这始终是本地主机。
--keyring-migration-user
,
--keyring-migration-password
:用于连接到正在运行的服务器的帐户的用户名和密码。
--keyring-migration-port
:对于TCP / IP连接,要在正在运行的服务器上连接的端口号。
--keyring-migration-socket
:对于Unix套接字文件或Windows命名管道连接,要在正在运行的服务器上连接的套接字文件或命名管道。
有关密钥迁移选项的其他详细信息,请参见 第6.4.4.10节“密钥环命令选项” 。
使用刚才描述的密钥迁移选项启动迁移服务器,可能还有其他选项。 请记住以下注意事项:
可能需要其他服务器选项,例如两个密钥环插件的其他配置参数。
例如,如果
keyring_file
是其中一个插件,则必须
keyring_file_data
在密钥环数据文件位置不是默认位置时
设置
系统变量。
其他非密钥环选项也可能是必需的。
指定这些选项的一种方法是使用
--defaults-file
命名包含所需选项的选项文件。
如果从与通常用于运行MySQL的系统帐户不同的系统帐户调用迁移服务器,则可能会创建在正常操作期间服务器无法访问的密钥环目录或文件。
假设
mysqld
通常以
mysql
操作系统用户
身份
运行,但您在登录时调用迁移服务器
isabel
。
迁移服务器创建的任何新目录或文件都将归其所有
isabel
。
当服务器运行时,
mysql
操作系统用户尝试访问所拥有的文件系统对象
时,后续启动将失败
isabel
。
要避免此问题,请以
root
操作系统用户
身份启动迁移服务器,
并提供一个
选项,其中
通常用于运行MySQL的系统帐户。
--user=
user_name
user_name
迁移服务器期望路径名选项值为完整路径。 可能无法按预期解析相对路径名称。
脱机密钥迁移的示例命令行:
mysqld --defaults-file = / usr / local / mysql / etc / my.cnf
--keyring迁移源= keyring_file.so
--keyring迁移目的地= keyring_encrypted_file.so
--keyring_encrypted_file_password =password
在线密钥迁移的示例命令行:
mysqld --defaults-file = / usr / local / mysql / etc / my.cnf --keyring迁移源= keyring_file.so --keyring迁移目的地= keyring_encrypted_file.so --keyring_encrypted_file_password =password
--keyring迁移主机=本地主机 --keyring迁移用户=根 --keyring迁移密码=root_password
密钥迁移服务器执行迁移操作,如下所示:
(仅限联机迁移)使用连接选项连接到正在运行的服务器。
用于连接的帐户必须具有修改全局
keyring_operations
系统变量
所需的权限
(
ENCRYPTION_KEY_ADMIN
除了
SYSTEM_VARIABLES_ADMIN
或之外
SUPER
)。
(仅限联机迁移)
keyring_operations
在正在运行的服务器上
禁用
。
(正在运行的服务器必须支持
keyring_operations
。)
加载源和目标密钥环插件。
将密钥环中的密钥复制到目标密钥环。
卸载密钥环插件。
(仅限联机迁移)
keyring_operations
在正在运行的服务器上
启用
。
(仅限联机迁移)断开与正在运行的服务器的连接。
出口。
如果在密钥迁移期间发生错误,则会删除复制到目标插件的所有密钥,从而保持目标密钥库不变。
对于联机迁移操作,迁移服务器负责
keyring_operations
在正在运行的服务器上
启用和禁用
。
但是,如果迁移服务器异常退出(例如,如果有人强行终止它),则可能
keyring_operations
无法在正在运行的服务器上重新启用,从而无法执行密钥环操作。
在这种情况下,可能需要连接到正在运行的服务器并
keyring_operations
手动
启用
。
成功进行在线密钥迁移操作后,可能需要重新启动正在运行的服务器:
如果正在运行的服务器正在使用源密钥库,则无需在迁移后重新启动它。
如果正在运行的服务器在迁移之前使用源密钥库,但在迁移后应使用目标密钥库,则必须重新配置它以使用目标密钥环插件并重新启动。
如果正在运行的服务器正在使用目标密钥库并将继续使用它,则应在迁移后重新启动它以加载迁移到目标密钥库的所有密钥。
MySQL服务器密钥迁移模式支持暂停单个正在运行的服务器。 要在多个密钥服务器使用所涉及的密钥库时执行密钥迁移,请使用以下过程:
手动连接到每个正在运行的服务器,并设置
keyring_operations=OFF
。
使用迁移服务器执行脱机密钥迁移。
手动连接到每个正在运行的服务器,并设置
keyring_operations=ON
。
所有正在运行的服务器必须支持
keyring_operations=ON
系统变量
MySQL Keyring支持生成不同类型的密钥(加密算法)和长度。 可用的密钥类型取决于安装的密钥环插件。 给定插件还可以对每个键类型的键长度施加约束。
表6.26“密钥环插件密钥类型” 总结了每个密钥环插件允许的密钥类型。 长度以字节为单位。 对于使用 第6.4.4.8节“通用密钥环密钥管理函数”中 描述的密钥环用户定义函数(UDF)之一生成的密钥 ,由于UDF的限制,长度不能超过2,048字节接口。
表6.26密钥环插件密钥类型
插件名称 | 允许的密钥类型 | 密钥类型的允许密钥长度 |
---|---|---|
keyring_encrypted_file |
|
没有特别限制 没有特别限制 没有特别限制 |
keyring_file |
|
没有特别限制 没有特别限制 没有特别限制 |
keyring_okv |
AES |
16,24,32 |
keyring_aws |
AES |
16,24,32 |
MySQL服务器支持密钥环服务,该服务使内部服务器组件和插件能够安全地存储敏感信息,以便以后检索。
MySQL服务器还包括用于密钥环密钥管理的SQL接口,实现为一组通用用户定义函数(UDF),用于访问内部密钥环服务提供的功能。
密钥环UDF包含在一个插件库文件中,该文件还包含一个
keyring_udf
必须在UDF调用之前启用
的
插件。
对于要使用的这些UDF,
需要启用
密钥环插件,例如
keyring_file
或
keyring_okv
必须启用。
这里描述的UDF是通用的,旨在与任何密钥环插件一起使用。 给定的密钥环插件可能具有自己的UDF,仅用于该插件; 请参见 第6.4.4.9节“特定于插件的密钥环密钥管理功能” 。
以下部分提供了密钥环UDF的安装说明,并演示了如何使用它们。 有关UDF调用的密钥环服务函数的信息,请参见 第29.3.2节“密钥环服务” 。 有关一般密钥环信息,请参见 第6.4.4节“MySQL密钥环” 。
本节介绍如何安装或卸载密钥环用户定义函数(UDF),这些函数在包含插件的插件库文件中实现
keyring_udf
。
有关安装或卸载插件和UDF的一般信息,请参见
第5.6.1节“安装和卸载插件”
和
第5.7.1节“安装和卸载用户定义的函数”
。
密钥环UDF启用密钥环密钥管理操作,但
keyring_udf
也必须安装插件,因为没有它,UDF将无法正常工作。
尝试在没有
keyring_udf
插件的
情况下使用UDF会
导致错误。
要使服务器可以使用,插件库文件必须位于MySQL插件目录(
plugin_dir
系统变量
指定的目录
)中。
如有必要,通过设置
plugin_dir
服务器启动时
的值来配置插件目录位置
。
插件库文件基本名称是
keyring_udf
。
文件名后缀因平台
.so
而异
(例如,
对于Unix和类Unix系统,
.dll
对于Windows)。
要安装
keyring_udf
插件和UDF,请使用
INSTALL PLUGIN
和
CREATE FUNCTION
语句(
.so
根据需要
调整
平台
的
后缀):
安装PLUGIN keyring_udf SONAME'keyring_udf.so'; CREATE FUNCTION keyring_key_generate RETURNS INTEGER SONAME'keyring_udf.so'; CREATE FUNCTION keyring_key_fetch RETURNS STRING SONAME'keyring_udf.so'; CREATE FUNCTION keyring_key_length_fetch RETURNS INTEGER SONAME'keyring_udf.so'; CREATE FUNCTION keyring_key_type_fetch RETURNS STRING SONAME'keyring_udf.so'; CREATE FUNCTION keyring_key_store RETURNS INTEGER SONAME'keyring_udf.so'; 创建功能keyring_key_remove RETURNS INTEGER SONAME'keyring_udf.so';
如果在主复制服务器上使用插件和UDF,请将它们安装在所有从属服务器上,以避免复制问题。
如上所述安装后,插件和UDF将保持安装状态,直到卸载为止。
要删除它们,请使用
UNINSTALL PLUGIN
和
DROP FUNCTION
语句:
UNINSTALL PLUGIN keyring_udf; DROP FUNCTION keyring_key_generate; DROP FUNCTION keyring_key_fetch; DROP FUNCTION keyring_key_length_fetch; DROP FUNCTION keyring_key_type_fetch; DROP FUNCTION keyring_key_store; DROP FUNCTION keyring_key_remove;
在使用密钥环用户定义函数(UDF)之前,请按照 第6.4.4.8.1节“安装或卸载通用密钥环功能”中 提供的说明进行 安装 。
密钥环UDF受这些约束:
要使用任何密钥环UDF,
keyring_udf
必须启用
该
插件。
否则,会发生错误:
ERROR 1123(HY000):无法初始化函数'keyring_key_generate'; 此功能需要未安装的keyring_udf插件。 请安装
要安装
keyring_udf
插件,请参见
第6.4.4.8.1节“安装或卸载通用密钥环功能”
。
密钥环UDF调用密钥环服务功能(参见
第29.3.2节“密钥环服务”
)。
服务功能反过来使用安装的任何密钥环插件(例如,
keyring_file
或
keyring_okv
)。
因此,要使用任何密钥环UDF,必须启用一些底层密钥环插件。
否则,会发生错误:
ERROR 3188(HY000):函数'keyring_key_generate'失败,因为 底层密钥环服务返回错误。请检查一下 密钥环插件已安装且提供的参数有效 对于你正在使用的密钥环。
要安装密钥环插件,请参见 第6.4.4.1节“密钥环插件安装” 。
要使用任何密钥环UDF,用户必须拥有全局
EXECUTE
特权。
否则,会发生错误:
ERROR 1123(HY000):无法初始化函数'keyring_key_generate'; 用户无权执行此功能。用户需要 有执行
要将全局
EXECUTE
特权
授予
用户,请使用以下语句:
GRANT EXECUTE ON *。* TO user
;
或者,如果您
EXECUTE
仍然
希望
在允许用户访问特定密钥管理操作的同时
避免授予全局
特权,
则可以定义
“
包装器
”
存储的程序(本节稍后将介绍的技术)。
由给定用户存储在密钥环中的密钥可以稍后由同一用户操纵。
也就是说,
CURRENT_USER()
键操作时函数
的值
必须与密钥环中存储密钥时的值相同。
(此约束排除了使用密钥环UDF来操纵实例范围的密钥,例如由
InnoDB
支持表空间加密
而创建的
密钥。)
为了使多个用户能够对同一个键执行操作, 可以定义 “ 包装器 ” 存储的程序(本节稍后描述的技术)。
密钥环UDF支持底层密钥环插件支持的密钥类型和长度,由于UDF接口的限制,密钥不能超过2,048字节(16,384位)的附加约束。 请参见 第6.4.4.7节“支持的密钥环密钥类型” 。
要创建一个新的随机密钥并将其存储在密钥环中,请调用
keyring_key_generate()
,向其传递密钥的ID,密钥类型(加密方法)及其长度(以字节为单位)。
以下调用创建一个名为的2,048位DSA加密密钥
MyKey
:
MySQL的> SELECT keyring_key_generate('MyKey', 'DSA', 256);
+ ------------------------------------------- +
| keyring_key_generate('MyKey','DSA',256)|
+ ------------------------------------------- +
| 1 |
+ ------------------------------------------- +
返回值1表示成功。
如果无法创建密钥,则返回值为,
NULL
并发生错误。
这可能是一个原因是底层密钥环插件不支持密钥类型和密钥长度的指定组合;
请参见
第6.4.4.7节“支持的密钥环密钥类型”
。
为了能够检查返回类型而不管是否发生错误,请使用
并测试变量值:
SELECT ... INTO
@
var_name
MySQL的>SELECT keyring_key_generate('', '', -1) INTO @x;
ERROR 3188(HY000):函数'keyring_key_generate'失败,因为 底层密钥环服务返回错误。请检查一下 密钥环插件已安装且提供的参数有效 对于你正在使用的密钥环。 MySQL的>SELECT @x;
+ ------ + | @x | + ------ + | NULL | + ------ + mysql>SELECT keyring_key_generate('x', 'AES', 16) INTO @x;
mysql>SELECT @x;
+ ------ + | @x | + ------ + | 1 | + ------ +
此技术也适用于其他密钥环UDF,其失败返回值和错误。
传递给的ID
keyring_key_generate()
提供了一种在后续UDF调用中引用键的方法。
例如,使用密钥ID将其类型作为字符串或其长度(以字节为单位)检索为整数:
MySQL的>SELECT keyring_key_type_fetch('MyKey');
+ --------------------------------- + | keyring_key_type_fetch('MyKey')| + --------------------------------- + | DSA | + --------------------------------- + MySQL的>SELECT keyring_key_length_fetch('MyKey');
+ ----------------------------------- + | keyring_key_length_fetch('MyKey')| + ----------------------------------- + | 256 | + ----------------------------------- +
要检索密钥值,请将密钥ID传递给
keyring_key_fetch()
。
以下示例用于
HEX()
显示键值,因为它可能包含不可打印的字符。
该示例还使用了一个简短的密钥,但请注意,较长的密钥可提供更好的安全性:
MySQL的>SELECT keyring_key_generate('MyShortKey', 'DSA', 8);
+ ---------------------------------------------- + | keyring_key_generate('MyShortKey','DSA',8)| + ---------------------------------------------- + | 1 | + ---------------------------------------------- + MySQL的>SELECT HEX(keyring_key_fetch('MyShortKey'));
+ -------------------------------------- + | HEX(keyring_key_fetch('MyShortKey'))| + -------------------------------------- + | 1DB3B0FC3328A24C | + -------------------------------------- +
密钥环UDF将密钥ID,类型和值视为二进制字符串,因此比较区分大小写。
例如,ID
MyKey
和
mykey
引用不同的键。
要删除密钥,请将密钥ID传递给
keyring_key_remove()
:
MySQL的> SELECT keyring_key_remove('MyKey');
+ ----------------------------- +
| keyring_key_remove('MyKey')|
+ ----------------------------- +
| 1 |
+ ----------------------------- +
要混淆和存储您提供的密钥,请将密钥ID,类型和值传递给
keyring_key_store()
:
MySQL的> SELECT keyring_key_store('AES_key', 'AES', 'Secret string');
+ ------------------------------------------------- ----- +
| keyring_key_store('AES_key','AES','秘密字符串')|
+ ------------------------------------------------- ----- +
| 1 |
+ ------------------------------------------------- ----- +
如前所述,用户必须具有
EXECUTE
调用密钥环UDF
的全局
特权,并且最初在密钥环中存储密钥的用户必须是稍后对密钥执行后续操作的同一用户,这取决于
CURRENT_USER()
对每个
密钥环的
有效值。 UDF调用。
要允许对没有全局
EXECUTE
权限或可能不是关键
“
所有者
”的
用户进行关键操作,请
使用以下技术:
定义
“
包装器
”
存储的程序,这些程序封装了所需的键操作,其
DEFINER
值等于密钥所有者。
将
EXECUTE
特定存储程序
的
权限
授予
应该能够调用它们的各个用户。
如果包装程序存储程序实现的操作不包括密钥创建,请使用名为
DEFINER
存储程序定义中
的帐户预先创建任何必需的密钥
。
这种技术使得密钥可以在用户之间共享,并为DBA提供更细粒度的控制,使他们可以使用密钥执行操作,而无需授予全局权限。
以下示例说明如何设置
SharedKey
DBA拥有的
名为共享密钥
,以及
get_shared_key()
提供对当前密钥值的访问权限
的
存储函数。
具有该
EXECUTE
功能特权
的任何用户都可以检索该值,该
特权是在
key_schema
架构中
创建的
。
从MySQL管理帐户(
'root'@'localhost'
在此示例中)中,创建管理模式和存储的函数以访问密钥:
MySQL的>CREATE SCHEMA key_schema;
MySQL的>CREATE DEFINER = 'root'@'localhost'
FUNCTION key_schema.get_shared_key()
RETURNS BLOB READS SQL DATA
RETURN keyring_key_fetch('SharedKey');
从管理帐户中,确保共享密钥存在:
MySQL的> SELECT keyring_key_generate('SharedKey', 'DSA', 8);
+ --------------------------------------------- +
| keyring_key_generate('SharedKey','DSA',8)|
+ --------------------------------------------- +
| 1 |
+ --------------------------------------------- +
从管理帐户中,创建要授予密钥访问权限的普通用户帐户:
MySQL的>CREATE USER 'key_user'@'localhost'
IDENTIFIED BY 'key_user_pwd';
从该
key_user
帐户验证,如果没有适当的
EXECUTE
权限,新帐户将无法访问共享密钥:
MySQL的> SELECT HEX(key_schema.get_shared_key());
ERROR 1370(42000):执行命令被拒绝用户'key_user'@'localhost'
用于例行'key_schema.get_shared_key'
从管理帐户,授
EXECUTE
给
key_user
了存储功能:
MySQL的>GRANT EXECUTE ON FUNCTION key_schema.get_shared_key
TO 'key_user'@'localhost';
在
key_user
帐户中,验证密钥现在是否可访问:
MySQL的> SELECT HEX(key_schema.get_shared_key());
+ ---------------------------------- +
| HEX(key_schema.get_shared_key())|
+ ---------------------------------- +
| 9BAFB9E75CEEB013 |
+ ---------------------------------- +
对于每个通用密钥环用户定义函数(UDF),本节描述其用途,调用顺序和返回值。 有关可以调用这些UDF的条件的信息,请参见 第6.4.4.8.2节“使用通用密钥环函数” 。
给定密钥ID,反混淆并返回密钥值。
参数:
key_id
:一个指定密钥ID的字符串。
返回值:
NULL
如果密钥不存在,则
返回键值作为成功字符串
,或者返回
NULL
失败错误。
keyring_key_fetch()
由于UDF接口的限制,
使用的密钥环值
限制为2,048字节。
可以使用密钥环服务函数存储长度超过该长度的密钥环值(请参见
第29.3.2节“密钥环服务”
),但如果使用
keyring_key_fetch()
,则截断为2,048字节。
例:
MySQL的>SELECT keyring_key_generate('RSA_key', 'RSA', 16);
+ -------------------------------------------- + | keyring_key_generate('RSA_key','RSA',16)| + -------------------------------------------- + | 1 | + -------------------------------------------- + MySQL的>SELECT HEX(keyring_key_fetch('RSA_key'));
+ ----------------------------------- + | HEX(keyring_key_fetch('RSA_key'))| + ----------------------------------- + | 91C2253B696064D3556984B6630F891A | + ----------------------------------- + MySQL的>SELECT keyring_key_type_fetch('RSA_key');
+ ----------------------------------- + | keyring_key_type_fetch('RSA_key')| + ----------------------------------- + | RSA | + ----------------------------------- + MySQL的>SELECT keyring_key_length_fetch('RSA_key');
+ ------------------------------- + | keyring_key_length_fetch('RSA_key')| + ------------------------------- + | 16 | + ------------------------------- +
该示例用于
HEX()
显示键值,因为它可能包含不可打印的字符。
该示例还使用了一个简短的密钥,但请注意,较长的密钥可提供更好的安全性。
keyring_key_generate(
key_id
,
key_type
,
key_length
)
生成具有给定ID,类型和长度的新随机密钥,并将其存储在密钥环中。 类型和长度值必须与底层密钥环插件支持的值一致,并且由于UDF接口的限制,密钥不能超过2,048字节(16,384位)的附加约束。 有关每个插件允许的类型,请参见 第29.3.2节“密钥环服务” 。
参数:
key_id
:一个指定密钥ID的字符串。
key_type
:一个指定键类型的字符串。
key_length
:一个整数,指定密钥长度(以字节为单位)。
最大长度为2,048。
返回值:
成功返回1,或
NULL
失败错误。
例:
MySQL的> SELECT keyring_key_generate('RSA_key', 'RSA', 384);
+ --------------------------------------------- +
| keyring_key_generate('RSA_key','RSA',384)|
+ --------------------------------------------- +
| 1 |
+ --------------------------------------------- +
keyring_key_length_fetch(
key_id
)
给定密钥ID,返回密钥长度。
参数:
key_id
:一个指定密钥ID的字符串。
返回值:
NULL
如果密钥不存在,则
返回以字节为单位的密钥长度,作为成功的整数
,或者
NULL
为失败而返回错误。
例:
请参阅说明
keyring_key_fetch()
。
从密钥环中删除具有给定ID的密钥。
参数:
key_id
:一个指定密钥ID的字符串。
返回值:
成功或
NULL
失败
返回1
。
例:
MySQL的> SELECT keyring_key_remove('AES_key');
+ ------------------------------- +
| keyring_key_remove('AES_key')|
+ ------------------------------- +
| 1 |
+ ------------------------------- +
keyring_key_store(
key_id
,
key_type
,
key
)
在密钥环中对密钥进行模糊处理和存储。
参数:
key_id
:一个指定密钥ID的字符串。
key_type
:一个指定键类型的字符串。
key
:一个指定键值的字符串。
返回值:
成功返回1,或
NULL
失败错误。
例:
MySQL的> SELECT keyring_key_store('new key', 'DSA', 'My key value');
+ ------------------------------------------------- ---- +
| keyring_key_store('新密钥','DSA','我的密钥值')|
+ ------------------------------------------------- ---- +
| 1 |
+ ------------------------------------------------- ---- +
keyring_key_type_fetch(
key_id
)
给定密钥ID,返回密钥类型。
参数:
key_id
:一个指定密钥ID的字符串。
返回值:
NULL
如果密钥不存在,则
返回密钥类型作为成功字符串
,或者返回
NULL
失败错误。
例:
请参阅说明
keyring_key_fetch()
。
对于每个密钥环插件特定的用户定义函数(UDF),本节描述其用途,调用顺序和返回值。 有关通用密钥环UDF的信息,请参见 第6.4.4.8节“通用密钥环密钥管理功能” 。
此UDF与
keyring_aws
插件
相关联
。
它的使用需要
SUPER
特权。
keyring_aws_rotate_cmk()
旋转客户主密钥(CMK)。
轮换仅更改AWS KMS用于后续数据密钥加密操作的密钥。
AWS KMS维护以前的CMK版本,因此使用以前的CMK生成的密钥在轮换后仍可解密。
轮换会更改AWS KMS内使用的CMK值,但不会更改用于引用它的ID,因此无需
keyring_aws_cmk_id
在调用后
更改
系统变量
keyring_aws_rotate_cmk()
。
参数:
没有。
返回值:
成功返回1,或
NULL
失败错误。
此UDF与
keyring_aws
插件
相关联
。
它的使用需要
SUPER
特权。
keyring_aws_rotate_keys()
旋转存储在
系统变量
keyring_aws
命名
的
存储文件
中的密钥
keyring_aws_data_file
。
旋转将存储在文件中的每个密钥发送到AWS KMS,以使用
keyring_aws_cmk_id
系统变量的值作为CMK值
进行重新加密
,并将新的加密密钥存储在文件中。
keyring_aws_rotate_keys()
在这些情况下对密钥重新加密很有用:
旋转CMK后;
也就是说,在调用
keyring_aws_rotate_cmk()
UDF之后
将
keyring_aws_cmk_id
系统变量更改为不同的键值后
参数:
没有。
返回值:
成功返回1,或
NULL
失败错误。
MySQL支持以下与密钥环相关的命令行选项:
--keyring-migration-destination=
plugin
属性 | 值 |
---|---|
命令行格式 | --keyring-migration-destination=plugin_name |
介绍 | 8.0.4 |
类型 | 串 |
用于密钥迁移的目标密钥环插件。
请参见
第6.4.4.6节“在密钥环密钥库之间迁移密钥”
。
选项值的格式和解释与选项中描述的相同
--keyring-migration-source
。
--keyring-migration-source
并且
--keyring-migration-destination
对于所有密钥环迁移操作都是必需的。
源插件和目标插件必须不同,迁移服务器必须支持这两个插件。
--keyring-migration-host=
host_name
属性 | 值 |
---|---|
命令行格式 | --keyring-migration-host=host_name |
介绍 | 8.0.4 |
类型 | 串 |
默认值 | localhost |
正在使用其中一个密钥迁移密钥库的正在运行的服务器的主机位置。
请参见
第6.4.4.6节“在密钥环密钥库之间迁移密钥”
。
迁移总是发生在本地主机上,因此该选项始终指定用于连接到本地服务器,如值
localhost
,
127.0.0.1
,
::1
,或本地主机IP地址或主机名。
--keyring-migration-password[=
password
]
属性 | 值 |
---|---|
命令行格式 | --keyring-migration-password[=password] |
介绍 | 8.0.4 |
类型 | 串 |
用于连接当前正在使用其中一个密钥迁移密钥库的正在运行的服务器的密码。
请参见
第6.4.4.6节“在密钥环密钥库之间迁移密钥”
。
如果省略
password
命令行上选项名称后面
的
值,则服务器会提示输入一个值。
在命令行上指定密码应该被认为是不安全的。 请参见 第6.1.2.1节“密码安全的最终用户指南” 。 您可以使用选项文件以避免在命令行上提供密码。 在这种情况下,该文件应具有限制模式,并且只能用于运行迁移服务器的帐户。
--keyring-migration-port=
port_num
属性 | 值 |
---|---|
命令行格式 | --keyring-migration-port=port_num |
介绍 | 8.0.4 |
类型 | 数字 |
默认值 | 3306 |
对于TCP / IP连接,用于连接当前正在使用其中一个密钥迁移密钥库的正在运行的服务器的端口号。 请参见 第6.4.4.6节“在密钥环密钥库之间迁移密钥” 。
--keyring-migration-socket=
path
属性 | 值 |
---|---|
命令行格式 | --keyring-migration-socket={file_name|pipe_name} |
介绍 | 8.0.4 |
类型 | 串 |
对于Unix套接字文件或Windows命名管道连接,用于连接到当前使用其中一个密钥迁移密钥库的正在运行的服务器的套接字文件或命名管道。 请参见 第6.4.4.6节“在密钥环密钥库之间迁移密钥” 。
--keyring-migration-source=
plugin
属性 | 值 |
---|---|
命令行格式 | --keyring-migration-source=plugin_name |
介绍 | 8.0.4 |
类型 | 串 |
用于密钥迁移的源密钥环插件。 请参见 第6.4.4.6节“在密钥环密钥库之间迁移密钥” 。
--plugin-load
除了只能指定一个插件库之外,
选项值
与之
类似
。
该值以
or表示
。
这
是要加载的插件
的名称,是包含插件代码的库文件的名称。
如果插件库的名称没有任何先前的插件名称,则服务器会加载库中的所有插件。
服务器在
系统变量
指定的目录中查找插件库文件
。
name
=
plugin_library
plugin_library
name
plugin_library
plugin_dir
--keyring-migration-source
并且
--keyring-migration-destination
对于所有密钥环迁移操作都是必需的。
源插件和目标插件必须不同,迁移服务器必须支持这两个插件。
--keyring-migration-user=
user_name
属性 | 值 |
---|---|
命令行格式 | --keyring-migration-user=user_name |
介绍 | 8.0.4 |
类型 | 串 |
用于连接当前正在使用其中一个密钥迁移密钥库的正在运行的服务器的用户名。 请参见 第6.4.4.6节“在密钥环密钥库之间迁移密钥” 。
MySQL Keyring插件支持以下系统变量。 使用它们配置密钥环插件操作。 除非安装了适当的密钥环插件,否则这些变量不可用(请参见 第6.4.4.1节“密钥环插件安装” )。
属性 | 值 |
---|---|
命令行格式 | --keyring-aws-cmk-id=value |
介绍 | 8.0.11 |
系统变量 | keyring_aws_cmk_id |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
从AWS KMS服务器获取并由
keyring_aws
插件
使用的客户主密钥(CMK)ID
。
除非安装了该插件,否则此变量不可用,但如果已安装,则此变量的值是必需的。
属性 | 值 |
---|---|
命令行格式 | --keyring-aws-conf-file=file_name |
介绍 | 8.0.11 |
系统变量 | keyring_aws_conf_file |
范围 | 全球 |
动态 | 没有 |
SET_VAR
提示适用
|
没有 |
类型 | 文件名 |
默认值 | platform specific |
keyring_aws
密钥环插件
的配置文件的位置
。
除非安装了该插件,否则此变量不可用。
在插件启动时,
keyring_aws
从配置文件中读取AWS秘密访问密钥ID和密钥。
要使
keyring_aws
插件成功启动,配置文件必须存在且包含有效的秘密访问密钥信息,如上所述进行初始化
第6.4.4.5节“使用keyring_aws Amazon Web Services密钥环插件”中
。
默认文件名
keyring_aws_conf
位于默认密钥环文件目录中。
此默认目录的位置与
keyring_file_data
系统变量
的位置相同
。
有关详细信息,请参阅该变量的说明,以及在手动创建目录时要考虑的注意事项。
属性 | 值 |
---|---|
命令行格式 | --keyring-aws-data-file |
介绍 | 8.0.11 |
系统变量 | keyring_aws_data_file |
范围 | 全球 |
动态 | 没有 |
SET_VAR
提示适用
|
没有 |
类型 | 文件名 |
默认值 | platform specific |
keyring_aws
密钥环插件
的存储文件的位置
。
除非安装了该插件,否则此变量不可用。
在插件启动时,如果
keyring_aws_data_file
指定
的值
指定了不存在的文件,则
keyring_aws
插件会尝试创建它(如果需要,还会创建其父目录)。
如果文件存在,则将文件中
keyring_aws
包含的任何加密密钥读入其内存缓存中。
keyring_aws
不会将未加密的密钥缓存在内存中。
默认文件名
keyring_aws_data
位于默认密钥环文件目录中。
此默认目录的位置与
keyring_file_data
系统变量
的位置相同
。
有关详细信息,请参阅该变量的说明,以及在手动创建目录时要考虑的注意事项。
属性 | 值 |
---|---|
命令行格式 | --keyring-aws-region=value |
介绍 | 8.0.11 |
系统变量 | keyring_aws_region |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 列举 |
默认值 | us-east-1 |
有效值 |
|
AWS区域。
属性 | 值 |
---|---|
命令行格式 | --keyring-encrypted-file-data=file_name |
介绍 | 8.0.11 |
系统变量 | keyring_encrypted_file_data |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 文件名 |
默认值 | platform specific |
keyring_encrypted_file
插件
用于安全数据存储的数据文件的路径名
。
除非安装了该插件,否则此变量不可用。
文件位置应位于仅供密钥环插件使用的目录中。
例如,不要将文件放在数据目录下。
密钥环操作是事务性的:
keyring_encrypted_file
插件在写入操作期间使用备份文件,以确保在操作失败时它可以回滚到原始文件。
备份文件的名称与
keyring_encrypted_file_data
系统变量
的值相同
,后缀为
.backup
。
不要
keyring_encrypted_file
对多个MySQL实例
使用相同的
数据文件。
每个实例都应该有自己唯一的数据文件。
默认文件名
keyring_encrypted
位于特定于平台的目录中,并且取决于
CMake
选项
的值,
如下表所示。
如果要从源构建,请显式指定文件的默认目录,请使用
CMake
选项。
INSTALL_LAYOUT
INSTALL_MYSQLKEYRINGDIR
INSTALL_LAYOUT
值
|
默认
keyring_encrypted_file_data
值
|
---|---|
DEB
,
RPM
,
SLES
,
SVR4
|
/var/lib/mysql-keyring/keyring_encrypted |
除此以外 | keyring/keyring_encrypted
在
CMAKE_INSTALL_PREFIX
价值
之下
|
在插件启动时,如果
keyring_encrypted_file_data
指定
的值
指定了不存在的文件,则
keyring_encrypted_file
插件会尝试创建它(如果需要,还会创建其父目录)。
如果手动创建目录,它应该具有限制模式,并且只能用于运行MySQL服务器的帐户。
例如,在Unix和类Unix系统上,要使用该
/usr/local/mysql/mysql-keyring
目录,以下命令(执行为
root
)创建目录并设置其模式和所有权:
cd / usr / local / mysql mkdir mysql-keyring chmod 750 mysql-keyring chown mysql mysql-keyring chgrp mysql mysql-keyring
如果
keyring_encrypted_file
插件无法创建或访问其数据文件,它会将错误消息写入错误日志。
如果尝试运行时分配
keyring_encrypted_file_data
导致错误,则变量值保持不变。
一旦
keyring_encrypted_file
插件创建了其数据文件并开始使用它,重要的是不要删除该文件。
丢失文件将导致使用其密钥加密的数据无法访问。
(只要您更改
keyring_encrypted_file_data
要匹配
的值,
就
可以重命名或移动文件
。)
keyring_encrypted_file_password
属性 | 值 |
---|---|
命令行格式 | --keyring-encrypted-file-password=password |
介绍 | 8.0.11 |
系统变量 | keyring_encrypted_file_password |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
keyring_encrypted_file
插件
使用的密码
。
除非安装了该插件,否则此变量不可用。
密码是插件操作必需的;
如果未在服务器启动时指定,则
keyring_encrypted_file
初始化失败。
如果在选项文件中指定了此变量,则该文件应具有限制模式,并且只能由用于运行MySQL服务器的帐户访问。
一旦
keyring_encrypted_file_password
值已定,改变它不转动钥匙圈密码,可以使服务器无法访问。
如果提供的密码不正确,则
keyring_encrypted_file
插件无法从加密的密钥环文件加载密钥。
密码值无法在运行时使用
SHOW VARIABLES
Performance Schena
global_variables
表显示,因为显示值已经过模糊处理。
属性 | 值 |
---|---|
命令行格式 | --keyring-file-data=file_name |
系统变量 | keyring_file_data |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 文件名 |
默认值 | platform specific |
keyring_file
插件
用于安全数据存储的数据文件的路径名
。
除非安装了该插件,否则此变量不可用。
文件位置应位于仅供密钥环插件使用的目录中。
例如,不要将文件放在数据目录下。
密钥环操作是事务性的:
keyring_file
插件在写入操作期间使用备份文件,以确保在操作失败时它可以回滚到原始文件。
备份文件的名称与
keyring_file_data
系统变量
的值相同
,后缀为
.backup
。
不要
keyring_file
对多个MySQL实例
使用相同的
数据文件。
每个实例都应该有自己唯一的数据文件。
默认文件名
keyring
位于特定于平台的目录中,并且取决于
CMake
选项
的值,
如下表所示。
如果要从源构建,请显式指定文件的默认目录,请使用
CMake
选项。
INSTALL_LAYOUT
INSTALL_MYSQLKEYRINGDIR
INSTALL_LAYOUT
值
|
默认
keyring_file_data
值
|
---|---|
DEB
,
RPM
,
SLES
,
SVR4
|
/var/lib/mysql-keyring/keyring |
除此以外 | keyring/keyring
在
CMAKE_INSTALL_PREFIX
价值
之下
|
在插件启动时,如果
keyring_file_data
指定
的值
指定了不存在的文件,则
keyring_file
插件会尝试创建它(如果需要,还会创建其父目录)。
如果手动创建目录,它应该具有限制模式,并且只能用于运行MySQL服务器的帐户。
例如,在Unix和类Unix系统上,要使用该
/usr/local/mysql/mysql-keyring
目录,以下命令(执行为
root
)创建目录并设置其模式和所有权:
cd / usr / local / mysql mkdir mysql-keyring chmod 750 mysql-keyring chown mysql mysql-keyring chgrp mysql mysql-keyring
如果
keyring_file
插件无法创建或访问其数据文件,它会将错误消息写入错误日志。
如果尝试运行时分配
keyring_file_data
导致错误,则变量值保持不变。
一旦
keyring_file
插件创建了其数据文件并开始使用它,重要的是不要删除该文件。
例如,
InnoDB
使用该文件存储用于解密使用
InnoDB
表空间加密的
表中的数据的主密钥
;
请参见
第15.6.3.9节“InnoDB静态数据加密”
。
丢失文件将导致此类表中的数据无法访问。
(只要更改了值,就可以重命名或移动文件
keyring_file_data
匹配。)建议您在创建第一个加密表之后以及主密钥轮换之前和之后立即创建密钥环数据文件的单独备份。
属性 | 值 |
---|---|
命令行格式 | --keyring-okv-conf-dir=dir_name |
介绍 | 8.0.11 |
系统变量 | keyring_okv_conf_dir |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 目录名称 |
默认值 | empty string |
存储
keyring_okv
插件
使用的配置信息的目录的路径名
。
除非安装了该插件,否则此变量不可用。
该位置应该是仅供
keyring_okv
插件
使用的目录
。
例如,不要在数据目录下找到该目录。
默认
keyring_okv_conf_dir
值为空。
要使
keyring_okv
插件能够访问Oracle Key Vault,必须将该值设置为包含Oracle Key Vault配置和SSL材料的目录。
有关设置此目录的说明,请参见
第6.4.4.4节“使用keyring_okv KMIP插件”
。
该目录应具有限制模式,并且只能用于运行MySQL服务器的帐户。
例如,在Unix和类Unix系统上,要使用该
/usr/local/mysql/mysql-keyring-okv
目录,以下命令(执行为
root
)创建目录并设置其模式和所有权:
cd / usr / local / mysql mkdir mysql-keyring-okv chmod 750 mysql-keyring-okv chown mysql mysql-keyring-okv chgrp mysql mysql-keyring-okv
如果
keyring_okv_conf_dir
指定
的值
指定了不存在的目录,或者不包含允许建立与Oracle Key Vault连接的配置信息,
keyring_okv
则会将错误消息写入错误日志。
如果尝试运行时分配
keyring_okv_conf_dir
导致错误,则变量值和密钥环操作保持不变。
属性 | 值 |
---|---|
介绍 | 8.0.4 |
系统变量 | keyring_operations |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 布尔 |
默认值 | ON |
是否启用密钥环操作。
在密钥迁移操作期间使用此变量。
请参见
第6.4.4.6节“在密钥环密钥库之间迁移密钥”
。
修改此变量所需的权限是
ENCRYPTION_KEY_ADMIN
其中之一
SYSTEM_VARIABLES_ADMIN
或
SUPER
。
MySQL Enterprise Audit是商业产品MySQL企业版中的扩展。 要了解有关商业产品的更多信息,请访问 https://www.mysql.com/products/ 。
MySQL企业版包括MySQL Enterprise Audit,使用名为的服务器插件实现
audit_log
。
MySQL Enterprise Audit使用开放的MySQL Audit
API来启用标准的,基于策略的监视,记录和阻止在特定MySQL服务器上执行的连接和查询活动。
MySQL Enterprise
Audit旨在满足Oracle审计规范,为受内部和外部监管准则管理的应用程序提供开箱即用,易于使用的审计和合规性解决方案。
安装后,审计插件使MySQL Server能够生成包含服务器活动审计记录的日志文件。 日志内容包括客户端连接和断开连接的时间,以及它们在连接时执行的操作,例如它们访问的数据库和表。
安装审计插件后(请参见
第6.4.5.2节“安装或卸载MySQL Enterprise Audit”
),它会写入审计日志文件。
默认情况下,该文件
audit.log
在服务器数据目录中
命名
。
要更改文件名,请设置
audit_log_file
在服务器启动时
系统变量。
默认情况下,审核日志文件内容以新式XML格式编写,无需压缩或加密。
要选择文件格式,请
audit_log_format
在服务器启动时
设置
系统变量。
有关文件格式和内容的详细信息,请参见
第6.4.5.4节“审核日志文件格式”
。
有关控制日志记录方式的更多信息,包括审计日志文件命名和格式选择,请参见 第6.4.5.5节“审计日志记录配置” 。 要对审计事件执行过滤,请参见 第6.4.5.6节“审计日志过滤” 。 有关用于配置审核日志插件的参数的说明,请参见 第6.4.5.8.4节“审核日志选项和变量” 。
如果启用了审计日志插件,则为性能架构(请参见 第26章, MySQL性能架构 )会为其提供工具。 要识别相关工具,请使用以下查询:
从performance_schema.setup_instruments中选择名称 名称在哪里'%/ alog /%';
MySQL Enterprise Audit基于审计日志插件和相关组件:
名为的服务器端插件
audit_log
检查可审计事件,并确定是否将它们写入审核日志。
用户定义的函数可以处理控制日志记录行为,加密密码和日志文件读取的过滤定义。
mysql
系统数据库
中的表
提供过滤器和用户帐户数据的持久存储。
系统变量使审计日志配置和状态变量能够提供运行时操作信息。
一个
AUDIT_ADMIN
特权使用户能够管理审计日志。
本节介绍如何安装或卸载MySQL Enterprise Audit,它是使用 第6.4.5.1节“审核日志组件”中 所述的审核日志插件和相关组件实现的 。 有关安装插件的一般信息,请参见 第5.6.1节“安装和卸载插件” 。
按照说明阅读完整部分。 部分程序因环境而异。
如果已安装,
audit_log
即使禁用
,
插件也会涉及一些最小的开销。
为避免此开销,请不要安装MySQL Enterprise Audit,除非您打算使用它。
要使服务器可以使用,插件库文件必须位于MySQL插件目录(
plugin_dir
系统变量
指定的目录
)中。
如有必要,通过设置
plugin_dir
服务器启动时
的值来配置插件目录位置
。
要安装MySQL Enterprise Audit,请查看
share
MySQL安装目录并选择适合您平台的脚本。
可用脚本的不同之处在于用于引用插件库文件的后缀:
audit_log_filter_win_install.sql
:为
.dll
用作文件名后缀的
Windows系统选择此脚本
。
audit_log_filter_linux_install.sql
:为Linux和类似系统选择此脚本,
.so
用作文件名后缀。
运行脚本如下。 此处的示例使用Linux安装脚本。 为您的系统进行适当的替换。
shell>mysql -u root -p < audit_log_filter_linux_install.sql
输入密码:(enter root password here)
一些MySQL版本引入了对MySQL Enterprise Audit表结构的更改。 要确保您的表是从早期版本的MySQL 8.0升级的最新表,请执行MySQL升级过程,确保使用强制更新的选项(请参见 第2.11节“升级MySQL” )。 如果您更喜欢仅为MySQL Enterprise Audit表运行update语句,请参阅以下讨论。
从MySQL 8.0.12开始,对于新的MySQL安装,
MySQL Enterprise Audit使用
的
表中的
列
USER
和
HOST
列
audit_log_user
具有更好地对应
于
系统表中
User
和
Host
列
的定义的定义
mysql.user
。
要升级已安装MySQL Enterprise Audit的安装,建议您更改表定义,如下所示:
ALTER TABLE mysql.audit_log_user DROP FOREIGN KEY audit_log_user_ibfk_1; ALTER TABLE mysql.audit_log_filter CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_ci; ALTER TABLE mysql.audit_log_user CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_ci; ALTER TABLE mysql.audit_log_user MODIFY COLUMN USER VARCHAR(32); ALTER TABLE mysql.audit_log_user 添加外键(FILTERNAME)参考mysql.audit_log_filter(NAME);
要在主/从复制,组复制或InnoDB集群的上下文中使用MySQL Enterprise Audit,必须在主节点或主节点上运行安装脚本之前准备从节点或辅助节点。
这是必要的,因为
INSTALL PLUGIN
脚本中
的
语句不会被复制。
在每个从属节点或辅助节点上,
INSTALL PLUGIN
从安装脚本中
提取
语句并手动执行。
在主节点或主节点上,按前面所述运行安装脚本。
要验证插件安装,请检查
INFORMATION_SCHEMA.PLUGINS
表或使用该
SHOW PLUGINS
语句(请参见
第5.6.2节“获取服务器插件信息”
)。
例如:
MySQL的>SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE 'audit%';
+ ------------- + --------------- + | PLUGIN_NAME | PLUGIN_STATUS | + ------------- + --------------- + | audit_log | ACTIVE | + ------------- + --------------- +
如果插件无法初始化,请检查服务器错误日志以获取诊断消息。
安装MySQL Enterprise Audit后,您可以使用该
--audit-log
选项来控制后续服务器启动
audit_log
插件激活。
例如,要防止在运行时删除插件,请使用以下选项:
的[mysqld] 审计日志= FORCE_PLUS_PERMANENT
如果希望在没有审计插件的情况下阻止服务器运行,请使用
--audit-log
值为
FORCE
或
FORCE_PLUS_PERMANENT
强制服务器启动失败,如果插件未成功初始化。
默认情况下,基于规则的审核日志筛选不会为任何用户记录可审核事件。 这与传统审核日志行为不同,后者记录所有用户的所有可审核事件(请参见 第6.4.5.7节“传统模式审核日志过滤” )。 如果您希望使用基于规则的过滤生成日志行为,请创建一个简单的过滤器以启用日志记录并将其分配给默认帐户:
SELECT audit_log_filter_set_filter('log_all','{“filter”:{“log”:true}}'); SELECT audit_log_filter_set_user('%','log_all');
分配给的过滤器
%
用于来自任何未明确分配过滤器的帐户的连接(最初对所有帐户都是如此)。
如上所述安装后,MySQL Enterprise Audit将一直安装,直到卸载为止。 要删除它,请执行以下语句:
DROP TABLE IF EXISTS mysql.audit_log_user; DROP TABLE IF EXISTS mysql.audit_log_filter; UNINSTALL PLUGIN audit_log; DROP FUNCTION audit_log_filter_set_filter; DROP FUNCTION audit_log_filter_remove_filter; DROP FUNCTION audit_log_filter_set_user; DROP FUNCTION audit_log_filter_remove_user; DROP FUNCTION audit_log_filter_flush; DROP FUNCTION audit_log_encryption_password_get; DROP FUNCTION audit_log_encryption_password_set; DROP FUNCTION audit_log_read; DROP FUNCTION audit_log_read_bookmark;
默认情况下,审计日志插件生成的审计日志文件的内容未加密,可能包含敏感信息,例如SQL语句的文本。
出于安全原因,审计日志文件应写入只能由MySQL服务器访问的目录以及具有查看日志的合法理由的用户。
默认文件名
audit.log
位于数据目录中。
这可以通过
audit_log_file
在服务器启动时
设置
系统变量
来更改
。
由于日志轮换,可能存在其他审核日志文件。
为了提高安全性,请启用审核日志文件加密。 请参阅 审核日志文件加密 。
只要发生可审计事件,MySQL服务器就会调用审计日志插件将审计记录写入其日志文件。
通常,插件启动后编写的第一个审计记录包含服务器描述和启动选项。
后面的元素表示客户端连接和断开连接事件,执行的SQL语句等事件。
仅记录顶级语句,而不记录存储程序(如触发器或存储过程)中的语句。
语句引用的文件内容(
LOAD
DATA
如未记录)。
要选择审核日志插件用于写入其日志文件的日志格式,请
audit_log_format
在服务器启动时
设置
系统变量。
这些格式可用:
新式XML格式(
audit_log_format=NEW
):与旧式XML格式相比,与Oracle Audit Vault具有更好兼容性的XML格式。
MySQL 8.0默认使用新式XML格式。
旧式XML格式(
audit_log_format=OLD
):旧MySQL系列中默认使用的原始审核日志格式。
JSON格式(
audit_log_format=JSON
)
默认情况下,审核日志文件内容以新式XML格式编写,无需压缩或加密。
有关更改日志格式时要考虑的问题的信息,请参阅 审核日志文件格式 。
以下部分描述了可用的审计日志记录格式:
这是一个新格式XML格式的示例日志文件(
audit_log_format=NEW
),为了便于阅读,稍微重新格式化:
<?xml version =“1.0”encoding =“utf-8”?> <AUDIT> <AUDIT_RECORD> <TIMESTAMP> 2017-10-16T14:06:33 UTC </ TIMESTAMP> <RECORD_ID> 1_2017-10-16T14:06:33 </ RECORD_ID> <NAME>审核</ NAME> <SERVER_ID> 1 </ SERVER_ID> <VERSION> 1 </ VERSION> <STARTUP_OPTIONS>的/ usr /本地/ MySQL的/斌/ mysqld的 --socket =的/ usr /本地/ MySQL的/的mysql.sock --port = 3306 </ STARTUP_OPTIONS> <OS_VERSION> i686的Linux的</ OS_VERSION> <MYSQL_VERSION> 21年5月7日日志</ MYSQL_VERSION> </ AUDIT_RECORD> <AUDIT_RECORD> <TIMESTAMP> 2017-10-16T14:09:38 UTC </ TIMESTAMP> <RECORD_ID> 2_2017-10-16T14:06:33 </ RECORD_ID> <名称>连接</ NAME> <CONNECTION_ID> 5 </ CONNECTION_ID> <STATUS> 0 </ STATUS> <STATUS_CODE> 0 </ STATUS_CODE> <USER>根</ USER> <OS_LOGIN /> <HOST>本地主机</ HOST> <IP> 127.0.0.1 </ IP> <COMMAND_CLASS>连接</ COMMAND_CLASS> <CONNECTION_TYPE> SSL / TLS </ CONNECTION_TYPE> <PRIV_USER>根</ PRIV_USER> <PROXY_USER /> <DB>测试</ DB> </ AUDIT_RECORD> ... <AUDIT_RECORD> <TIMESTAMP> 2017-10-16T14:09:38 UTC </ TIMESTAMP> <RECORD_ID> 6_2017-10-16T14:06:33 </ RECORD_ID> <NAME>查询</ NAME> <CONNECTION_ID> 5 </ CONNECTION_ID> <STATUS> 0 </ STATUS> <STATUS_CODE> 0 </ STATUS_CODE> <USER> root [root] @ localhost [127.0.0.1] </ USER> <OS_LOGIN /> <HOST>本地主机</ HOST> <IP> 127.0.0.1 </ IP> <COMMAND_CLASS> drop_table </ COMMAND_CLASS> <SQLTEXT> DROP TABLE IF EXISTS t </ SQLTEXT> </ AUDIT_RECORD> ... <AUDIT_RECORD> <TIMESTAMP> 2017-10-16T14:09:39 UTC </ TIMESTAMP> <RECORD_ID> 8_2017-10-16T14:06:33 </ RECORD_ID> <NAME>退出</ NAME> <CONNECTION_ID> 5 </ CONNECTION_ID> <STATUS> 0 </ STATUS> <STATUS_CODE> 0 </ STATUS_CODE> <USER>根</ USER> <OS_LOGIN /> <HOST>本地主机</ HOST> <IP> 127.0.0.1 </ IP> <COMMAND_CLASS>连接</ COMMAND_CLASS> <CONNECTION_TYPE> SSL / TLS </ CONNECTION_TYPE> </ AUDIT_RECORD> ... <AUDIT_RECORD> <TIMESTAMP> 2017-10-16T14:09:43 UTC </ TIMESTAMP> <RECORD_ID> 11_2017-10-16T14:06:33 </ RECORD_ID> <NAME>退出</ NAME> <CONNECTION_ID> 6 </ CONNECTION_ID> <STATUS> 0 </ STATUS> <STATUS_CODE> 0 </ STATUS_CODE> <USER>根</ USER> <OS_LOGIN /> <HOST>本地主机</ HOST> <IP> 127.0.0.1 </ IP> <COMMAND_CLASS>连接</ COMMAND_CLASS> <CONNECTION_TYPE> SSL / TLS </ CONNECTION_TYPE> </ AUDIT_RECORD> <AUDIT_RECORD> <TIMESTAMP> 2017-10-16T14:09:45 UTC </ TIMESTAMP> <RECORD_ID> 12_2017-10-16T14:06:33 </ RECORD_ID> <NAME> NOAUDIT </ NAME> <SERVER_ID> 1 </ SERVER_ID> </ AUDIT_RECORD> </ AUDIT>
审计日志文件使用UTF-8(每个字符最多4个字节)写为XML。
根元素是
<AUDIT>
。
根元素包含
<AUDIT_RECORD>
元素,每个元素都提供有关审计事件的信息。
当审计日志插件开始编写新的日志文件时,它会写入XML声明并打开
<AUDIT>
根元素标记。
当插件关闭日志文件时,它会写入关闭的
</AUDIT>
根元素标记。
文件打开时,结束标记不存在。
元素中的
<AUDIT_RECORD>
元素具有以下特征:
一些元素出现在每个
<AUDIT_RECORD>
元素中。
其他是可选的,可能会出现,具体取决于审计记录类型。
<AUDIT_RECORD>
不保证
元素内
元素的
顺序
。
元素值不是固定长度。 如稍后给出的元素描述中所示,可以截断长值。
的
<
,
>
,
"
,和
&
字符被编码为
<
,
>
,
"
,和
&
,分别。
NUL字节(U + 00)被编码为
?
字符。
无效为XML字符的字符使用数字字符引用进行编码。 有效的XML字符是:
#x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
以下元素在每个元素中都是必需的
<AUDIT_RECORD>
:
<NAME>
一个字符串,表示生成审计事件的指令类型,例如服务器从客户端收到的命令。
例:
<NAME>查询</ NAME>
一些共同的
<NAME>
价值:
审计启动审计时,可能是服务器启动时间 连接当客户端连接时,也称为登录 查询SQL语句(直接执行) 准备SQL语句的准备; 通常后跟Execute 执行SQL语句的执行; 通常遵循准备 关机服务器关机 退出当客户端断开连接时 NoAudit审计已被关闭
可能的值是
Audit
,
Binlog Dump
,
Change
user
,
Close stmt
,
Connect Out
,
Connect
,
Create DB
,
Daemon
,
Debug
,
Delayed insert
,
Drop
DB
,
Execute
,
Fetch
,
Field List
,
Init DB
,
Kill
,
Long Data
,
NoAudit
,
Ping
,
Prepare
,
Processlist
,
Query
,
Quit
,
Refresh
,
Register Slave
,
Reset
stmt
,
Set option
,
Shutdown
,
Sleep
,
Statistics
,
Table
Dump
,
Time
。
除了
Audit
和之外
NoAudit
,这些值对应
于
头文件中
列出
的
命令值
。
例如,
与
对应于
和
分别。
COM_
xxx
my_command.h
Create DB
Change
user
COM_CREATE_DB
COM_CHANGE_USER
<RECORD_ID>
审计记录的唯一标识符。
该值由格式中的序列号和时间戳组成
。
当审核日志插件打开审核日志文件时,它会将序列号初始化为审核日志文件的大小,然后为记录的每个记录将序列递增1。
时间戳是UTC值,
格式表示审核日志插件打开文件的日期和时间。
SEQ_TIMESTAMP
YYYY-MM-DD
Thh:mm:ss
例:
<RECORD_ID> 12_2017-10-16T14:06:33 </ RECORD_ID>
<TIMESTAMP>
一个字符串,表示
格式
的UTC值,
表示生成审计事件的日期和时间。
例如,与从客户端接收的SQL语句的执行相对应的事件具有
在语句结束之后而不是在语句结束时发生
的
值。
YYYY-MM-DD
Thh:mm:ss
UTC<TIMESTAMP>
例:
<TIMESTAMP> 2017-10-16T14:09:45 UTC </ TIMESTAMP>
以下元素在
<AUDIT_RECORD>
元素中
是可选的
。
其中许多只出现特定的
<NAME>
元素值。
<COMMAND_CLASS>
一个字符串,指示执行的操作类型。
例:
<COMMAND_CLASS> drop_table </ COMMAND_CLASS>
值对应于
命令计数器。
例如,
is
和
for
和
语句分别。
以下语句显示可能的名称:
statement/sql/
xxx
xxx
drop_table
select
DROP
TABLE
SELECT
SELECT REPLACE(EVENT_NAME,'statement / sql /','')AS名称 FROM performance_schema.events_statements_summary_global_by_event_name 在哪里EVENT_NAME LIKE'statement / sql /%' 按名称订购;
<CONNECTION_ID>
表示客户端连接标识符的无符号整数。
这
CONNECTION_ID()
与会话中函数
返回的值相同
。
例:
<CONNECTION_ID> 127 </ CONNECTION_ID>
<CONNECTION_TYPE>
与服务器连接的安全状态。
允许的值是
TCP/IP
(未加密建立TCP / IP连接),
SSL/TLS
(通过加密建立TCP / IP连接),
Socket
(Unix套接字文件连接),
Named Pipe
(Windows命名管道连接)和
Shared
Memory
(Windows共享内存连接)。
例:
<CONNECTION_TYPE> SSL / TLS </ CONNECTION_TYPE>
<DB>
表示默认数据库名称的字符串。
例:
<DB>测试</ DB>
<HOST>
表示客户端主机名的字符串。
例:
<HOST>本地主机</ HOST>
<IP>
表示客户端IP地址的字符串。
例:
<IP> 127.0.0.1 </ IP>
<MYSQL_VERSION>
表示MySQL服务器版本的字符串。
这与
VERSION()
函数或
version
系统变量
的值相同
。
例:
<MYSQL_VERSION> 21年5月7日日志</ MYSQL_VERSION>
<OS_LOGIN>
一个字符串,表示在身份验证过程中使用的外部用户名,由用于验证客户端的插件设置。
使用本机(内置)MySQL身份验证,或者如果插件未设置该值,则此元素为空。
该值与
external_user
系统变量
的值相同
(请参见
第6.2.18节“代理用户”
)。
例:
<OS_LOGIN>杰弗里</ OS_LOGIN>
<OS_VERSION>
一个字符串,表示构建或正在运行服务器的操作系统。
例:
<OS_VERSION> x86_64的Linux的</ OS_VERSION>
<PRIV_USER>
表示服务器对客户端进行身份验证的用户的字符串。
这是服务器用于权限检查的用户名,可能与
<USER>
值
不同
。
例:
<PRIV_USER>杰弗里</ PRIV_USER>
<PROXY_USER>
表示代理用户的字符串(请参见 第6.2.18节“代理用户” )。 如果用户代理无效,则该值为空。
例:
<PROXY_USER>显影剂</ PROXY_USER>
<SERVER_ID>
表示服务器ID的无符号整数。
这与
server_id
系统变量
的值相同
。
例:
<SERVER_ID> 1 </ SERVER_ID>
<SQLTEXT>
表示SQL语句文本的字符串。 该值可以为空。 长值可能会被截断。 与审计日志文件本身一样,字符串使用UTF-8(每个字符最多4个字节)写入,因此该值可能是转换的结果。 例如,原始语句可能已作为SJIS字符串从客户端收到。
例:
<SQLTEXT> DELETE FROM t1 </ SQLTEXT>
<STARTUP_OPTIONS>
一个字符串,表示MySQL服务器启动时在命令行或选项文件中给出的选项。 第一个选项是服务器可执行文件的路径。
例:
<STARTUP_OPTIONS>的/ usr /本地/ MySQL的/斌/ mysqld的 --port = 3306 --log_output = FILE </ STARTUP_OPTIONS>
<STATUS>
表示命令状态的无符号整数:0表示成功,非零表示发生错误。
这与
mysql_errno()
C API函数
的值相同
。
有关
<STATUS_CODE>
它的不同之处,
请参阅说明
<STATUS>
。
审核日志不包含SQLSTATE值或错误消息。 要查看错误代码,SQLSTATE值和消息之间的关联,请参见 第B.3.1节“服务器错误消息参考” 。
不记录警告。
例:
<STATUS> 1051 </ STATUS>
<STATUS_CODE>
表示命令状态的无符号整数:0表示成功,1表示发生错误。
该
STATUS_CODE
值与值不同
STATUS
:
STATUS_CODE
成功为0,错误为1,与Audit Vault的EZ_collector使用者兼容。
STATUS
是
mysql_errno()
C API函数
的值
。
成功时为0,错误为非零,因此错误不一定为1。
例:
<STATUS_CODE> 0 </ STATUS_CODE>
<USER>
表示客户端发送的用户名的字符串。
这可能与
<PRIV_USER>
价值
不同
。
例:
<USER> root [root] @ localhost [127.0.0.1] </ USER>
<VERSION>
无符号整数,表示审计日志文件格式的版本。
例:
<VERSION> 1 </ VERSION>
以下是旧式XML格式(
audit_log_format=OLD
)
的示例日志文件,
为了便于阅读,略微重新格式化:
<?xml version =“1.0”encoding =“utf-8”?> <AUDIT> <AUDIT_RECORD TIMESTAMP =“2017-10-16T14:25:00 UTC” RECORD_ID = “1_2017-10-16T14:25:00” NAME = “审计” SERVER_ID = “1” VERSION = “1” STARTUP_OPTIONS = “ - 端口= 3306” OS_VERSION = “i686的Linux的” MYSQL_VERSION = “21年5月7日日志”/> <AUDIT_RECORD TIMESTAMP =“2017-10-16T14:25:24 UTC” RECORD_ID = “2_2017-10-16T14:25:00” NAME = “连接” CONNECTION_ID = “4” STATUS = “0” STATUS_CODE = “0” USER = “根” OS_LOGIN = “” HOST = “本地主机” IP = “127.0.0.1” COMMAND_CLASS = “连接” CONNECTION_TYPE = “SSL / TLS” PRIV_USER = “根” PROXY_USER = “” DB = “测试”/> ... <AUDIT_RECORD TIMESTAMP =“2017-10-16T14:25:24 UTC” RECORD_ID = “6_2017-10-16T14:25:00” NAME = “查询” CONNECTION_ID = “4” STATUS = “0” STATUS_CODE = “0” USER =“root [root] @ localhost [127.0.0.1]” OS_LOGIN = “” HOST = “本地主机” IP = “127.0.0.1” COMMAND_CLASS = “drop_table” SQLTEXT =“DROP TABLE IF EXISTS t”/> ... <AUDIT_RECORD TIMESTAMP =“2017-10-16T14:25:24 UTC” RECORD_ID = “8_2017-10-16T14:25:00” NAME = “退出” CONNECTION_ID = “4” STATUS = “0” STATUS_CODE = “0” USER = “根” OS_LOGIN = “” HOST = “本地主机” IP = “127.0.0.1” COMMAND_CLASS = “连接” CONNECTION_TYPE = “SSL / TLS”/> <AUDIT_RECORD TIMESTAMP =“2017-10-16T14:25:32 UTC” RECORD_ID = “12_2017-10-16T14:25:00” NAME = “NOAUDIT” SERVER_ID = “1”/> </ AUDIT>
审计日志文件使用UTF-8(每个字符最多4个字节)写为XML。
根元素是
<AUDIT>
。
根元素包含
<AUDIT_RECORD>
元素,每个元素都提供有关审计事件的信息。
当审计日志插件开始编写新的日志文件时,它会写入XML声明并打开
<AUDIT>
根元素标记。
当插件关闭日志文件时,它会写入关闭的
</AUDIT>
根元素标记。
文件打开时,结束标记不存在。
<AUDIT_RECORD>
元素的
属性
具有以下特征:
某些属性出现在每个
<AUDIT_RECORD>
元素中。
其他是可选的,可能会出现,具体取决于审计记录类型。
<AUDIT_RECORD>
不保证元素
内的属性顺序
。
属性值不是固定长度。 如稍后给出的属性描述中所示,可以截断长值。
的
<
,
>
,
"
,和
&
字符被编码为
<
,
>
,
"
,和
&
,分别。
NUL字节(U + 00)被编码为
?
字符。
无效为XML字符的字符使用数字字符引用进行编码。 有效的XML字符是:
#x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
以下属性在每个
<AUDIT_RECORD>
元素中
都是必需的
:
NAME
一个字符串,表示生成审计事件的指令类型,例如服务器从客户端收到的命令。
例:
NAME="Query"
一些共同的
NAME
价值:
审计启动审计时,可能是服务器启动时间 连接当客户端连接时,也称为登录 查询SQL语句(直接执行) 准备SQL语句的准备; 通常后跟Execute 执行SQL语句的执行; 通常遵循准备 关机服务器关机 退出当客户端断开连接时 NoAudit审计已被关闭
可能的值是
Audit
,
Binlog Dump
,
Change
user
,
Close stmt
,
Connect Out
,
Connect
,
Create DB
,
Daemon
,
Debug
,
Delayed insert
,
Drop
DB
,
Execute
,
Fetch
,
Field List
,
Init DB
,
Kill
,
Long Data
,
NoAudit
,
Ping
,
Prepare
,
Processlist
,
Query
,
Quit
,
Refresh
,
Register Slave
,
Reset
stmt
,
Set option
,
Shutdown
,
Sleep
,
Statistics
,
Table
Dump
,
Time
。
除了
"Audit"
和之外
"NoAudit"
,这些值对应
于
头文件中
列出
的
命令值
。
例如,
与
对应于
和
分别。
COM_
xxx
my_command.h
"Create DB"
"Change user"
COM_CREATE_DB
COM_CHANGE_USER
RECORD_ID
审计记录的唯一标识符。
该值由格式中的序列号和时间戳组成
。
当审核日志插件打开审核日志文件时,它会将序列号初始化为审核日志文件的大小,然后为记录的每个记录将序列递增1。
时间戳是UTC值,
格式表示审核日志插件打开文件的日期和时间。
SEQ_TIMESTAMP
YYYY-MM-DD
Thh:mm:ss
例:
RECORD_ID="12_2017-10-16T14:25:00"
TIMESTAMP
一个字符串,表示
格式
的UTC值,
表示生成审计事件的日期和时间。
例如,与从客户端接收的SQL语句的执行相对应的事件具有
在语句结束之后而不是在语句结束时发生
的
值。
YYYY-MM-DD
Thh:mm:ss
UTCTIMESTAMP
例:
TIMESTAMP="2017-10-16T14:25:32
UTC"
以下属性在
<AUDIT_RECORD>
元素中
是可选的
。
其中许多只出现在具有特定
NAME
属性
值的元素中
。
COMMAND_CLASS
一个字符串,指示执行的操作类型。
例:
COMMAND_CLASS="drop_table"
值对应于
命令计数器。
例如,
is
和
for
和
语句分别。
以下语句显示可能的名称:
statement/sql/
xxx
xxx
drop_table
select
DROP
TABLE
SELECT
SELECT REPLACE(EVENT_NAME,'statement / sql /','')AS名称 FROM performance_schema.events_statements_summary_global_by_event_name 在哪里EVENT_NAME LIKE'statement / sql /%' 按名称订购;
CONNECTION_ID
表示客户端连接标识符的无符号整数。
这
CONNECTION_ID()
与会话中函数
返回的值相同
。
例:
CONNECTION_ID="127"
CONNECTION_TYPE
与服务器连接的安全状态。
允许的值是
TCP/IP
(未加密建立TCP / IP连接),
SSL/TLS
(通过加密建立TCP / IP连接),
Socket
(Unix套接字文件连接),
Named Pipe
(Windows命名管道连接)和
Shared
Memory
(Windows共享内存连接)。
例:
CONNECTION_TYPE="SSL/TLS"
DB
表示默认数据库名称的字符串。
例:
DB="test"
HOST
表示客户端主机名的字符串。
例:
HOST="localhost"
IP
表示客户端IP地址的字符串。
例:
IP="127.0.0.1"
MYSQL_VERSION
表示MySQL服务器版本的字符串。
这与
VERSION()
函数或
version
系统变量
的值相同
。
例:
MYSQL_VERSION="5.7.21-log"
OS_LOGIN
一个字符串,表示在身份验证过程中使用的外部用户名,由用于验证客户端的插件设置。
使用本机(内置)MySQL身份验证,或者如果插件未设置该值,则此属性为空。
该值与
external_user
系统变量
的值相同
(请参见
第6.2.18节“代理用户”
)。
例:
OS_LOGIN="jeffrey"
OS_VERSION
一个字符串,表示构建或正在运行服务器的操作系统。
例:
OS_VERSION="x86_64-Linux"
PRIV_USER
表示服务器对客户端进行身份验证的用户的字符串。
这是服务器用于权限检查的用户名,它可能与
USER
值
不同
。
例:
PRIV_USER="jeffrey"
PROXY_USER
表示代理用户的字符串(请参见 第6.2.18节“代理用户” )。 如果用户代理无效,则该值为空。
例:
PROXY_USER="developer"
SERVER_ID
表示服务器ID的无符号整数。
这与
server_id
系统变量
的值相同
。
例:
SERVER_ID="1"
SQLTEXT
表示SQL语句文本的字符串。 该值可以为空。 长值可能会被截断。 与审计日志文件本身一样,字符串使用UTF-8(每个字符最多4个字节)写入,因此该值可能是转换的结果。 例如,原始语句可能已作为SJIS字符串从客户端收到。
例:
SQLTEXT="DELETE FROM t1"
STARTUP_OPTIONS
一个字符串,表示MySQL服务器启动时在命令行或选项文件中给出的选项。
例:
STARTUP_OPTIONS="--port=3306
--log_output=FILE"
STATUS
表示命令状态的无符号整数:0表示成功,非零表示发生错误。
这与
mysql_errno()
C API函数
的值相同
。
有关
STATUS_CODE
它的不同之处,
请参阅说明
STATUS
。
审核日志不包含SQLSTATE值或错误消息。 要查看错误代码,SQLSTATE值和消息之间的关联,请参见 第B.3.1节“服务器错误消息参考” 。
不记录警告。
例:
STATUS="1051"
STATUS_CODE
表示命令状态的无符号整数:0表示成功,1表示发生错误。
该
STATUS_CODE
值与值不同
STATUS
:
STATUS_CODE
成功为0,错误为1,与Audit Vault的EZ_collector使用者兼容。
STATUS
是
mysql_errno()
C API函数
的值
。
成功时为0,错误为非零,因此错误不一定为1。
例:
STATUS_CODE="0"
USER
表示客户端发送的用户名的字符串。
这可能与
PRIV_USER
价值
不同
。
VERSION
无符号整数,表示审计日志文件格式的版本。
例:
VERSION="1"
对于JSON格式的审计日志记录(
audit_log_format=JSON
),日志文件内容形成一个
JSON
数组,每个数组元素将一个审计事件表示
JSON
为键值对
的
哈希。
完整事件记录的示例将在本节后面部分显示。
以下是部分事件的摘录:
[ { “timestamp”:“2018-01-15 13:50:01”, “id”:0, “阶级”:“审计”, “事件”:“启动”, ... }, { “timestamp”:“2018-01-15 15:02:32”, “id”:0, “阶级”:“连接”, “事件”:“连接”, ... }, ... { “timestamp”:“2018-01-15 17:37:26”, “id”:0, “class”:“table_access”, “事件”:“插入”, ... } ... ]
审计日志文件使用UTF-8编写(每个字符最多4个字节)。
当审核日志插件开始编写新的日志文件时,它会写入打开的
[
数组标记。
当插件关闭日志文件时,它会写入结束
]
数组标记。
文件打开时,关闭标记不存在。
审计记录中的项目具有以下特征:
每个审核记录中都会显示一些项目。 其他是可选的,可能会出现,具体取决于审计记录类型。
审计记录中的项目顺序无法保证。
项目值不是固定长度。 如稍后给出的项目描述中所示,可以截断长值。
的
"
和
\
字符被编码为
\"
与
\\
分别。
以下示例显示了不同事件类型的JSON对象格式(由
class
和
event
项
表示
),为了便于阅读,略微重新格式化:
审核启动事件:
{“timestamp”:“2018-01-15 14:21:56”, “id”:0, “阶级”:“审计”, “事件”:“启动”, “connection_id”:0, “startup_data”:{“server_id”:1, “os_version”:“i686-Linux”, “mysql_version”:“5.7.21-log”, “args”:[“/ usr / local / mysql / bin / mysqld”, “--loose审计日志格式= JSON”, “--log误差= LOG.ERR”, “--pid文件= mysqld.pid”, “--port = 3306”]}}
当审计日志插件开始作为服务器启动的结果(而不是在运行时被启用),
connection_id
被设置为0,并且
account
与
login
不存在。
审核关闭事件:
{“timestamp”:“2018-01-15 14:28:20”, “id”:3, “阶级”:“审计”, “事件”:“关机”, “connection_id”:0, “shutdown_data”:{“server_id”:1}}
当审计日志插件被卸载为服务器关闭的结果(而不是在运行时被禁用),
connection_id
被设置为0,并且
account
与
login
不存在。
连接或更改用户事件:
{“timestamp”:“2018-01-15 14:23:18”, “id”:1, “阶级”:“连接”, “事件”:“连接”, “connection_id”:5, “account”:{“user”:“root”,“host”:“localhost”}, “login”:{“user”:“root”,“os”:“”,“ip”:“:: 1”,“proxy”:“”}, “connection_data”:{“connection_type”:“ssl”, “状态”:0, “db”:“test”}}
断开事件:
{“timestamp”:“2018-01-15 14:24:45”, “id”:3, “阶级”:“连接”, “事件”:“断开”, “connection_id”:5, “account”:{“user”:“root”,“host”:“localhost”}, “login”:{“user”:“root”,“os”:“”,“ip”:“:: 1”,“proxy”:“”}, “connection_data”:{“connection_type”:“ssl”}}
查询事件:
{“timestamp”:“2018-01-15 14:23:35”, “id”:2, “阶级”:“一般”, “事件”:“状态”, “connection_id”:5, “account”:{“user”:“root”,“host”:“localhost”}, “login”:{“user”:“root”,“os”:“”,“ip”:“:: 1”,“proxy”:“”}, “general_data”:{“command”:“查询”, “sql_command”:“show_variables”, “查询”:“显示变量”, “状态”:0}}
表访问事件(读取,删除,插入,更新):
{“timestamp”:“2018-01-15 14:23:41”, “id”:0, “class”:“table_access”, “事件”:“插入”, “connection_id”:5, “account”:{“user”:“root”,“host”:“localhost”}, “login”:{“user”:“root”,“os”:“”,“ip”:“127.0.0.1”,“proxy”:“”}, “table_access_data”:{“db”:“test”, “table”:“t1”, “query”:“INSERT INTO t1(i)VALUES(1),(2),(3)”, “sql_command”:“insert”}}
以下列表中的项目显示在JSON格式审核记录的顶级:每个项目值都是标量或
JSON
散列。
对于具有哈希值的项目,描述仅列出该哈希中的项目名称。
有关二级哈希项的更完整描述,请参阅本节后面的内容。
account
与事件关联的MySQL帐户。
的值是包含这些项目相当于值的散列
CURRENT_USER()
的段内的功能:
user
,
host
。
例:
“account”:{“user”:“root”,“host”:“localhost”}
class
表示事件类的字符串。
该类与
event
指定事件子类
的
项
一起定义事件的类型
。
例:
“阶级”:“连接”
下表显示了允许的组合
class
和
event
值。
表6.27审计日志类和事件组合
类价值 | 允许的事件值 |
---|---|
audit |
startup
,
shutdown
|
connection |
connect
,
change_user
,
disconnect
|
general |
status |
table_access_data |
read
,
delete
,
insert
,
update
|
connection_data
有关客户端连接的信息。
的值是包含这些项目的哈希:
connection_type
,
status
,
db
。
此项仅适用于
class
值为的
审计记录
connection
。
例:
“connection_data”:{“connection_type”:“ssl”, “状态”:0, “db”:“test”}
connection_id
表示客户端连接标识符的无符号整数。
这
CONNECTION_ID()
与会话中函数
返回的值相同
。
例:
“connection_id”:5
event
表示事件类的子类的字符串。
子类与
class
指定事件类
的
项
一起定义
事件的类型。
有关更多信息,请参阅
class
项目说明。
例:
“事件”:“连接”
general_data
有关已执行语句或命令的信息。
的值是包含这些项目的哈希:
command
,
sql_command
,
query
,
status
。
此项仅适用于
class
值为的
审计记录
general
。
例:
“general_data”:{“command”:“查询”, “sql_command”:“show_variables”, “查询”:“显示变量”, “状态”:0}
id
表示事件ID的无符号整数。
例:
“id”:2
对于具有相同
timestamp
值的
审计记录
,它们的
id
值区分它们并形成序列。
在审计日志中,
timestamp
/
id
对是唯一的。
这些对是用于标识日志中的事件位置的书签。
login
指示客户端如何连接到服务器的信息。
的值是包含这些项目的哈希:
user
,
os
,
ip
,
proxy
。
例:
“login”:{“user”:“root”,“os”:“”,“ip”:“:: 1”,“proxy”:“”}
shutdown_data
有关审计日志插件终止的信息。
该值是包含这些项的哈希值:
server_id
此项仅适用于具有
class
和
event
值
audit
和的
审计记录
shutdown
。
例:
“shutdown_data”:{“server_id”:1}
startup_data
有关审计日志插件初始化的信息。
的值是包含这些项目的哈希:
server_id
,
os_version
,
mysql_version
,
args
。
此项仅适用于具有
class
和
event
值
audit
和的
审计记录
startup
。
例:
“startup_data”:{“server_id”:1, “os_version”:“i686-Linux”, “mysql_version”:“5.7.21-log”, “args”:[“/ usr / local / mysql / bin / mysqld”, “--loose审计日志格式= JSON”, “--log误差= LOG.ERR”, “--pid文件= mysqld.pid”, “--port = 3306”]}
table_access_data
有关访问表的信息。
该值是包含这些项目的哈希:
db
,
table
,
query
,
sql_command
,此产品仅适用于一个审计记录发生
class
的价值
table_access
。
例:
“table_access_data”:{“db”:“test”, “table”:“t1”, “query”:“INSERT INTO t1(i)VALUES(1),(2),(3)”, “sql_command”:“insert”}
timestamp
一个字符串,表示
YYYY-MM-DD hh:mm:ss
格式
的UTC值,
表示生成审计事件的日期和时间。
例如,与从客户端接收的SQL语句的执行相对应的事件具有
timestamp
在语句结束之后而不是在语句结束时发生
的
值。
例:
“timestamp”:“2018-01-15 13:50:01”
对于具有相同
timestamp
值的
审计记录
,它们的
id
值区分它们并形成序列。
在审计日志中,
timestamp
/
id
对是唯一的。
这些对是用于标识日志中的事件位置的书签。
这些项目显示在与JSON格式审核记录的顶级项目关联的哈希值中:
args
启动MySQL服务器时在命令行或选项文件中给出的一组选项。 第一个选项是服务器可执行文件的路径。
例:
“args”:[“/ usr / local / mysql / bin / mysqld”, “--loose审计日志格式= JSON”, “--log误差= LOG.ERR”, “--pid文件= mysqld.pid”, “--port = 3306”]
command
一个字符串,表示生成审计事件的指令类型,例如服务器从客户端收到的命令。
例:
“命令”:“查询”
connection_type
与服务器连接的安全状态。
允许的值是
tcp/ip
(未加密建立TCP / IP连接),
ssl
(通过加密建立TCP / IP连接),
socket
(Unix套接字文件连接),
named_pipe
(Windows命名管道连接)和
shared_memory
(Windows共享内存连接)。
例:
“connection_type”:“tcp / tcp”
db
表示数据库名称的字符串。
对于
connection_data
,它是默认数据库。
因为
table_access_data
,它是表数据库。
例:
“db”:“测试”
host
表示客户端主机名的字符串。
例:
“host”:“localhost”
ip
表示客户端IP地址的字符串。
例:
“ip”:“:: 1”
mysql_version
表示MySQL服务器版本的字符串。
这与
VERSION()
函数或
version
系统变量
的值相同
。
例:
“mysql_version”:“5.7.21-log”
os
一个字符串,表示在身份验证过程中使用的外部用户名,由用于验证客户端的插件设置。
使用本机(内置)MySQL身份验证,或者如果插件未设置该值,则此属性为空。
该值与
external_user
系统变量
的值相同
。
请参见
第6.2.18节“代理用户”
。
例:
“os”:“jeffrey”
os_version
一个字符串,表示构建或正在运行服务器的操作系统。
例:
“os_version”:“i686-Linux”
proxy
表示代理用户的字符串(请参见 第6.2.18节“代理用户” )。 如果用户代理无效,则该值为空。
例:
“代理”:“开发者”
query
表示SQL语句文本的字符串。 该值可以为空。 长值可能会被截断。 与审计日志文件本身一样,字符串使用UTF-8(每个字符最多4个字节)写入,因此该值可能是转换的结果。 例如,原始语句可能已作为SJIS字符串从客户端收到。
例:
“query”:“DELETE FROM t1”
server_id
表示服务器ID的无符号整数。
这与
server_id
系统变量
的值相同
。
例:
“server_id”:1
sql_command
一个表示SQL语句类型的字符串。
例:
“sql_command”:“插入”
值对应于
命令计数器。
例如,
is
和
for
和
语句分别。
以下语句显示可能的名称:
statement/sql/
xxx
xxx
drop_table
select
DROP
TABLE
SELECT
SELECT REPLACE(EVENT_NAME,'statement / sql /','')AS名称 FROM performance_schema.events_statements_summary_global_by_event_name 在哪里EVENT_NAME LIKE'statement / sql /%' 按名称订购;
status
表示命令状态的无符号整数:0表示成功,非零表示发生错误。
这与
mysql_errno()
C API函数
的值相同
。
审核日志不包含SQLSTATE值或错误消息。 要查看错误代码,SQLSTATE值和消息之间的关联,请参见 第B.3.1节“服务器错误消息参考” 。
不记录警告。
例:
“身份”:1051
table
表示表名的字符串。
例:
“表”:“t1”
user
表示用户名的字符串。
含义因
user
发生
的项目而异
:
在
account
items中,
user
是一个字符串,表示服务器对客户端进行身份验证的用户。
这是服务器用于权限检查的用户名。
在
login
items中,
user
是一个表示客户端发送的用户名的字符串。
例:
“用户”:“root”
本节介绍如何配置审核日志记录特征,例如审核日志插件写入事件的文件,写入事件的格式以及是否启用日志文件压缩和加密。
有关影响审计日志记录的用户定义函数和系统变量的其他信息,请参见 第6.4.5.8.2节“审计日志函数” 和 第6.4.5.8.4节“审计日志选项和变量” 。
审计日志插件还可以根据事件内容或事件发起的帐户控制将审计事件写入审计日志文件。 请参见 第6.4.5.6节“审核日志过滤” 。
要配置审核日志文件名,请
audit_log_file
在服务器启动时
设置
系统变量。
默认情况下,该名称
audit.log
位于服务器数据目录中。
出于安全原因,请将审核日志文件写入仅可供MySQL服务器访问的目录以及具有查看日志的合法理由的用户。
该插件将该
audit_log_file
值
解释
为由基本名称和可选后缀组成。
如果启用了压缩或加密,则有效文件名(实际用于创建日志文件的名称)与配置的文件名不同,因为它具有其他后缀:
如果启用了压缩,则插件会添加后缀
.gz
。
如果启用了加密,则插件会添加后缀
.enc
。
有效的审核日志文件名是为配置的文件名添加适用的压缩和加密后缀而生成的名称。
例如,如果配置的
audit_log_file
值为
audit.log
,则有效文件名是下表中显示的值之一。
启用功能 | 有效的文件名 |
---|---|
没有压缩或加密 | audit.log |
压缩 | audit.log.gz |
加密 | audit.log.enc |
压缩,加密 | audit.log.gz.enc |
审计日志插件根据有效的审计日志文件名在初始化和终止期间执行某些操作:
在初始化期间,插件会检查具有审核日志文件名的文件是否已存在,如果是,则重命名。 (在这种情况下,插件假定先前的服务器调用在审计日志插件运行时意外退出。)然后插件将写入新的空审计日志文件。
在终止期间,插件会重命名审核日志文件。
根据自动日志文件轮换的通常规则进行文件重命名(无论是在插件初始化期间还是终止期间); 请参阅 自动审核日志文件轮换 。
要配置审核日志文件格式,请
audit_log_format
在服务器启动时
设置
系统变量。
默认情况下,格式为
NEW
(新式XML格式)。
有关每种格式的详细信息,请参见
第6.4.5.4节“审核日志文件格式”
。
如果更改
audit_log_format
,建议您也进行更改
audit_log_file
。
否则,将有两组具有相同基本名称但格式不同的日志文件。
可以为任何日志记录格式启用审核日志文件压缩。
要配置审核日志文件压缩,请
audit_log_compression
在服务器启动时
设置
系统变量。
允许的值是
NONE
(无压缩;默认值)和
GZIP
(GNU Zip压缩)。
如果同时启用了压缩和加密,则会在加密之前进行压缩。 要手动恢复原始文件,请先解密,然后解压缩。 请参阅 审核日志文件手动解压缩和解密 。
可以为任何日志记录格式启用审核日志文件加密。 加密基于用户定义的密码(审计日志插件生成的初始密码除外)。 要使用此功能,必须启用MySQL密钥环,因为审计日志记录将其用于密码存储。 可以使用任何密钥环插件; 有关说明,请参见 第6.4.4节“MySQL密钥环” 。
要配置审核日志文件加密,请
audit_log_encryption
在服务器启动时
设置
系统变量。
允许的值是
NONE
(无加密;默认值)和
AES
(AES-256-CBC密码加密)。
要设置或获取加密密码,请使用以下用户定义的函数(UDF):
要设置当前加密密码,请调用
audit_log_encryption_password_set()
。
此功能将新密码存储在密钥环中。
如果启用了加密,它还会执行重命名当前日志文件的日志文件循环操作,并开始使用密码加密的新日志文件。
根据自动日志文件轮换的通常规则进行文件重命名;
请参阅
自动审核日志文件轮换
。
以前编写的审核日志文件不会使用新密码重新加密。 如果需要手动解密这些文件,请保留以前密码的记录。
要获取当前加密密码,请调用
audit_log_encryption_password_get()
,从密钥环中检索密码。
有关审核日志加密功能的其他信息,请参见 第6.4.5.8.2节“审核日志功能” 。
审计日志插件初始化时,如果发现启用了日志文件加密,则会检查密钥环是否包含审计日志加密密码。
如果没有,插件会自动生成随机初始加密密码并将其存储在密钥环中。
要发现此密码,请调用
audit_log_encryption_password_get()
。
如果同时启用了压缩和加密,则会在加密之前进行压缩。 要手动恢复原始文件,请先解密,然后解压缩。 请参阅 审核日志文件手动解压缩和解密 。
可以使用标准工具对审核日志文件进行解压缩和解密。 这应仅针对已关闭(已存档)且不再使用的日志文件执行,而不应针对审计日志插件当前正在编写的日志文件执行此操作。 您可以识别归档日志文件,因为它们已由审核日志插件重命名,以在基本名称后面的文件名中包含时间戳。
对于此讨论,假设
audit_log_file
设置为
audit.log
。
在这种情况下,归档的审核日志文件具有下表中显示的名称之一。
启用功能 | 存档文件名 |
---|---|
没有压缩或加密 | audit. |
压缩 | audit. |
加密 | audit. |
压缩,加密 | audit. |
要手动解压缩压缩日志文件,请使用 gunzip , gzip -d 或等效命令。 例如:
gunzip -c审计。timestamp
.log.gz>审计。timestamp
.LOG
要手动解密加密的日志文件,请使用 openssl 命令。 例如:
openssl enc -d -aes-256-cbc -pass pass:password
-pass -md sha256 - 审计。timestamp
.log.enc - 审计。timestamp
.LOG
如果为审核日志记录启用了压缩和加密,则会在加密之前进行压缩。
在这种情况下,文件名具有
.gz
.enc
添加
和
后缀,对应于这些操作发生的顺序。
要手动恢复原始文件,请反向执行操作。
也就是说,首先解密文件,然后解压缩它:
openssl enc -d -aes-256-cbc -pass pass:password
-pass -md sha256 - 审计。timestamp
.log.gz.enc - 审计。timestamp
.log.gz gunzip -c审计。timestamp
.log.gz>审计。timestamp
.LOG
审计日志文件可能会变得非常大并占用大量磁盘空间。
为了管理其日志文件使用的空间,审计日志插件可以手动或自动提供日志文件轮换。
旋转功能使用
audit_log_flush
和
audit_log_rotate_on_size
系统变量:
默认情况下,
audit_log_rotate_on_size=0
除非手动执行,否则不会发生日志轮换。
在这种情况下,用于
audit_log_flush
在手动重命名后关闭并重新打开当前日志文件。
如果
audit_log_rotate_on_size
大于0,则在写入当前日志文件导致其大小超过此值时会发生自动旋转。
审核日志插件关闭文件,重命名文件并打开新的日志文件。
启用自动旋转后,
audit_log_flush
无效。
在后面描述的几个其他条件下也会发生自动旋转。
重命名的日志文件不会自动删除。 例如,对于基于大小的日志文件轮换,重命名的日志文件不会在名称序列的末尾旋转。 相反,它们具有独特的名称并无限期地积累。 为避免过多使用空间,请定期删除旧文件,必要时先备份它们。
以下讨论更详细地描述了日志文件轮换方法。
如果
audit_log_rotate_on_size=0
(默认值),除非手动执行,否则不会发生日志轮换。
在这种情况下,当
audit_log_flush
值从禁用更改为启用
时,审核日志插件将关闭并重新打开日志文件
。
日志文件重命名必须在服务器外部完成。
假设日志文件名
audit.log
,并要保持三个最近的日志文件,通过名称循环
audit.log.1
通过
audit.log.3
。
在Unix上,手动执行旋转,如下所示:
从命令行重命名当前日志文件:
mv audit.log.2 audit.log.3 mv audit.log.1 audit.log.2 mv audit.log audit.log.1
此策略将覆盖当前
audit.log.3
内容,对已归档日志文件的数量及其使用的空间进行限制。
此时,插件仍在写入已重命名为的当前日志文件
audit.log.1
。
连接到服务器并刷新日志文件,以便插件关闭它并重新打开一个新
audit.log
文件:
SET GLOBAL audit_log_flush = ON;
audit_log_flush
特别之处在于它的值仍然存在,
OFF
因此您无需在再次启用它以执行另一次刷新之前显式禁用它。
对于JSON格式的日志记录,手动重命名审核日志文件使它们对日志读取功能不可用,因为审核日志插件不再能够确定它们是日志文件序列的一部分(请参阅
审核日志文件读取
)。
考虑设置
audit_log_rotate_on_size
大于0以使用基于大小的旋转。
如果
audit_log_rotate_on_size
大于0,则设置
audit_log_flush
无效。
相反,只要对当前日志文件的写入导致其大小超过该
audit_log_rotate_on_size
值,审计日志插件就会关闭该文件,重命名该文件并打开新的日志文件。
在这些条件下也会发生自动旋转:
在插件初始化期间,如果已存在具有审核日志文件名的文件(请参阅 审核日志文件名 )。
在插件终止期间。
audit_log_encryption_password_set()
调用
该
函数时设置加密密码。
该插件通过在其基本名称之后插入时间戳来重命名原始文件。
例如,如果文件名是
audit.log
,则插件将其重命名为诸如的值
audit.20180115T140633.log
。
时间戳是
格式
的UTC值
。
时间戳表示XML日志记录的轮换时间,以及写入JSON日志记录文件的最后一个事件的时间戳。
YYYYMMDD
Thhmmss
审计日志插件可以使用几种策略中的任何一种进行日志写入。 无论策略如何,日志记录都是在尽力而为的基础上进行的,并不能保证一致性。
要指定写策略,请
audit_log_strategy
在服务器启动时
设置
系统变量。
默认情况下,策略值是
ASYNCHRONOUS
,并且插件异步记录到缓冲区,等待缓冲区已满。
可以告诉插件不要等待(
PERFORMANCE
)或同步记录,使用文件系统缓存(
SEMISYNCHRONOUS
)或
sync()
在每次写入请求后
强制输出
调用(
SYNCHRONOUS
)
。
对于异步写策略,
audit_log_buffer_size
系统变量是以字节为单位的缓冲区大小。
在服务器启动时设置此变量以更改缓冲区大小。
该插件使用单个缓冲区,它在初始化时分配,并在终止时删除。
插件不为非同步写策略分配此缓冲区。
异步日志记录策略具有以下特征:
对服务器性能和可伸缩性的影响最小。
阻止在尽可能短的时间内生成审计事件的线程; 也就是说,分配缓冲区的时间加上将事件复制到缓冲区的时间。
输出进入缓冲区。 一个单独的线程处理从缓冲区到日志文件的写入。
使用异步日志记录时,如果在写入文件期间出现问题或者插件没有干净地关闭(例如,在服务器主机意外退出的情况下),则日志文件的完整性可能会受到影响。
要降低此风险,请设置
audit_log_strategy
为使用同步日志记录。
PERFORMANCE
策略的
一个缺点
是它在缓冲区已满时丢弃事件。
对于负载很重的服务器,审计日志可能缺少事件。
审计日志插件支持书签和读取JSON格式的审计日志文件。 (这些功能不适用于以其他日志格式编写的文件。)
当审计日志插件初始化并配置为JSON日志记录时,它使用包含审计日志文件的目录(根据
audit_log_file
值
确定
)作为搜索可读审计日志文件的位置。
为此,它使用值
audit_log_file
来确定文件基本名称和后缀值,然后查找名称与以下模式匹配的
[...]
文件
,其中
表示可选的文件名部分:
basename
[timestamp
]。suffix
[。广州] [ENC]
该插件打开每个匹配的文件,检查它是否真的包含JSON审计记录,并使用每个文件的第一个记录中的时间戳对它们进行排序,以构建一个日志文件列表,这些日志文件可以与日志读取功能一起使用。
该插件不能包含在手动重命名的序列文件中,并且与前面的模式不匹配,或者使用密钥环中不再可用的密码加密。
要从审核日志中读取事件,请使用以下用户定义的函数(UDF):
audit_log_read_bookmark()
返回
JSON
表示最近编写的审核日志事件的书签
的
字符串。
此书签适合传递以
audit_log_read()
指示该功能从何处开始阅读。
书签示例:
{“timestamp”:“2018-01-15 21:03:44”,“id”:0}
audit_log_read()
从审计日志中读取事件并返回
JSON
包含审计事件数组的字符串。
audit_log_read()
使用当前书签调用
示例
:
MySQL的> SELECT audit_log_read(audit_log_read_bookmark());
+ ------------------------------------------------- ---------------------- +
| audit_log_read(audit_log_read_bookmark())|
+ ------------------------------------------------- ---------------------- +
| [{“timestamp”:“2018-01-15 22:41:24”,“id”:0,“class”:“connection”,... |
+ ------------------------------------------------- ---------------------- +
audit_log_read()
返回值
中的每个事件
都是一个
JSON
哈希值,但最后一个数组元素可能是一个
值,表示没有后续事件可供读取。
例如:
JSON
null
[ {“timestamp”:“2018-01-15 22:08:08”,“id”:10, “阶级”:“一般”,“事件”:“状态”, ... }, { “timestamp”:“2018-01-15 22:08:08”,“id”:11, “class”:“connection”,“event”:“disconnect”, ... }, { “timestamp”:“2018-01-15 13:39:33”,“id”:0, “class”:“连接”,“事件”:“连接”, ... }, { “timestamp”:“2018-01-15 13:39:33”,“id”:1, “阶级”:“一般”,“事件”:“状态”, ... }, { “timestamp”:“2018-01-15 13:39:33”,“id”:2, “class”:“connection”,“event”:“disconnect”, ... }, 空值 ]
使用
audit_log_read()
这样:
对于
audit_log_read()
在会话中
的第一次调用
,传递指示从哪里开始阅读的书签。
如果返回的数组的最终值不是
值,则在刚读取的数据之后会有更多事件,并且
可以在没有或带有书签参数的情况下调用。
如果没有参数,则继续阅读下一个未读事件。
使用书签参数,从书签继续读取。
JSON
null
audit_log_read()
如果返回的数组的最终值是一个
值,则不再有剩余的事件需要读取,下一次调用
必须包含书签参数。
JSON
null
audit_log_read()
书签是
JSON
指示读取位置和
数量的
散列。
以下项目在书签值中很重要(其他项目将被忽略):
timestamp
,
id
:要读取的第一个事件的审核日志中的位置。
必须存在两个项目才能完全指定位置。
max_array_length
:从日志中读取的最大事件数。
如果省略,则默认为读取日志结尾或读取缓冲区已满,以先到者为准。
从任一日志读取函数返回的结果是二进制字符串。
要将字符串与需要非二进制字符串的函数(例如操作
JSON
值
的函数
)一起使用,请将其转换为
utf8mb4
。
假设书签具有此值:
MySQL的> SELECT @mark := audit_log_read_bookmark() AS mark;
+ ------------------------------------------------- +
| 标记|
+ ------------------------------------------------- +
| {“timestamp”:“2018-01-15 16:10:28”,“id”:2} |
+ ------------------------------------------------- +
audit_log_read()
使用该书签
调用
可以返回多个事件。
要设置读取事件数量的限制
audit_log_read()
,将书签转换为
utf8mb4
,然后添加
max_array_length
值为1
的
项目。例如,使用前面的书签,转换并修改如下:
mysql>SET @mark = CONVERT(@mark USING utf8mb4);
mysql>SET @mark := JSON_SET(@mark, '$.max_array_length', 1);
mysql>SELECT @mark;
+ ------------------------------------------------- --------------------- + | @mark | + ------------------------------------------------- --------------------- + | {“id”:2,“timestamp”:“2018-01-15 16:10:28”,“max_array_length”:1} | + ------------------------------------------------- --------------------- +
修改后的书签在传递给
audit_log_read()
时会产生单个审核记录的结果。
要设置
audit_log_read()
读取
的字节数限制
,请设置
audit_log_read_buffer_size
系统变量。
从MySQL 8.0.12开始,此变量的默认值为32KB,可以在运行时设置。
每个客户端应该
audit_log_read_buffer_size
为其使用适当地
设置其会话值
audit_log_read()
。
在MySQL 8.0.12之前,
audit_log_read_buffer_size
默认值为1MB,影响所有客户端,并且只能在服务器启动时更改。
每次调用都
audit_log_read()
返回适合缓冲区大小的可用项目,跳过不符合缓冲区大小的项目。
鉴于此行为,在评估应用程序的适当缓冲区大小时请考虑以下因素:
在
audit_log_read()
每个呼叫的呼叫
次数
和返回的项目
之间存在权衡
。
使用较小的缓冲区大小,调用返回的项目较少,因此需要更多的调用。
缓冲区大小越大,调用返回的项越多,因此需要的调用次数越少。
使用较小的缓冲区大小(例如默认大小为32KB),项目超出缓冲区大小的可能性更大,并且
audit_log_read()
会跳过它们。
跳过的项目会生成警告。
有关审计日志读取功能的其他信息,请参见 第6.4.5.8.2节“审计日志功能” 。
本节介绍如果安装了审核日志插件以及随附的审核表和UDF,审核日志筛选的工作原理。 如果安装了插件但没有附带的审计表和UDF,则插件以传统过滤模式运行,如 第6.4.5.7节“传统模式审计日志过滤”中所述 。 传统模式是MySQL 5.7.13之前的过滤行为; 也就是说,在引入基于规则的过滤之前。
审计日志插件可以通过过滤来控制审计事件的日志记录:
可以使用以下特征过滤审核事件:
用户帐号
审核事件类
审计事件子类
事件字段的值,例如指示操作状态或执行的SQL语句的事件字段
审核筛选基于规则:
过滤器定义创建一组审核规则。 可以将定义配置为基于刚刚描述的特征包括或排除用于记录的事件。
除了用于事件记录的现有功能之外,过滤规则还具有阻止(中止)合格事件执行的能力。
可以定义多个过滤器,并且可以将任何给定过滤器分配给任意数量的用户帐户。
可以定义默认过滤器以用于未明确指定过滤器的任何用户帐户。
可以使用基于用户定义函数(UDF)的SQL接口定义,显示和修改审计过滤器。
审计筛选器定义存储在
mysql
系统数据库
的表中
。
在给定会话中,只读
audit_log_filter_id
系统变量的值指示是否已将过滤器分配给会话。
默认情况下,基于规则的审核日志筛选不会为任何用户记录可审核事件。 要记录所有用户的所有可审计事件,请使用以下语句,这些语句创建一个简单的过滤器以启用日志记录并将其分配给默认帐户:
SELECT audit_log_filter_set_filter('log_all','{“filter”:{“log”:true}}'); SELECT audit_log_filter_set_user('%','log_all');
分配给的过滤器
%
用于来自任何未明确分配过滤器的帐户的连接(最初对所有帐户都是如此)。
以下列表简要总结了为审计过滤控制实现SQL接口的UDF:
audit_log_filter_set_user()
:开始过滤用户帐户
audit_log_filter_remove_user()
:停止过滤用户帐户
audit_log_filter_flush()
:刷新过滤表的手动更改以影响正在进行的过滤
有关过滤功能的用法示例和完整详细信息,请参见 第6.4.5.6.1节“使用审计日志过滤功能” 和 第6.4.5.8.2节“审计日志功能” 。
审核日志过滤功能受以下限制:
要使用任何过滤功能,
audit_log
必须启用插件或发生错误。
此外,审计表必须存在或发生错误。
要安装
audit_log
插件及其随附的UDF和表,请参见
第6.4.5.2节“安装或卸载MySQL Enterprise Audit”
。
要使用任何过滤功能,用户必须拥有该
SUPER
权限或发生错误。
要将
SUPER
权限
授予
用户帐户,请使用以下语句:
授予超级*。* TO user
;
或者,如果您
SUPER
仍然
希望
在允许用户访问特定过滤功能的同时
避免授予
权限,
则可以定义
“
包装器
”
存储的程序。
在
第6.4.4.8.2节“使用通用密钥环函数”
中,密钥环UDF的上下文中描述了这种技术
;
它可以适用于过滤UDF。
该
audit_log
如果已安装,但附带的审计表和功能都没有建立在传统模式下运行的插件。
插件在服务器启动时将这些消息写入错误日志:
[警告]插件audit_log报告:'无法打开审核日志过滤器表。' [警告]插件audit_log报告:'审核日志插件支持过滤, 还没有安装。审核日志插件将在旧版中运行 模式,将在下一个版本中禁用。
在传统模式下,只能根据事件帐户或状态进行过滤。 有关详细信息,请参见 第6.4.5.7节“传统模式审核日志过滤” 。
在使用审计日志用户定义函数(UDF)之前,请按照
第6.4.5.2节“安装或卸载MySQL Enterprise Audit”中
提供的说明进行
安装
。
SUPER
使用任何这些功能都需要
该
权限。
审计日志过滤功能通过提供用于创建,修改和删除过滤器定义以及为用户帐户分配过滤器的界面来启用过滤控制。
过滤器定义是
JSON
值。
有关
JSON
在MySQL中
使用
数据的
信息
,请参见
第11.6节“JSON数据类型”
。
本节显示了一些简单的过滤器定义。
有关过滤器定义的更多信息,请参见
第6.4.5.6.2节“编写审核日志过滤器定义”
。
当连接到达时,审核日志插件通过在当前筛选器分配中搜索用户帐户名来确定要用于新会话的筛选器:
如果为用户分配了筛选器,则审核日志将使用该筛选器。
否则,如果不存在特定于用户的筛选器分配,但是为默认帐户(
%
)
分配了筛选器
,则审核日志将使用默认筛选器。
否则,审核日志不会从会话中选择任何审核事件进行处理。
如果在会话期间发生更改用户操作(请参见 第28.7.7.3节“mysql_change_user()” ),则会针对新用户使用相同的规则更新会话的筛选器分配。
默认情况下,没有帐户分配过滤器,因此任何帐户都不会处理可审核事件。
假设您希望默认情况下仅记录与连接相关的活动(例如,查看connect,change-user和disconnect事件,而不是用户在连接时执行的SQL语句)。
要实现此目的,请定义一个过滤器(此处显示为名称
log_conn_events
),
该过滤器
仅允许记录
connection
类中
的事件
,并将该过滤器分配给默认帐户,由
%
帐户名称
表示
:
SET @f ='{“filter”:{“class”:{“name”:“connection”}}}'; SELECT audit_log_filter_set_filter('log_conn_events',@ f); SELECT audit_log_filter_set_user('%','log_conn_events');
现在,审核日志使用此默认帐户筛选器来处理来自任何未明确定义筛选器的帐户的连接。
要明确地将过滤器分配给特定用户帐户,请定义过滤器,然后将其分配给相关帐户:
SELECT audit_log_filter_set_filter('log_all','{“filter”:{“log”:true}}'); SELECT audit_log_filter_set_user('user1 @ localhost','log_all'); SELECT audit_log_filter_set_user('user2 @ localhost','log_all');
现在为
user1@localhost
和
启用了完整日志记录
user2@localhost
。
使用默认帐户过滤器继续过滤来自其他帐户的连接。
要取消关联用户帐户与当前过滤器的关联,请取消分配过滤器或指定其他过滤器:
要从用户帐户取消分配过滤器:
SELECT audit_log_filter_remove_user('user1 @ localhost');
过滤帐户的当前会话不受影响。 如果存在,则使用默认帐户过滤器过滤来自帐户的后续连接,否则不会记录。
要为用户帐户分配不同的过滤器:
SELECT audit_log_filter_set_filter('log_nothing','{“filter”:{“log”:false}}'); SELECT audit_log_filter_set_user('user1 @ localhost','log_nothing');
过滤帐户的当前会话不受影响。
使用新过滤器过滤来自帐户的后续连接。
对于此处显示的过滤器,这意味着不会记录新连接
user1@localhost
。
对于审核日志筛选,用户名和主机名比较区分大小写。 这与特权检查的比较不同,对于这些比较,主机名比较不区分大小写。
要删除过滤器,请执行以下操作:
SELECT audit_log_filter_remove_filter('log_nothing');
删除过滤器也会从已分配过滤器的任何用户取消分配,包括这些用户的所有当前会话。
刚刚描述的过滤UDF立即影响审计过滤,并更新
mysql
存储过滤器和用户帐户
的
系统数据库中
的审计日志表
(请参见
第6.4.5.8.1节“审计日志表”
)。
也可以直接使用语句,如修改审计日志表
INSERT
,
UPDATE
和
DELETE
,但这样的变化不影响立即过滤。
要刷新更改并使其可操作,请致电
audit_log_filter_flush()
:
SELECT audit_log_filter_flush();
audit_log_filter_flush()
只有在直接修改审计表后才能使用,强制重新加载所有过滤器。
否则,应避免使用此功能。
它实际上是,卸载的简化版本并重新加载
audit_log
与插件
UNINSTALL PLUGIN
加
INSTALL PLUGIN
。
audit_log_filter_flush()
影响所有当前会话并将它们与之前的过滤器分离。
除非断开连接并重新连接或执行更改用户操作,否则不再记录当前会话。
要确定是否已将过滤器分配给当前会话,请检查只读
audit_log_filter_id
系统变量
的会话值
。
如果值为0,则不分配过滤器。
非零值表示已分配过滤器的内部维护ID:
MySQL的> SELECT @@audit_log_filter_id;
+ ----------------------- +
| @@ audit_log_filter_id |
+ ----------------------- +
| 2 |
+ ----------------------- +
过滤器定义是
JSON
值。
有关
JSON
在MySQL中
使用
数据的
信息
,请参见
第11.6节“JSON数据类型”
。
过滤器定义具有此形式,其中
actions
指示过滤如何发生:
{“过滤器”:actions
}
以下讨论描述了过滤器定义中允许的构造。
要显式启用或禁用所有事件的日志记录,请使用
log
过滤器中
的
元素:
{ “过滤器”:{“log”:true} }
该
log
值可以是
true
或
false
。
上述过滤器可以记录所有事件。 它相当于:
{ “过滤器”:{} }
登录行为取决于
log
价值,以及是否
class
或
event
指定项目:
使用
log
指定时,将使用其给定值。
如果没有
log
指定,则记录是否指定
true
no
class
或
event
item,
false
否则(在这种情况下,
class
或者
event
可以包括它们自己的
log
项目)。
要记录特定类的事件,请使用
class
过滤器中
的
元素,其
name
字段表示要记录的类的名称:
{ “过滤器”:{ “class”:{“name”:“connection”} } }
该
name
值可以是
connection
,
general
或分别
table_access
用于记录连接,常规或表访问事件。
前面的过滤器可以记录
connection
类中
的事件
。
它相当于以下过滤器,其中
log
明确的项目:
{ “过滤器”:{ “log”:false, “class”:{“log”:true, “名称”:“连接”} } }
要启用多个类的日志记录,请将
class
值
定义
为
JSON
命名类
的
数组元素:
{ “过滤器”:{ “班级”:[ {“name”:“connection”}, {“name”:“general”}, {“name”:“table_access”} ] } }
当给定项的多个实例出现在过滤器定义中的同一级别时,可以将项值组合到数组值中该项的单个实例中。 前面的定义可以这样写:
{ “过滤器”:{ “班级”:[ {“name”:[“connection”,“general”,“table_access”]} ] } }
要选择特定事件子类,请使用
event
包含
name
命名子类
的
项的
项。
项目选择的事件的默认操作
event
是记录它们。
例如,此筛选器启用对命名事件子类的日志记录:
{ “过滤器”:{ “班级”:[ { “名称”:“连接”, “事件”:[ {“name”:“connect”}, {“name”:“disconnect”} ] }, {“name”:“general”}, { “name”:“table_access”, “事件”:[ {“name”:“insert”}, {“name”:“删除”}, {“name”:“update”} ] } ] } }
该项
event
还可以包含显式
log
项,以指示是否记录限定事件。
此项
event
选择多个事件并明确指示它们的日志记录行为:
“事件”:[ {“name”:“read”,“log”:false}, {“name”:“insert”,“log”:true}, {“name”:“delete”,“log”:true}, {“name”:“update”,“log”:true} ]
该
event
项目还可以指示是否阻止符合条件的事件(如果它包含
abort
项目)。
有关详细信息,请参阅
阻止特定事件的执行
。
表6.28“事件类和子类组合” 描述了每个事件类的允许子类值。
表6.28事件类和子类组合
活动类 | 事件子类 | 描述 |
---|---|---|
connection |
connect |
连接启动(成功或不成功) |
connection |
change_user |
用户在会话期间使用不同的用户/密码重新验证 |
connection |
disconnect |
连接终止 |
general |
status |
一般操作信息 |
message |
internal |
内部生成的消息 |
message |
user |
消息生成
audit_api_message_emit_udf()
|
table_access |
read |
表读语句,例如
SELECT
或
INSERT
INTO ... SELECT
|
table_access |
delete |
表删除语句,例如
DELETE
或
TRUNCATE TABLE
|
table_access |
insert |
表插入语句,例如
INSERT
或
REPLACE
|
table_access |
update |
表更新语句,例如
UPDATE
|
表6.29“每个事件类和子类组合的日志和中止特征” 描述了每个事件子类是否可以记录或中止。
表6.29每个事件类和子类组合的日志和中止特征
活动类 | 事件子类 | 可以记录 | 可以中止 |
---|---|---|---|
connection |
connect |
是 | 没有 |
connection |
change_user |
是 | 没有 |
connection |
disconnect |
是 | 没有 |
general |
status |
是 | 没有 |
message |
internal |
是 | 是 |
message |
user |
是 | 是 |
table_access |
read |
是 | 是 |
table_access |
delete |
是 | 是 |
table_access |
insert |
是 | 是 |
table_access |
update |
是 | 是 |
过滤器可以以包含或独占模式定义:
包含模式仅记录明确指定的项目。
独占模式记录除明确指定的项目之外
要执行包含日志记录,请全局禁用日志记录并启用特定类的日志记录
这种过滤日志
connect
和
disconnect
事件中的
connection
类,并且在事件
general
类:
{ “过滤器”:{ “log”:false, “班级”:[ { “名称”:“连接”, “事件”:[ {“name”:“connect”,“log”:true}, {“name”:“disconnect”,“log”:true} ] }, {“name”:“general”,“log”:true} ] } }
要执行独占日志记录,请全局启用日志记录并禁用特定类的日志记录
此过滤器记录除
general
类中
事件之外的所有内容
:
{ “过滤器”:{ “log”:是的, “类”: {“name”:“general”,“log”:false} } }
该过滤器记录
change_user
的事件
connection
类,
message
事件和
table_access
事件:
{ “过滤器”:{ “log”:是的, “班级”:[ { “名称”:“连接”, “事件”:[ {“name”:“connect”,“log”:false}, {“name”:“disconnect”,“log”:false} ] }, {“name”:“general”,“log”:false} ] } }
要根据特定事件字段值启用日志记录,请在
field
项目中
指定一个
项目,该
log
项目指示字段名称及其预期值:
{ “过滤器”:{ “class”:{ “名字”:“一般”, “event”:{ “名称”:“状态”, “log”:{ “field”:{“name”:“general_command.str”,“value”:“查询”} } } } } }
每个事件都包含特定于事件类的字段,可以从过滤器中访问这些字段以执行自定义过滤。
连接事件指示在会话期间何时发生与连接相关的活动,例如用户连接到服务器或从服务器断开连接。 表6.30,“连接事件字段” 表示 连接事件 的允许字段。
表6.30连接事件字段
字段名称 | 字段类型 | 描述 |
---|---|---|
status |
整数 |
活动状态: 0:好的 否则:失败 |
connection_id |
无符号整数 | 连接ID |
user.str |
串 | 验证期间指定的用户名 |
user.length |
无符号整数 | 用户名长度 |
priv_user.str |
串 | 经过身份验证的用户名(帐户用户名) |
priv_user.length |
无符号整数 | 经过身份验证的用户名长度 |
external_user.str |
串 | 外部用户名(由第三方认证插件提供) |
external_user.length |
无符号整数 | 外部用户名长度 |
proxy_user.str |
串 | 代理用户名 |
proxy_user.length |
无符号整数 | 代理用户名长度 |
host.str |
串 | 已连接的用户主机 |
host.length |
无符号整数 | 连接的用户主机长度 |
ip.str |
串 | 连接的用户IP地址 |
ip.length |
无符号整数 | 连接的用户IP地址长度 |
database.str |
串 | 连接时指定的数据库名称 |
database.length |
无符号整数 | 数据库名称长度 |
connection_type |
整数 |
连接类型:
或
或
或
或
或
或
|
的
值是符号伪常量可以给出的,而不是字面数值。
它们必须作为字符串引用并且区分大小写。
"::
xxx
"
一般事件表示操作的状态代码及其详细信息。 表6.31,“常规事件字段” 表示一般事件的允许字段。
表6.31常规事件字段
字段名称 | 字段类型 | 描述 |
---|---|---|
general_error_code |
整数 |
活动状态: 0:好的 否则:失败 |
general_thread_id |
无符号整数 | 连接/线程ID |
general_user.str |
串 | 验证期间指定的用户名 |
general_user.length |
无符号整数 | 用户名长度 |
general_command.str |
串 | 命令名称 |
general_command.length |
无符号整数 | 命令名称长度 |
general_query.str |
串 | SQL语句文本 |
general_query.length |
无符号整数 | SQL语句文本长度 |
general_host.str |
串 | 主机名 |
general_host.length |
无符号整数 | 主机名长度 |
general_sql_command.str |
串 | SQL命令类型名称 |
general_sql_command.length |
无符号整数 | SQL命令类型名称长度 |
general_external_user.str |
串 | 外部用户名(由第三方认证插件提供) |
general_external_user.length |
无符号整数 | 外部用户名长度 |
general_ip.str |
串 | 连接的用户IP地址 |
general_ip.length |
无符号整数 | 连接用户IP地址长度 |
general_command.str
表示命令名:
Query
,
Execute
,
Quit
,或
Change user
。
与一般的事件
general_command.str
字段设置为
Query
或
Execute
包含
general_sql_command.str
设置为指定SQL命令的类型的值:
alter_db
,
alter_db_upgrade
,
admin_commands
,等等。
这些值可以看作此语句显示的性能模式工具的最后组件:
MySQL的>SELECT NAME FROM performance_schema.setup_instruments
WHERE NAME LIKE 'statement/sql/%' ORDER BY NAME;
+ --------------------------------------- + | NAME | + --------------------------------------- + | statement / sql / alter_db | | statement / sql / alter_db_upgrade | | statement / sql / alter_event | | statement / sql / alter_function | | statement / sql / alter_instance | | statement / sql / alter_procedure | | statement / sql / alter_server | ...
表访问事件提供有关特定表访问的信息。 表6.32“表访问事件字段” 表示 表访问事件 的允许字段。
表6.32表访问事件字段
字段名称 | 字段类型 | 描述 |
---|---|---|
connection_id |
无符号整数 | 事件连接ID |
sql_command_id |
整数 | SQL命令ID |
query.str |
串 | SQL语句文本 |
query.length |
无符号整数 | SQL语句文本长度 |
table_database.str |
串 | 与事件关联的数据库名称 |
table_database.length |
无符号整数 | 数据库名称长度 |
table_name.str |
串 | 与事件关联的表名称 |
table_name.length |
无符号整数 | 表名长度 |
以下列表显示哪些语句产生哪些表访问事件:
read
事件:
SELECT
INSERT ... SELECT
(对于
SELECT
子句中
引用的表
)
REPLACE ... SELECT
(对于
SELECT
子句中
引用的表
)
UPDATE ... WHERE
(对于
WHERE
子句中
引用的表
)
HANDLER ... READ
delete
事件:
DELETE
TRUNCATE TABLE
insert
事件:
INSERT
INSERT ... SELECT
(对于
INSERT
子句
中引用的表
)
REPLACE
REPLACE ... SELECT
(对于
REPLACE
条款
中引用的表)
LOAD DATA
LOAD XML
update
事件:
UPDATE
UPDATE ... WHERE
(对于
UPDATE
子句中
引用的表
)
event
项目可以包括
abort
指示是否阻止合格事件执行的项目。
例如,
abort
启用阻止特定SQL语句执行的规则。
该
abort
项目必须出现在
event
项目中。
例如:
“event”:{ “名称”:qualifying event subclass names
“中止”:condition
}
对于
name
项目
选择的事件子类
,
abort
操作为true或false,具体取决于
condition
评估。
如果条件的计算结果为true,则会阻止该事件。
否则,事件继续执行。
所述
condition
规范可以是一样简单
true
或
false
,或者它可以是更复杂的,使得评价取决于事件特性。
该过滤块
INSERT
,
UPDATE
和
DELETE
语句:
{ “过滤器”:{ “class”:{ “name”:“table_access”, “event”:{ “name”:[“insert”,“update”,“delete”], “abort”:是的 } } } }
这个更复杂的过滤器会阻止相同的语句,但仅限于特定的表(
finances.bank_account
):
{ “过滤器”:{ “class”:{ “name”:“table_access”, “event”:{ “name”:[“insert”,“update”,“delete”], “abort”:{ “和”:[ {“field”:{“name”:“table_database.str”,“value”:“finances”}}, {“field”:{“name”:“table_name.str”,“value”:“bank_account”}} ] } } } } }
过滤器匹配和阻止的语句会向客户端返回错误:
错误1045(28000):语句被审核日志过滤器中止
并非所有事件都可以被阻止(请参阅 表6.29“每个事件类和子类组合的日志和中止特征” )。 对于不能执行的事件,审计日志会将警告写入错误日志而不是阻止它。
对于尝试定义
abort
项目出现在
event
项目
之外
的过滤器的尝试,
会发生错误。
逻辑运算符(
and
,
or
,
not
)可被用
log
物品。
这允许构建更高级的过滤配置:
{ “过滤器”:{ “class”:{ “名字”:“一般”, “event”:{ “名称”:“状态”, “log”:{ “要么”: [ { “和”:[ {“field”:{“name”:“general_command.str”,“value”:“查询”}}, {“field”:{“name”:“general_command.length”,“value”:5}} ] }, { “和”:[ {“field”:{“name”:“general_command.str”,“value”:“执行”}}, {“field”:{“name”:“general_command.length”,“value”:7}} ] } ] } } } } }
要在
log
条件中
引用预定义变量
,请使用
variable
项目,该项目测试与给定值的相等性:
{ “过滤器”:{ “class”:{ “名字”:“一般”, “event”:{ “名称”:“状态”, “log”:{ “变量”:{ “name”:“audit_log_connection_policy_value”,“value”:“:: none” } } } } } }
每个预定义变量对应于系统变量。
通过编写测试预定义变量的过滤器,您可以通过设置相应的系统变量来修改过滤器操作,而无需重新定义过滤器。
例如,通过编写测试
audit_log_connection_policy_value
预定义变量
值的过滤器,
可以通过更改
audit_log_connection_policy
系统变量
的值来修改过滤器操作
。
该
系统变量用于遗留模式审计日志(见
第6.4.5.7,“传统模式下的审计日志过滤”
)。
使用基于规则的审计日志过滤,这些变量仍然可见(例如,使用
),但是对它们的更改不起作用,除非您编写包含引用它们的构造的过滤器。
audit_log_
xxx
_policySHOW
VARIABLES
以下列表描述了
variable
项目
允许的预定义变量
:
audit_log_connection_policy_value
此变量对应于
audit_log_connection_policy
系统变量
的值
。
该值是无符号整数。
表6.33“audit_log_connection_policy_value值”
显示允许值和相应的
audit_log_connection_policy
值。
表6.33 audit_log_connection_policy_value值
值 | 对应的audit_log_connection_policy值 |
---|---|
0
要么
"::none"
|
NONE |
1
要么
"::errors"
|
ERRORS |
2
要么
"::all"
|
ALL |
的
值是符号伪常量可以给出的,而不是字面数值。
它们必须作为字符串引用并且区分大小写。
"::
xxx
"
audit_log_policy_value
此变量对应于
audit_log_policy
系统变量
的值
。
该值是无符号整数。
表6.34“audit_log_policy_value值”
显示允许值和相应的
audit_log_policy
值。
表6.34 audit_log_policy_value值
值 | 对应的audit_log_policy值 |
---|---|
0
要么
"::none"
|
NONE |
1
要么
"::logins"
|
LOGINS |
2
要么
"::all"
|
ALL |
3
要么
"::queries"
|
QUERIES |
的
值是符号伪常量可以给出的,而不是字面数值。
它们必须作为字符串引用并且区分大小写。
"::
xxx
"
audit_log_statement_policy_value
此变量对应于
audit_log_statement_policy
系统变量
的值
。
该值是无符号整数。
表6.35“audit_log_statement_policy_value值”
显示允许值和相应的
audit_log_statement_policy
值。
表6.35 audit_log_statement_policy_value值
值 | 对应的audit_log_statement_policy值 |
---|---|
0
要么
"::none"
|
NONE |
1
要么
"::errors"
|
ERRORS |
2
要么
"::all"
|
ALL |
的
值是符号伪常量可以给出的,而不是字面数值。
它们必须作为字符串引用并且区分大小写。
"::
xxx
"
要引用条件中的预定义函数
log
,请使用
function
项目,其中取值
name
和
args
值分别指定函数名称及其参数:
{ “过滤器”:{ “class”:{ “名字”:“一般”, “event”:{ “名称”:“状态”, “log”:{ “功能”:{ “name”:“find_in_include_list”, “args”:[{“string”:[{“field”:“user.str”}, {“string”:“@”}, {“field”:“host.str”}]}] } } } } } }
name
项目中
指定
的函数应该只是函数名称,没有括号或参数列表。
args
必须按照函数说明中列出的顺序给出项目中的
参数
(如果有)。
参数可以指预定义变量,事件字段或字符串或数字常量。
前面的过滤器根据是否
在
系统变量中
找到当前用户
来确定是否记录
general
类
status
事件
audit_log_include_accounts
。
该用户是使用事件中的字段构建的。
以下列表描述了
function
项目
的允许预定义功能
:
audit_log_exclude_accounts_is_null()
检查
audit_log_exclude_accounts
系统变量
是否
为
NULL
。
定义与旧审计日志实现相对应的过滤器时,此功能非常有用。
参数:
没有。
audit_log_include_accounts_is_null()
检查
audit_log_include_accounts
系统变量
是否
为
NULL
。
定义与旧审计日志实现相对应的过滤器时,此功能非常有用。
参数:
没有。
debug_sleep(millisec)
睡眠时间为给定的毫秒数。 在性能测量期间使用此功能。
debug_sleep()
仅适用于调试版本。
参数:
millisec
:无符号整数,指定要休眠的毫秒数。
find_in_exclude_list(account)
检查审核日志排除列表中是否存在帐户字符串(
audit_log_exclude_accounts
系统变量
的值
)。
参数:
account
:一个指定用户帐户名称的字符串。
find_in_include_list(account)
检查审计日志包含列表中是否存在帐户字符串(
audit_log_include_accounts
系统变量
的值
)。
参数:
account
:一个指定用户帐户名称的字符串。
string_find(text, substr)
检查
substr
值是否包含在
text
值中。
此搜索区分大小写。
参数:
text
:要搜索的文本字符串。
substr
:要搜索的子字符串
text
。
在某些情况下,可以动态更改过滤器定义。
为此,请
filter
在现有内部
定义
配置
filter
。
例如:
{ “过滤器”:{ “id”:“主”, “class”:{ “name”:“table_access”, “event”:{ “名称”:[“更新”,“删除”], “log”:false, “过滤器”:{ “class”:{ “名字”:“一般”, “event”:{“name”:“status”, “过滤器”:{“ref”:“main”}} }, “启用”: { “要么”: [ {“field”:{“name”:“table_name.str”,“value”:“temp_1”}}, {“field”:{“name”:“table_name.str”,“value”:“temp_2”}} ] } } } } } }
当子过滤器中的
activate
元素求值
时,将激活新过滤器
true
。
不允许
activate
在顶级
使用
filter
。
通过使用子
ref
过滤器内的项目来引用原始过滤
器,可以用原始过滤器替换新过滤
器
id
。
显示的过滤器操作如下:
该
main
过滤器等待
table_access
的事件,无论是
update
或
delete
。
如果
update
or或
delete
table_access
事件发生在
temp_1
或
temp_2
表上,则过滤器将替换为内部过滤器(没有
id
,因为不需要明确引用它)。
如果命令结束命令(
general
/
status
event),则会将一个条目写入审核日志文件,并将过滤器替换为
main
过滤器。
该过滤器是有用的日志陈述,更新或从删除任何东西
temp_1
或
temp_2
表,像这样的:
UPDATE temp_1,temp_3 SET temp_1.a = 21,temp_3.a = 23;
该语句生成多个
table_access
事件,但审核日志文件仅包含
general
/
status
entries。
id
定义中使用的
任何
值仅针对该定义进行评估。
它们与
audit_log_filter_id
系统变量
的值无关
。
本节介绍旧版审核日志过滤,该过滤适用于
audit_log
安装
了
插件但不适用于基于规则的过滤所需的随附审核表和UDF。
审核日志插件可以过滤审核事件。 这使您可以根据事件发起的帐户或事件状态来控制是否将审计事件写入审计日志文件。 状态筛选分别针对连接事件和语句事件进行。
要根据原始帐户筛选审计事件,请在服务器启动或运行时设置其中一个系统变量:
audit_log_include_accounts
:要包含在审核日志记录中的帐户。
如果设置了此变量,则仅审核这些帐户。
audit_log_exclude_accounts
:要从审核日志记录中排除的帐户。
如果设置了此变量,则会审核除这些帐户之外的所有帐户。
任一变量的值都可以是
NULL
包含一个或多个逗号分隔帐户名的字符串,每个帐户名都有
格式。
默认情况下,
在这种情况
下,两个变量都
不会进行帐户过滤,并且会对所有帐户进行审核。
user_name
@host_name
NULL
仅
修改
audit_log_include_accounts
或
audit_log_exclude_accounts
影响
修改后
创建的连接,而不是现有连接。
示例:要启用审核日志记录只为
user1
与
user2
本地主机帐户帐户,设置
audit_log_include_accounts
这样的系统变量:
SET GLOBAL audit_log_include_accounts ='user1 @ localhost,user2 @ localhost';
一次只能一个
audit_log_include_accounts
或
audit_log_exclude_accounts
不一个非
NULL
:
如果设置
audit_log_include_accounts
,则服务器设置
audit_log_exclude_accounts
为
NULL
。
如果您尝试设置
audit_log_exclude_accounts
,则会发生错误,除非
audit_log_include_accounts
是
NULL
。
在这种情况下,您必须先将
audit_log_include_accounts
其设置为
清除
NULL
。
- 这将audit_log_exclude_accounts设置为NULL SET GLOBAL audit_log_include_accounts =value
; - 由于audit_log_include_accounts不为NULL,因此失败 SET GLOBAL audit_log_exclude_accounts =value
; - 要设置audit_log_exclude_accounts,请先设置 - audit_log_include_accounts为NULL SET GLOBAL audit_log_include_accounts = NULL; SET GLOBAL audit_log_exclude_accounts =value
;
如果检查任一变量的值,请注意
SHOW VARIABLES
显示
NULL
为空字符串。
为避免这种情况,请
SELECT
改用:
MySQL的>SHOW VARIABLES LIKE 'audit_log_include_accounts';
+ ---------------------------- + ------- + | Variable_name | 价值| + ---------------------------- + ------- + | audit_log_include_accounts | | + ---------------------------- + ------- + MySQL的>SELECT @@audit_log_include_accounts;
+ ------------------------------ + | @@ audit_log_include_accounts | + ------------------------------ + | NULL | + ------------------------------ +
如果用户名或主机名需要引用,因为它包含逗号,空格或其他特殊字符,请使用单引号引用它。
如果变量值本身用单引号引用,则将每个内部单引号加倍或使用反斜杠对其进行转义。
以下语句均为本地
root
帐户
启用审核日志记录,
并且等效,即使引用样式不同:
SET GLOBAL audit_log_include_accounts ='root @ localhost'; SET GLOBAL audit_log_include_accounts ='''root''@''localhost'''; SET GLOBAL audit_log_include_accounts ='\'root \'@ \'localhost \''; SET GLOBAL audit_log_include_accounts =“'root'@'localhost'”;
如果
ANSI_QUOTES
启用
了
SQL模式,则
最后一个语句将不起作用,
因为在该模式下双引号表示标识符引用,而不是字符串引用。
要根据状态筛选审计事件,请在服务器启动或运行时设置以下系统变量。 这些变量仅适用于旧版审核日志筛选。 对于JSON审核日志筛选,应用不同的状态变量; 请参见 第6.4.5.8.4节“审核日志选项和变量” 。
audit_log_connection_policy
:连接事件的记录策略
audit_log_statement_policy
:记录事件的记录策略
每个变量的值为
ALL
(记录所有关联事件;这是默认值),
ERRORS
(仅记录失败事件)或
NONE
(不记录事件)。
例如,要记录所有语句事件但仅记录失败的连接事件,请使用以下设置:
SET GLOBAL audit_log_statement_policy = ALL; SET GLOBAL audit_log_connection_policy =错误;
另一项政策系统变量,
audit_log_policy
是可用的,但不提供尽可能多的控制,
audit_log_connection_policy
和
audit_log_statement_policy
。
它只能在服务器启动时设置。
在运行时,它是一个只读变量。
它取值
ALL
(记录所有事件;这是默认值),
LOGINS
(日志连接事件),
QUERIES
(日志语句事件)或
NONE
(不记录事件)。
对于任何这些值,审计日志插件会记录所有选定事件,而不会区分成功或失败。
audit_log_policy
启动时的
使用
如下:
如果未将
audit_log_policy
其
设置
或设置为其默认值
ALL
,则为
指定的
任何显式设置
audit_log_connection_policy
或
audit_log_statement_policy
应用。
如果未指定,则默认为
ALL
。
如果设置
audit_log_policy
为一个非
ALL
值,该值优于并可用于设置
audit_log_connection_policy
和
audit_log_statement_policy
,如下表所示。
如果还将这些变量中的任何一个设置为默认值以外的值
ALL
,则服务器会将消息写入错误日志以指示其值已被覆盖。
启动audit_log_policy值 | 产生的audit_log_connection_policy值 | 产生的audit_log_statement_policy值 |
---|---|---|
LOGINS |
ALL |
NONE |
QUERIES |
NONE |
ALL |
NONE |
NONE |
NONE |
以下讨论作为MySQL Enterprise Audit组件的参考:
要安装审核日志表和函数,请使用
第6.4.5.2节“安装或卸载MySQL Enterprise Audit”中提供的说明
。
除非安装了这些组件,否则
audit_log
插件将以传统模式运行。
请参见
第6.4.5.7节“传统模式审核日志过滤”
。
MySQL Enterprise Audit使用
mysql
系统数据库中的
表
来持久存储过滤器和用户帐户数据。
只有具有该数据库权限的用户才能访问这些表。
表使用
InnoDB
存储引擎。
如果缺少这些表,则
audit_log
插件将以传统模式运行。
请参见
第6.4.5.7节“传统模式审核日志过滤”
。
该
audit_log_filter
表存储过滤器定义。
该表包含以下列:
NAME
过滤器名称。
FILTER
与筛选器名称关联的筛选器定义。
定义存储为
JSON
值。
该
audit_log_user
表存储用户帐户信息。
该表包含以下列:
USER
帐户的用户名部分。
对于一个帐户
user1@localhost
,该
USER
部分是
user1
。
HOST
帐户的主机名部分。
对于一个帐户
user1@localhost
,该
HOST
部分是
localhost
。
FILTERNAME
分配给帐户的过滤器的名称。
过滤器名称将帐户与
audit_log_filter
表中
定义的过滤器相关联
。
本节描述了每个审计日志用户定义函数(UDF),其用途,调用顺序和返回值。 有关可以调用这些UDF的条件的信息,请参见 第6.4.5.6节“审核日志过滤” 。
每个审核日志UDF都返回一个字符串,指示操作是否成功。
OK
表示成功。
表示失败。
ERROR:
message
这些审核日志UDF可用:
audit_log_encryption_password_get()
以二进制字符串形式检索当前审核日志加密密码。 密码是从MySQL密钥环中获取的,必须启用该密钥环或发生错误。 可以使用任何密钥环插件; 有关说明,请参见 第6.4.4节“MySQL密钥环” 。
有关审核日志加密的其他信息,请参阅 审核日志文件加密 。
参数:
没有。
返回值:
成功的密码字符串(最多766个字节),或
NULL
失败的错误。
例:
MySQL的> SELECT audit_log_encryption_password_get();
+ ------------------------------- +
| audit_log_encryption_password_get()|
+ ------------------------------- +
| 秘密|
+ ------------------------------- +
audit_log_encryption_password_set(
password
)
将审核日志加密密码设置为参数,将密码存储在MySQL密钥环中。 如果启用了加密,则该函数将执行日志文件循环操作,该操作将重命名当前日志文件,并开始使用密码加密的新日志文件。 必须启用密钥环或发生错误。 可以使用任何密钥环插件; 有关说明,请参见 第6.4.4节“MySQL密钥环” 。
有关审核日志加密的其他信息,请参阅 审核日志文件加密 。
参数:
password
:密码字符串。
允许的最大长度为766字节。
返回值:
1表示成功,0表示失败。
例:
MySQL的>SELECT audit_log_encryption_password_set(
+ --------------------------------------------- + | audit_log_encryption_password_set(password
);password
)| + --------------------------------------------- + | 1 | + --------------------------------------------- +
调用任何其他过滤UDF会立即影响操作审核日志筛选并更新审核日志表。
相反,如果你修改这些表的内容,直接使用语句,例如
INSERT
,
UPDATE
和
DELETE
,所做的更改不会影响立即过滤。
要刷新更改并使其可操作,请致电
audit_log_filter_flush()
。
audit_log_filter_flush()
只有在直接修改审计表后才能使用,强制重新加载所有过滤器。
否则,应避免使用此功能。
它实际上是,卸载的简化版本并重新加载
audit_log
与插件
UNINSTALL PLUGIN
加
INSTALL PLUGIN
。
audit_log_filter_flush()
影响所有当前会话并将它们与之前的过滤器分离。
除非断开连接并重新连接或执行更改用户操作,否则不再记录当前会话。
如果此函数失败,则会返回错误消息,并且在下次成功调用之前将禁用审核日志
audit_log_filter_flush()
。
参数:
没有。
返回值:
一个字符串,指示操作是否成功。
OK
表示成功。
表示失败。
ERROR:
message
例:
MySQL的> SELECT audit_log_filter_flush();
+ -------------------------- +
| audit_log_filter_flush()|
+ -------------------------- +
| 好的
+ -------------------------- +
audit_log_filter_remove_filter(
filter_name
)
给定过滤器名称,从当前过滤器集中删除过滤器。 过滤器不存在不是错误。
如果为任何用户帐户分配了已删除的筛选器,则会停止筛选这些用户(将从
audit_log_user
表
中删除这些筛选器
)。
终止过滤包括这些用户的任何当前会话:它们与过滤器分离,不再记录。
参数:
filter_name
:一个指定过滤器名称的字符串。
返回值:
一个字符串,指示操作是否成功。
OK
表示成功。
表示失败。
ERROR:
message
例:
MySQL的> SELECT audit_log_filter_remove_filter('SomeFilter');
+ ---------------------------------------------- +
| audit_log_filter_remove_filter('SomeFilter')|
+ ---------------------------------------------- +
| 好的
+ ---------------------------------------------- +
audit_log_filter_remove_user(
user_name
)
给定用户帐户名称,导致用户不再被分配到过滤器。 如果用户未分配过滤器,则不会出错。 为用户过滤当前会话不受影响。 如果存在,则使用默认帐户过滤器过滤用户的新连接,否则不会记录。
如果名称为
%
,则该函数将删除用于未明确分配过滤器的任何用户帐户的默认帐户过滤器。
参数:
user_name
:用户帐户名称
格式
为字符串
,或
表示默认帐户。
user_name
@host_name
%
返回值:
一个字符串,指示操作是否成功。
OK
表示成功。
表示失败。
ERROR:
message
例:
MySQL的> SELECT audit_log_filter_remove_user('user1@localhost');
+ ------------------------------------------------- +
| audit_log_filter_remove_user('user1 @ localhost')|
+ ------------------------------------------------- +
| 好的
+ ------------------------------------------------- +
audit_log_filter_set_filter(
filter_name
,
definition
)
给定过滤器名称和定义,将过滤器添加到当前过滤器集。 如果过滤器已存在且由任何当前会话使用,则这些会话将从过滤器中分离,并且不再记录。 发生这种情况是因为新过滤器定义具有与其先前ID不同的新过滤器ID。
参数:
filter_name
:一个指定过滤器名称的字符串。
definition
:一个
JSON
指定过滤器定义的值。
返回值:
一个字符串,指示操作是否成功。
OK
表示成功。
表示失败。
ERROR:
message
例:
mysql>SET @f = '{ "filter": { "log": false } }';
mysql>SELECT audit_log_filter_set_filter('SomeFilter', @f);
+ ----------------------------------------------- + | audit_log_filter_set_filter('SomeFilter',@ f)| + ----------------------------------------------- + | 好的 + ----------------------------------------------- +
audit_log_filter_set_user(
user_name
,
filter_name
)
给定用户帐户名称和过滤器名称,将过滤器分配给用户。 用户只能分配一个过滤器,因此如果已为用户分配过滤器,则替换分配。 为用户过滤当前会话不受影响。 使用新过滤器过滤新连接。
作为特殊情况,名称
%
表示默认帐户。
过滤器用于来自未明确指定过滤器的任何用户帐户的连接。
参数:
user_name
:用户帐户名称
格式
为字符串
,或
表示默认帐户。
user_name
@host_name
%
filter_name
:一个指定过滤器名称的字符串。
返回值:
一个字符串,指示操作是否成功。
OK
表示成功。
表示失败。
ERROR:
message
例:
MySQL的> SELECT audit_log_filter_set_user('user1@localhost', 'SomeFilter');
+ ------------------------------------------------- ----------- +
| audit_log_filter_set_user('user1 @ localhost','SomeFilter')|
+ ------------------------------------------------- ----------- +
| 好的
+ ------------------------------------------------- ----------- +
从审计日志中读取事件并返回
JSON
包含审计事件数组的
二进制
字符串。
如果不是审核日志格式
JSON
,则会发生错误。
返回值中的每个事件都是一个
JSON
哈希值,但最后一个数组元素可能是一个
值,表示没有后续事件可供读取。
JSON
null
对于
audit_log_read()
在会话中
的第一次调用
,传递指示从哪里开始阅读的书签。
如果返回的数组的最终值不是
值,则在刚读取的数据之后会有更多事件,并且
可以在没有或带有书签参数的情况下调用。
如果没有参数,则继续阅读下一个未读事件。
使用书签参数,从书签继续读取。
JSON
null
audit_log_read()
如果返回的数组的最终值是一个
值,则不再有剩余的事件需要读取,下一次调用
必须包含书签参数。
JSON
null
audit_log_read()
要获取最近编写的事件的书签,请致电
audit_log_read_bookmark()
。
有关审核日志读取功能的其他信息,请参阅 审核日志文件读取 。
参数:
arg
:可选书签,表示为包含
JSON
指示读取位置和内容
的
散列
的字符串
。
以下项目的
arg
值
很重要
(其他项目被忽略):
timestamp
,
id
:要读取的第一个事件的审核日志中的位置。
必须存在两个项目才能完全指定位置。
max_array_length
:从日志中读取的最大事件数。
如果省略,则默认为读取日志结尾或读取缓冲区已满,以先到者为准。
返回值:
二进制
JSON
字符串,包含成功的审计事件数组,或
NULL
失败错误。
例:
MySQL的> SELECT audit_log_read(audit_log_read_bookmark());
+ ------------------------------------------------- ---------------------- +
| audit_log_read(audit_log_read_bookmark())|
+ ------------------------------------------------- ---------------------- +
| [{“timestamp”:“2018-01-15 22:41:24”,“id”:0,“class”:“connection”,... |
+ ------------------------------------------------- ---------------------- +
返回
JSON
表示最近编写的审核日志事件的书签
的二进制
字符串。
如果不是审核日志格式
JSON
,则会发生错误。
书签是
JSON
哈希,
timestamp
其中的
id
项目表示审计日志中的事件位置。
它适用于传递以
audit_log_read()
指示该功能从何处开始阅读。
有关审核日志读取功能的其他信息,请参阅 审核日志文件读取 。
参数:
没有。
返回值:
JSON
包含成功书签的
二进制
字符串,或
NULL
失败错误。
例:
MySQL的> SELECT audit_log_read_bookmark();
+ ------------------------------------------------- +
| audit_log_read_bookmark()|
+ ------------------------------------------------- +
| {“timestamp”:“2018-01-15 21:03:44”,“id”:0} |
+ ------------------------------------------------- +
表6.36审核日志选项和变量引用
名称 | CMD线 | 选项文件 | 系统变量 | 状态变量 | Var范围 | 动态 |
---|---|---|---|---|---|---|
审计日志 | 是 | 是 | ||||
audit_log_buffer_size | 是 | 是 | 是 | 全球 | 没有 | |
audit_log_compression | 是 | 是 | 是 | 全球 | 没有 | |
audit_log_connection_policy | 是 | 是 | 是 | 全球 | 是 | |
audit_log_current_session | 是 | 都 | 没有 | |||
Audit_log_current_size | 是 | 全球 | 没有 | |||
audit_log_encryption | 是 | 是 | 是 | 全球 | 没有 | |
Audit_log_event_max_drop_size | 是 | 全球 | 没有 | |||
Audit_log_events | 是 | 全球 | 没有 | |||
Audit_log_events_filtered | 是 | 全球 | 没有 | |||
Audit_log_events_lost | 是 | 全球 | 没有 | |||
Audit_log_events_written | 是 | 全球 | 没有 | |||
audit_log_exclude_accounts | 是 | 是 | 是 | 全球 | 是 | |
audit_log_file | 是 | 是 | 是 | 全球 | 没有 | |
audit_log_filter_id | 是 | 都 | 没有 | |||
audit_log_flush | 是 | 全球 | 是 | |||
audit_log_format | 是 | 是 | 是 | 全球 | 没有 | |
audit_log_include_accounts | 是 | 是 | 是 | 全球 | 是 | |
audit_log_policy | 是 | 是 | 是 | 全球 | 没有 | |
audit_log_read_buffer_size | 是 | 是 | 是 | 不定 | 不定 | |
audit_log_rotate_on_size | 是 | 是 | 是 | 全球 | 是 | |
audit_log_statement_policy | 是 | 是 | 是 | 全球 | 是 | |
audit_log_strategy | 是 | 是 | 是 | 全球 | 没有 | |
Audit_log_total_size | 是 | 全球 | 没有 | |||
Audit_log_write_waits | 是 | 全球 | 没有 |
本节介绍配置MySQL Enterprise Audit操作的命令选项和系统变量。
如果在启动时指定的值不正确,则
audit_log
插件可能无法正确初始化,并且服务器无法加载它。
在这种情况下,服务器还可能会为其他审核日志设置生成错误消息,因为它无法识别它们。
要配置审核日志插件的激活,请使用此选项:
属性 | 值 |
---|---|
命令行格式 | --audit-log[=value] |
介绍 | 8.0.11 |
类型 | 列举 |
默认值 | ON |
有效值 |
|
此选项控制服务器
audit_log
在启动时
加载
插件的方式。
仅当插件先前已注册
INSTALL
PLUGIN
或已加载
--plugin-load
或时,
它才可
用
--plugin-load-add
。
请参见
第6.4.5.2节“安装或卸载MySQL Enterprise Audit”
。
选项值应该是可用于插件加载选项的选项之一,如
第5.6.1节“安装和卸载插件”中所述
。
例如,
--audit-log=FORCE_PLUS_PERMANENT
告诉服务器加载插件并防止在服务器运行时删除它。
如果启用了审计日志插件,它会公开几个允许控制日志记录的系统变量:
MySQL的> SHOW VARIABLES LIKE 'audit_log%';
+ ----------------------------- + -------------- +
| Variable_name | 价值|
+ ----------------------------- + -------------- +
| audit_log_buffer_size | 1048576 |
| audit_log_connection_policy | 所有|
| audit_log_current_session | 关闭|
| audit_log_exclude_accounts | |
| audit_log_file | audit.log |
| audit_log_filter_id | 0 |
| audit_log_flush | 关闭|
| audit_log_format | 新|
| audit_log_include_accounts | |
| audit_log_policy | 所有|
| audit_log_rotate_on_size | 0 |
| audit_log_statement_policy | 所有|
| audit_log_strategy | 异步|
+ ----------------------------- + -------------- +
您可以在服务器启动时设置任何这些变量,并在运行时设置其中一些变量。 仅注意那些仅适用于传统模式审核日志过滤的那些。
属性 | 值 |
---|---|
命令行格式 | --audit-log-buffer-size=# |
介绍 | 8.0.11 |
系统变量 | audit_log_buffer_size |
范围 | 全球 |
动态 | 没有 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 1048576 |
最低价值 | 4096 |
最大值 (64位平台) | 18446744073709547520 |
最大值 (32位平台) | 4294967295 |
当审计日志插件异步地将事件写入日志时,它会在写入事件内容之前使用缓冲区来存储事件内容。 此变量控制该缓冲区的大小(以字节为单位)。 服务器将值调整为4096的倍数。插件使用单个缓冲区,它在初始化时分配,在终止时删除。 仅当日志记录是异步时,插件才会分配此缓冲区。
属性 | 值 |
---|---|
命令行格式 | --audit-log-compression=value |
介绍 | 8.0.11 |
系统变量 | audit_log_compression |
范围 | 全球 |
动态 | 没有 |
SET_VAR
提示适用
|
没有 |
类型 | 列举 |
默认值 | NONE |
有效值 |
|
审核日志文件的压缩类型。
允许的值是
NONE
(无压缩;默认值)和
GZIP
(GNU Zip压缩)。
有关更多信息,请参阅
审核日志文件压缩
。
属性 | 值 |
---|---|
命令行格式 | --audit-log-connection-policy=value |
介绍 | 8.0.11 |
系统变量 | audit_log_connection_policy |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 列举 |
默认值 | ALL |
有效值 |
|
此变量仅适用于传统模式审核日志筛选(请参见 第6.4.5.7节“传统模式审核日志筛选” )。
控制审核日志插件如何将连接事件写入其日志文件的策略。 下表显示了允许的值。
值 | 描述 |
---|---|
ALL |
记录所有连接事件 |
ERRORS |
仅记录失败的连接事件 |
NONE |
不记录连接事件 |
在服务器启动时,
audit_log_connection_policy
如果
audit_log_policy
还指定了
任何给定的显式值,
则可以覆盖
它,如
第6.4.5.5节“审计日志记录配置”中所述
。
属性 | 值 |
---|---|
介绍 | 8.0.11 |
系统变量 | audit_log_current_session |
范围 | 全球,会议 |
动态 | 没有 |
SET_VAR
提示适用
|
没有 |
类型 | 布尔 |
默认值 | depends on filtering policy |
是否为当前会话启用了审核日志记录。
此变量的会话值是只读的。
它是在会话开始时根据
audit_log_include_accounts
和
audit_log_exclude_accounts
系统变量
的值设置的
。
审核日志插件使用会话值来确定是否审核会话的事件。
(有一个全局值,但插件不使用它。)
属性 | 值 |
---|---|
命令行格式 | --audit-log-encryption=value |
介绍 | 8.0.11 |
系统变量 | audit_log_encryption |
范围 | 全球 |
动态 | 没有 |
SET_VAR
提示适用
|
没有 |
类型 | 列举 |
默认值 | NONE |
有效值 |
|
审核日志文件的加密类型。
允许的值是
NONE
(无加密;默认值)和
AES
(AES-256-CBC密码加密)。
有关更多信息,请参阅
审核日志文件加密
。
属性 | 值 |
---|---|
命令行格式 | --audit-log-exclude-accounts=value |
介绍 | 8.0.11 |
系统变量 | audit_log_exclude_accounts |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
默认值 | NULL |
此变量仅适用于传统模式审核日志筛选(请参见 第6.4.5.7节“传统模式审核日志筛选” )。
不应记录事件的帐户。
该值应为
NULL
或包含一个或多个逗号分隔帐户名列表的字符串。
有关更多信息,请参见
第6.4.5.6节“审核日志过滤”
。
修改
audit_log_exclude_accounts
仅影响
修改后
创建的连接,而不影响现有连接。
属性 | 值 |
---|---|
命令行格式 | --audit-log-file=file_name |
介绍 | 8.0.11 |
系统变量 | audit_log_file |
范围 | 全球 |
动态 | 没有 |
SET_VAR
提示适用
|
没有 |
类型 | 文件名 |
默认值 | audit.log |
审计日志插件将事件写入的文件的基本名称和后缀。
audit.log
无论日志记录格式如何,
默认值均为
。
要使名称后缀与格式相对应,请明确设置名称,选择不同的后缀(例如,
audit.xml
对于XML格式,
audit.json
对于JSON格式)。
如果值
audit_log_file
是相对路径名,则插件会相对于数据目录解释它。
如果值是完整路径名,则插件将按原样使用该值。
如果需要在单独的文件系统或目录上查找审计文件,则完整路径名可能很有用。
出于安全原因,请将审核日志文件写入仅可供MySQL服务器访问的目录以及具有查看日志的合法理由的用户。
有关审核日志插件如何解释
audit_log_file
插件初始化和终止时发生的文件重命名
的
值和规则的
详细信息
,请参阅
审核日志文件名
。
审核日志插件使用包含审核日志文件的目录(根据
audit_log_file
值
确定
)作为搜索可读审核日志文件的位置。
从这些日志文件和当前文件中,插件构造了一个列表,列出了与审计日志书签和阅读功能一起使用的列表。
请参阅
审核日志文件读取
。
属性 | 值 |
---|---|
介绍 | 8.0.11 |
系统变量 | audit_log_filter_id |
范围 | 全球,会议 |
动态 | 没有 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
此变量的会话值指示当前会话的审计筛选器的内部维护ID。 值为0表示会话未分配过滤器。
属性 | 值 |
---|---|
介绍 | 8.0.11 |
系统变量 | audit_log_flush |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 布尔 |
默认值 | OFF |
当此变量设置为enabled(1或
ON
)时,审计日志插件将关闭并重新打开其日志文件以对其进行刷新。
(该值保持不变,
OFF
因此您无需在再次启用它之前显式禁用它以执行另一次刷新。)启用此变量无效,除非
audit_log_rotate_on_size
为0.有关更多信息,请参见
第6.4.5.5节“审核日志记录配置”
。
属性 | 值 |
---|---|
命令行格式 | --audit-log-format=value |
介绍 | 8.0.11 |
系统变量 | audit_log_format |
范围 | 全球 |
动态 | 没有 |
SET_VAR
提示适用
|
没有 |
类型 | 列举 |
默认值 | NEW |
有效值 |
|
审核日志文件格式。
允许的值是
OLD
(旧式XML),
NEW
(新式XML;默认值)和
JSON
。
有关每种格式的详细信息,请参见
第6.4.5.4节“审核日志文件格式”
。
有关更改日志格式时要考虑的问题的信息,请参阅 审核日志文件格式 。
属性 | 值 |
---|---|
命令行格式 | --audit-log-include-accounts=value |
介绍 | 8.0.11 |
系统变量 | audit_log_include_accounts |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 串 |
默认值 | NULL |
此变量仅适用于传统模式审核日志筛选(请参见 第6.4.5.7节“传统模式审核日志筛选” )。
应记录事件的帐户。
该值应为
NULL
或包含一个或多个逗号分隔帐户名列表的字符串。
有关更多信息,请参见
第6.4.5.6节“审核日志过滤”
。
修改
audit_log_include_accounts
仅影响
修改后
创建的连接,而不影响现有连接。
属性 | 值 |
---|---|
命令行格式 | --audit-log-policy=value |
介绍 | 8.0.11 |
系统变量 | audit_log_policy |
范围 | 全球 |
动态 | 没有 |
SET_VAR
提示适用
|
没有 |
类型 | 列举 |
默认值 | ALL |
有效值 |
|
此变量仅适用于传统模式审核日志筛选(请参见 第6.4.5.7节“传统模式审核日志筛选” )。
控制审核日志插件如何将事件写入其日志文件的策略。 下表显示了允许的值。
值 | 描述 |
---|---|
ALL |
记录所有事件 |
LOGINS |
仅记录登录事件 |
QUERIES |
仅记录查询事件 |
NONE |
什么都不记录(禁用审计流) |
audit_log_policy
只能在服务器启动时设置。
在运行时,它是一个只读变量。
另外两个系统变量,
audit_log_connection_policy
并
audit_log_statement_policy
提供了日志记录策略更精细的控制,并可以在启动或运行时设置。
如果
audit_log_policy
在启动时
使用
而不是其他两个变量,则服务器使用其值来设置这些变量。
有关策略变量及其交互的更多信息,请参见
第6.4.5.5节“审核日志记录配置”
。
属性 | 值 |
---|---|
命令行格式 | --audit-log-read-buffer-size=# |
介绍 | 8.0.11 |
系统变量 (> = 8.0.11) | audit_log_read_buffer_size |
范围 (> = 8.0.12) | 全球,会议 |
范围 (8.0.11) | 全球 |
动态 (> = 8.0.12) | 是 |
动态 (8.0.11) | 没有 |
SET_VAR
提示适用
(> = 8.0.11)
|
没有 |
类型 | 整数 |
默认值 (> = 8.0.12) | 32768 |
默认值 (8.0.11) | 1048576 |
最小值 (> = 8.0.12) | 32768 |
最低价值 (8.0.11) | 1024 |
最大价值 | 4194304 |
从审计日志文件中读取的缓冲区大小(以字节为单位)。
该
audit_log_read()
函数读取的字节数不超过这个字节。
仅支持JSON日志格式的日志文件读取。
有关更多信息,请参阅
审核日志文件读取
。
从MySQL 8.0.12开始,此变量的默认值为32KB,可以在运行时设置。
每个客户端应该
audit_log_read_buffer_size
为其使用适当地
设置其会话值
audit_log_read()
。
在MySQL 8.0.12之前,
audit_log_read_buffer_size
默认值为1MB,影响所有客户端,并且只能在服务器启动时更改。
属性 | 值 |
---|---|
命令行格式 | --audit-log-rotate-on-size=# |
介绍 | 8.0.11 |
系统变量 | audit_log_rotate_on_size |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 整数 |
默认值 | 0 |
如果
audit_log_rotate_on_size
值为0,则审核日志插件不会执行自动日志文件轮换。
而是
audit_log_flush
用于关闭并重新打开按需记录。
在这种情况下,请在刷新之前手动将文件重命名为服务器。
如果该
audit_log_rotate_on_size
值大于0,则会发生基于自动大小的日志文件轮换。
每当写入日志文件导致其大小超过
audit_log_rotate_on_size
值,审计日志插件就会关闭当前日志文件,重命名该日志文件并打开新的日志文件。
有关审核日志文件轮换的详细信息,请参阅 审核日志文件空间管理和名称轮换 。
如果将此变量设置为不是4096的倍数的值,则会将其截断为最接近的倍数。 (因此,将其设置为小于4096的值会将其设置为0并且不会发生旋转,除非手动。)
属性 | 值 |
---|---|
命令行格式 | --audit-log-statement-policy=value |
介绍 | 8.0.11 |
系统变量 | audit_log_statement_policy |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 列举 |
默认值 | ALL |
有效值 |
|
此变量仅适用于传统模式审核日志筛选(请参见 第6.4.5.7节“传统模式审核日志筛选” )。
控制审计日志插件如何将语句事件写入其日志文件的策略。 下表显示了允许的值。
值 | 描述 |
---|---|
ALL |
记录所有语句事件 |
ERRORS |
仅记录失败的语句事件 |
NONE |
不记录语句事件 |
在服务器启动时,
audit_log_statement_policy
如果
audit_log_policy
还指定了
任何给定的显式值,
则可以覆盖
它,如
第6.4.5.5节“审计日志记录配置”中所述
。
属性 | 值 |
---|---|
命令行格式 | --audit-log-strategy=value |
介绍 | 8.0.11 |
系统变量 | audit_log_strategy |
范围 | 全球 |
动态 | 没有 |
SET_VAR
提示适用
|
没有 |
类型 | 列举 |
默认值 | ASYNCHRONOUS |
有效值 |
|
审计日志插件使用的日志记录方法。 允许使用以下策略值:
ASYNCHRONOUS
:异步记录。
等待输出缓冲区中的空间。
PERFORMANCE
:异步记录。
删除输出缓冲区中空间不足的请求。
SEMISYNCHRONOUS
:同步记录。
允许操作系统进行缓存。
SYNCHRONOUS
:同步记录。
sync()
每次请求后
致电
。
如果启用了审核日志插件,则会公开几个提供操作信息的状态变量。 这些变量可用于传统模式审核筛选和JSON模式审核筛选。
当前审核日志文件的大小。 将事件写入日志时值会增加,并且在旋转日志时将值重置为0。
性能日志记录模式中最大丢弃事件的大小。 有关日志记录模式的说明,请参见 第6.4.5.5节“审核日志记录配置” 。
审计日志插件处理的事件数,无论它们是否根据过滤策略写入日志(请参见 第6.4.5.5节“审计日志记录配置” )。
审计日志插件根据过滤策略过滤(未写入日志)处理的事件数(请参见 第6.4.5.5节“审计日志记录配置” )。
由于事件大于可用审计日志缓冲区空间而在性能日志记录模式下丢失的事件数。
此值可用于评估如何设置
audit_log_buffer_size
缓冲区的性能模式大小。
有关日志记录模式的说明,请参见
第6.4.5.5节“审核日志记录配置”
。
写入审核日志的事件数。
写入所有审核日志文件的事件的总大小。
与之不同
Audit_log_current_size
,
Audit_log_total_size
即使旋转日志也会增加。
事件在异步日志记录模式下必须等待审计日志缓冲区中的空间的次数。 有关日志记录模式的说明,请参见 第6.4.5.5节“审核日志记录配置” 。
MySQL Enterprise Audit受这些一般限制的约束:
仅记录SQL语句。 不记录no-SQL API(例如memcached,Node.JS和NDB API)所做的更改。
仅记录顶级语句,而不记录存储程序(如触发器或存储过程)中的语句。
语句引用的文件内容(
LOAD
DATA
如未记录)。
NDB集群。 根据以下条件,可以将MySQL Enterprise Audit与MySQL NDB Cluster一起使用:
必须使用SQL接口完成要记录的所有更改。 不记录使用无SQL接口的更改,例如NDB API,memcached或ClusterJ提供的更改。
必须在用于在群集上执行SQL的每个MySQL服务器上安装该插件。
必须在与群集一起使用的所有MySQL服务器之间聚合审核插件数据。 此聚合是应用程序或用户的责任。
从MySQL 8.0.14开始,该
audit_api_message_emit
组件使应用程序能够使用
audit_api_message_emit_udf()
用户定义的函数
将自己的消息事件添加到审计日志中
。
该
audit_api_message_emit
组件与审计类型的所有插件协作。
具体而言,示例使用
第6.4.5节“MySQL Enterprise Audit”中
audit_log
描述
的
插件
。
要使服务器可以使用,组件库文件必须位于MySQL插件目录(
plugin_dir
系统变量
指定的目录
)中。
如有必要,通过设置
plugin_dir
服务器启动时
的值来配置插件目录位置
。
要安装
audit_api_message_emit
组件,请使用以下语句:
INSTALL COMPONENT“file:// component_audit_api_message_emit”;
组件安装是一次性操作,无需在每个服务器启动时完成。
INSTALL
COMPONENT
加载组件,并将其注册到
mysql.component
系统表中,以便在后续服务器启动期间加载它。
要卸载
audit_api_message_emit
组件,请使用以下语句:
UNINSTALL COMPONENT“file:// component_audit_api_message_emit”;
UNINSTALL COMPONENT
卸载组件,并从中取消注册
mysql.component
系统表中
以使其在后续服务器启动期间不被加载。
安装或卸载
audit_api_message_emit
组件会安装或卸载
audit_api_message_emit_udf()
组件实现
的
功能。
没有必要使用
CREATE
FUNCTION
或
DROP
FUNCTION
这样做。
本节介绍
组件
audit_api_message_emit_udf()
实现
的
用户定义函数(UDF)
audit_api_message_emit
。
在使用审核消息功能之前,请根据 安装或卸载审核消息组件中 提供的说明 安装审核消息组件 。
audit_api_message_emit_udf(
component
,
producer
,
message
[,
key
,
value
] ...)
将消息事件添加到审核日志中。 消息事件包括调用者选择的组件,生成器和消息字符串,以及可选的一组键值对。
此UDF发布的事件将发送到所有已启用的审计类型插件,每个插件都根据自己的规则处理事件。 如果未启用审核类型的插件,则发布该事件无效。
参数:
component
:一个指定组件名称的字符串。
producer
:一个指定生产者名称的字符串。
message
:一个指定事件消息的字符串。
key
,
value
:事件可能包含0个或更多键值对,这些键值对指定任意应用程序提供的数据映射。
每个
key
参数都是一个字符串,它指定紧随其后的
value
参数
的名称
。
每个
value
参数指定紧随其后的
key
参数
的值
。
每个
value
都可以是字符串或数值,或
NULL
。
返回值:
字符串
OK
表示成功
。
如果函数失败,则会发生错误。
例:
MySQL的>SELECT audit_api_message_emit_udf('component_text',
'producer_text',
'message_text',
'key1', 'value1',
'key2', 123,
'key3', NULL) AS 'Message';
+ --------- + | 消息| + --------- + | 好的 + --------- +
附加信息:
接收发布事件的每个审计插件都以
audit_api_message_emit_udf()
特定于插件的格式记录事件。
例如,
audit_log
插件(参见
第6.4.5节“MySQL Enterprise Audit”
)按如下方式记录消息值,具体取决于
audit_log_format
系统变量
配置的日志格式
:
JSON格式(
audit_log_format=JSON
):
{ ... “阶级”:“消息”, “事件”:“用户”, ... “message_data”:{ “component”:“component_text”, “producer”:“producer_text”, “message”:“message_text”, “map”:{ “key1”:“value1”, “key2”:123, “key3”:null } } }
新式XML格式(
audit_log_format=NEW
):
<AUDIT_RECORD> ... <名称>消息</ NAME> ... <COMMAND_CLASS>用户</ COMMAND_CLASS> <组件> component_text </ COMPONENT> <PRODUCER> producer_text </ PRODUCER> <MESSAGE> MESSAGE_TEXT </ MESSAGE> <MAP> <ELEMENT> <KEY> KEY1 </ KEY> <值>值1 </ VALUE> </ ELEMENT> <ELEMENT> <KEY> KEY2 </ KEY> <值> 123 </ VALUE> </ ELEMENT> <ELEMENT> <KEY> KEY3 </ KEY> <VALUE /> </ ELEMENT> </ MAP> </ AUDIT_RECORD>
旧式XML格式(
audit_log_format=OLD
):
<AUDIT_RECORD ... NAME = “消息” ... COMMAND_CLASS = “用户” COMPONENT = “component_text” 生产者= “producer_text” MESSAGE = “MESSAGE_TEXT”/>
由于此格式强加的表示性约束,以旧式XML格式记录的消息事件不包括键值映射。
发布的消息
audit_api_message_emit_udf()
具有事件类
MYSQL_AUDIT_MESSAGE_CLASS
和子类
MYSQL_AUDIT_MESSAGE_USER
。
(内部生成的审计消息具有相同的类和子类
MYSQL_AUDIT_MESSAGE_INTERNAL
;此子类当前未使用。)要在
audit_log
过滤规则中
引用此类事件
,请使用
值为的
class
元素
。
例如:
name
message
{ “过滤器”:{ “class”:{ “名字”:“消息” } } }
如果有必要区分用户生成的消息事件和内部生成的消息事件,请使用
或
测试
subclass
值
。
user
internal
不支持基于键值映射的内容进行过滤。
有关编写过滤规则的信息,请参见 第6.4.5.6节“审核日志过滤” 。
MySQL企业防火墙是商业产品MySQL企业版中的扩展。 要了解有关商业产品的更多信息,请访问 https://www.mysql.com/products/ 。
MySQL企业版包括MySQL企业防火墙,这是一个应用程序级防火墙,使数据库管理员能够根据与已接受语句模式的白名单进行匹配来允许或拒绝SQL语句执行。 这有助于强化MySQL服务器免受SQL注入等攻击或尝试通过在合法查询工作负载特征之外使用应用程序来利用应用程序。
在防火墙中注册的每个MySQL帐户都有自己的语句白名单,可以为每个帐户定制保护。 对于给定的帐户,防火墙可以在记录,保护或检测模式下操作,用于接受可接受的语句模式的训练,针对不可接受的语句的主动保护,或对不可接受的语句的被动检测。 该图说明了防火墙如何处理每种模式下的传入语句。
以下部分描述了MySQL Enterprise Firewall的组件,讨论了如何安装和使用它,并提供了其组件的参考信息。
MySQL Enterprise Firewall基于实现这些组件的插件库:
名为服务器端的插件
MYSQL_FIREWALL
在执行之前检查SQL语句,并根据其内存缓存,决定是执行还是拒绝每个语句。
服务器端插件命名
MYSQL_FIREWALL_USERS
并
MYSQL_FIREWALL_WHITELIST
实现
INFORMATION_SCHEMA
了提供防火墙数据缓存视图的表。
名为
firewall_users
和
firewall_whitelist
在
mysql
数据库
中的
系统表
提供防火墙数据的持久存储。
存储过程命名
sp_set_firewall_mode()
并
sp_reload_firewall_rules()
执行诸如向防火墙注册MySQL帐户,建立其操作模式以及管理缓存与底层系统表之间的防火墙数据传输等任务。
一组用户定义的函数为较低级别的任务提供SQL级API,例如将缓存与底层系统表同步。
系统变量启用防火墙配置,状态变量提供运行时操作信息。
FIREWALL_ADMIN
和
FIREWALL_USER
权限使用户可以分别管理任何用户的防火墙规则和他们自己的防火墙规则。
MySQL Enterprise Firewall安装是一次性操作,用于安装 第6.4.7.1节“MySQL Enterprise Firewall Components”中 描述的 组件 。 可以使用图形界面或手动执行安装:
在Windows上,MySQL Installer包含一个为您启用MySQL Enterprise Firewall的选项。
MySQL Workbench 6.3.4或更高版本可以安装MySQL Enterprise Firewall,启用或禁用已安装的防火墙,或卸载防火墙。
手动MySQL Enterprise Firewall安装涉及运行位于
share
MySQL安装目录中
的脚本
。
按照说明阅读完整部分。 部分程序因环境而异。
如果安装,MySQL Enterprise Firewall即使在禁用时也会涉及一些最小的开销。 为避免此开销,请不要安装防火墙,除非您打算使用它。
MySQL Enterprise Firewall不与查询缓存一起使用。 如果启用了查询缓存,请在安装防火墙之前将其禁用(请参阅 查询缓存配置 )。
有关使用说明,请参见 第6.4.7.3节“使用MySQL Enterprise Firewall” 。 有关参考信息,请参见 第6.4.7.4节“MySQL Enterprise Firewall Reference” 。
如果已从旧版本的MySQL安装了MySQL Enterprise Firewall,请使用本节后面给出的说明将其卸载,然后在安装当前版本之前重新启动服务器。 在这种情况下,还需要再次注册您的配置。
在Windows上,您可以使用MySQL Installer来安装MySQL Enterprise Firewall, 如图6.2“Windows上的MySQL Enterprise Firewall安装”所示 。 选中 Enable Enterprise Firewall 复选框。 ( 用于网络访问的开放式防火墙端口 具有不同的用途。它指的是Windows防火墙并控制Windows是否阻止MySQL服务器侦听客户端连接的TCP / IP端口。)
要使用MySQL Workbench 6.3.4或更高版本安装MySQL Enterprise Firewall,请参阅 MySQL Enterprise Firewall Interface 。
要手动安装MySQL Enterprise Firewall,请查看
share
MySQL安装目录并选择适合您平台的脚本。
可用脚本的不同之处在于用于引用插件库文件的后缀:
win_install_firewall.sql
:为
.dll
用作文件名后缀的
Windows系统选择此脚本
。
linux_install_firewall.sql
:为Linux和类似系统选择此脚本,
.so
用作文件名后缀。
安装脚本在默认数据库中创建存储过程,因此请选择要使用的数据库。
然后按如下所示运行脚本,在命令行上命名所选的数据库。
这里的例子使用了
mysql
数据库和Linux安装脚本。
为您的系统进行适当的替换。
shell>mysql -u root -p mysql < linux_install_firewall.sql
输入密码:(enter root password here)
要在主/从复制,组复制或InnoDB群集的上下文中使用MySQL Enterprise Firewall,必须在主节点或主节点上运行安装脚本之前准备从节点或辅助节点。
这是必要的,因为
INSTALL PLUGIN
脚本中
的
语句不会被复制。
在每个从属节点或辅助节点上,
INSTALL PLUGIN
从安装脚本中
提取
语句并手动执行它们。
在主节点或主节点上,按前面所述运行安装脚本。
使用图形界面或手动安装MySQL Enterprise Firewall应启用防火墙。 要验证这一点,请连接到服务器并执行以下语句:
MySQL的> SHOW GLOBAL VARIABLES LIKE 'mysql_firewall_mode';
+ --------------------- + ------- +
| Variable_name | 价值|
+ --------------------- + ------- +
| mysql_firewall_mode | ON |
+ --------------------- + ------- +
如果插件无法初始化,请检查服务器错误日志以获取诊断消息。
可以使用MySQL Workbench或手动卸载MySQL Enterprise Firewall。
要使用MySQL Workbench 6.3.4或更高版本卸载MySQL Enterprise Firewall,请参阅 MySQL Enterprise Firewall Interface 。
要手动卸载MySQL Enterprise Firewall,请执行以下语句。
假设存储过程是在
mysql
数据库
中创建的
。
DROP PROCEDURE
如果在其他数据库中创建过程,请相应地
调整
语句。
DROP TABLE mysql.firewall_whitelist; DROP TABLE mysql.firewall_users; UNINSTALL PLUGIN mysql_firewall; UNINSTALL PLUGIN mysql_firewall_whitelist; UNINSTALL PLUGIN mysql_firewall_users; DROP FUNCTION set_firewall_mode; DROP FUNCTION normalize_statement; DROP FUNCTION read_firewall_whitelist; DROP FUNCTION read_firewall_users; DROP FUNCTION mysql_firewall_flush_status; DROP PROCEDURE mysql.sp_set_firewall_mode; DROP PROCEDURE mysql.sp_reload_firewall_rules;
在使用MySQL Enterprise Firewall之前,请按照 第6.4.7.2节“安装或卸载MySQL Enterprise Firewall”中 提供的说明进行 安装 。 此外,MySQL Enterprise Firewall不能与查询缓存一起使用; 如果启用了查询缓存,请禁用它(请参阅 查询缓存配置 )。
本节介绍如何使用SQL语句配置MySQL Enterprise Firewall。 或者,MySQL Workbench 6.3.4或更高版本提供了防火墙控制的图形界面。 请参阅 MySQL企业防火墙接口 。
要启用或禁用防火墙,请设置
mysql_firewall_mode
系统变量。
默认情况下,安装防火墙时会启用此变量。
要显式控制初始防火墙状态,可以在服务器启动时设置变量。
例如,要在选项文件中启用防火墙,请使用以下行:
的[mysqld] mysql_firewall_mode = ON
也可以在运行时禁用或启用防火墙:
mysql>SET GLOBAL mysql_firewall_mode = OFF;
mysql>SET GLOBAL mysql_firewall_mode = ON;
除了全局开/关防火墙模式之外,在防火墙中注册的每个帐户都有自己的操作模式。 对于处于录制模式的帐户,防火墙会学习应用程序的 “ 指纹 ”。 ,即可接受的语句模式,它们组合在一起形成白名单。 训练之后,将防火墙切换到保护模式,以强化MySQL,使其不会被偏离指纹的语句访问。 要进行其他培训,请根据需要将防火墙切换回录制模式,以使用新的语句模式更新白名单。 可以使用入侵检测模式将可疑语句写入错误日志但不拒绝访问。
防火墙基于每个帐户维护白名单规则,从而实现以下保护策略:
对于具有唯一保护要求的应用程序,请将其配置为使用不用于任何其他目的的帐户。
对于相关和共享保护要求的应用程序,请将它们配置为一个组以使用同一帐户。
防火墙操作基于将SQL语句转换为规范化摘要形式。
防火墙摘要类似于性能模式使用的语句摘要(请参见
第26.10节“性能模式语句摘要和采样”
)。
但是,与性能模式不同,相关的摘要相关系统变量是
max_digest_length
。
对于来自已注册帐户的连接,防火墙会将每个传入语句转换为规范化形式,并根据帐户模式对其进行处理:
在记录模式下,防火墙会将规范化语句添加到帐户白名单规则中。
在保护模式下,防火墙将规范化语句与帐户白名单规则进行比较。
如果匹配,则语句通过,服务器继续处理它。
否则,服务器拒绝该语句并向客户端返回错误。
如果
mysql_firewall_trace
启用
了
系统变量
,防火墙还会将拒绝的语句写入错误日志
。
在检测模式下,防火墙将语句与保护模式匹配,但将不匹配语句写入错误日志而不拒绝访问。
具有
OFF
防火墙
模式
或未在防火墙中注册的
帐户将
被忽略。
要使用MySQL Enterprise Firewall保护帐户,请按照下列步骤操作:
注册帐户并将其置于录制模式。
使用已注册的帐户连接到MySQL服务器并执行要学习的语句。 这将建立帐户的已接受语句的白名单。
将注册的帐户切换到保护模式。
以下示例说明如何向防火墙注册帐户,使用防火墙了解该帐户的可接受语句,并保护帐户不被执行不可接受的语句。
示例帐户
'fwuser'@'localhost'
供供访问
sakila
数据库中的
表的应用程序使用
。
(该数据库可在
https://dev.mysql.com/doc/index-other.html获得
。)
帐户名的用户和主机部分分别为诸如
CREATE
USER
和之类的
语句引用
GRANT
,而要指定用于防火墙组件的帐户,请将其命名为单引号字符串
'fwuser@localhost'
。
将帐户命名为防火墙组件的单引号字符串的约定意味着您不能使用
@
在用户名
中包含嵌入
字符的
帐户
。
使用管理MySQL帐户执行以下过程中的步骤,但指定由防火墙注册的帐户执行的帐户除外。
默认数据库应该是
sakila
使用注册帐户执行的语句。
如有必要,创建要保护的帐户(选择适当的密码)并为其授予
sakila
数据库
权限
:
mysql>CREATE USER 'fwuser'@'localhost' IDENTIFIED BY 'fWp@3sw0rd';
mysql>GRANT ALL ON sakila.* TO 'fwuser'@'localhost';
使用
sp_set_firewall_mode()
存储过程向防火墙注册帐户并将其置于记录模式(如果过程位于数据库以外
mysql
,请相应地调整语句):
MySQL的> CALL mysql.sp_set_firewall_mode('fwuser@localhost', 'RECORDING');
在执行过程中,存储过程调用防火墙用户定义的函数,这些函数可能产生自己的输出。
使用已注册的帐户,连接到服务器,然后执行一些合法的语句:
mysql>SELECT first_name, last_name FROM customer WHERE customer_id = 1;
mysql>UPDATE rental SET return_date = NOW() WHERE rental_id = 1;
mysql>SELECT get_customer_balance(1, NOW());
防火墙将语句转换为摘要形式,并将其记录在帐户白名单中。
在帐户以记录模式执行语句之前,其白名单为空,这相当于 “ 拒绝全部。 “ 如果切换到保护模式,将有效禁止该帐户执行语句。
此时,用户和白名单信息被缓存并可在防火墙中看到
INFORMATION_SCHEMA
表中
:
MySQL的>SELECT MODE FROM INFORMATION_SCHEMA.MYSQL_FIREWALL_USERS
WHERE USERHOST = 'fwuser@localhost';
+ ----------- + | MODE | + ----------- + | 记录| + ----------- + MySQL的>SELECT RULE FROM INFORMATION_SCHEMA.MYSQL_FIREWALL_WHITELIST
WHERE USERHOST = 'fwuser@localhost';
+ ------------------------------------------------- --------------------------- + | 规则| + ------------------------------------------------- --------------------------- + | SELECT`first_name`,`last_name` FROM`customer` WHERE`customer_id` =?| | SELECT`get_customer_balance`(?,NOW())| | 更新`rental` SET`report_date` = NOW()WHERE` rental_id` =?| | SELECT @@`version_comment` LIMIT?| + ------------------------------------------------- --------------------------- +
该
@@version_comment
规则来自
mysql
自动发送的语句
客户端作为注册用户连接到服务器时
。
在与应用程序使用匹配的条件下训练防火墙非常重要。 例如,给定的MySQL连接器可能会在连接开始时向服务器发送语句,以确定服务器特性和功能。 如果通常通过该连接器使用应用程序,那么也要以这种方式训练防火墙。 这使得这些初始语句成为与应用程序关联的帐户的白名单的一部分。
使用存储过程将注册用户切换到保护模式:
MySQL的> CALL mysql.sp_set_firewall_mode('fwuser@localhost', 'PROTECTING');
将帐户切换出
RECORDING
模式会将其防火墙缓存数据同步到底层
mysql
系统数据库表以进行持久存储。
如果不为正在记录的用户切换模式,则缓存的白名单数据不会写入系统表,并且在重新启动服务器时将丢失。
使用已注册的帐户,执行一些可接受和不可接受的声明。 防火墙将每个防火墙与帐户白名单进行匹配,并接受或拒绝它。
此语句与训练语句不同,但会产生与其中一个相同的规范化语句,因此防火墙接受它:
MySQL的> SELECT first_name, last_name FROM customer WHERE customer_id = '48';
+ ------------ + ----------- +
| first_name | last_name |
+ ------------ + ----------- +
| ANN | EVANS |
+ ------------ + ----------- +
这些语句与白名单中的任何内容都不匹配,每个语句都会导致错误:
MySQL的>SELECT first_name, last_name FROM customer WHERE customer_id = 1 OR TRUE;
错误1045(28000):语句被防火墙阻止 MySQL的>SHOW TABLES LIKE 'customer%';
错误1045(28000):语句被防火墙阻止 MySQL的>TRUNCATE TABLE mysql.slow_log;
错误1045(28000):语句被防火墙阻止
如果
mysql_firewall_trace
启用
了
系统变量
,防火墙还会将拒绝的语句写入错误日志
。
例如:
[注意]插件MYSQL_FIREWALL报告: '为fwuser @ localhost拒绝访问。原因:白名单中没有匹配项。 声明:TRUNCATE TABLE`mysql`。`slow_log`'
您可以在努力中使用这些日志消息来识别攻击源。
您可以将不匹配的语句记录为可疑语句而不拒绝访问。 为此,请将帐户置于入侵检测模式:
MySQL的> CALL mysql.sp_set_firewall_mode('fwuser@localhost', 'DETECTING');
使用已注册的帐户连接到服务器,然后执行与白名单不匹配的语句:
MySQL的> SHOW TABLES LIKE 'customer%';
+ ------------------------------ +
| Tables_in_sakila(客户%)|
+ ------------------------------ +
| 客户|
| customer_list |
+ ------------------------------ +
在检测模式下,防火墙允许执行非匹配语句,但会将消息写入错误日志:
[注意]插件MYSQL_FIREWALL报告: '来自'fwuser @ localhost'的可疑声明。原因:白名单中没有匹配项。 声明:显示表格如何?“
检测模式将消息写为Notes,这是信息消息。
要确保此类消息出现在错误日志中并且不被丢弃,请确保将
log_error_verbosity
系统变量设置为值3。
要评估防火墙活动,请检查其状态变量:
MySQL的> SHOW GLOBAL STATUS LIKE 'Firewall%';
+ ---------------------------- + ------- +
| Variable_name | 价值|
+ ---------------------------- + ------- +
| Firewall_access_denied | 3 |
| Firewall_access_granted | 4 |
| Firewall_access_suspicious | 1 |
| Firewall_cached_entries | 4 |
+ ---------------------------- + ------- +
这些变量分别表示拒绝,接受,记录为可疑的语句数,并分别添加到缓存中。
该
Firewall_access_granted
数是4,因为中
@@version_comment
通过发送声明
的mysql
你们每个人都用它来连接为注册用户三个时间客户端,再加上
SHOW TABLES
这是不会被阻止在声明
DETECTING
模式。
如果需要对帐户进行额外培训,请再次将其切换到记录模式,然后在执行要添加到白名单的语句后返回保护模式。
以下讨论作为MySQL Enterprise Firewall组件的参考:
MySQL Enterprise Firewall维护帐户和白名单信息。
它使用
INFORMATION_SCHEMA
表来提供缓存数据和表中的表
mysql
系统数据库中的
以持久的形式存储这些数据。
启用后,防火墙将其操作决策基于缓存数据。
INFORMATION_SCHEMA
任何人都可以访问
这些
表格。
该
mysql
只有具有该数据库权限的用户才能访问
表。
在
INFORMATION_SCHEMA.MYSQL_FIREWALL_USERS
与
mysql.firewall_users
表列表中注册的防火墙账户和他们的操作模式。
表格包含以下列:
USERHOST
在防火墙中注册的帐户。
每个帐户都具有格式,
并表示服务器验证的实际用户名和主机名。
注册用户时不应使用模式和网络掩码。
user_name
@host_name
MODE
帐户的当前防火墙操作模式。
允许的模式值
OFF
,
DETECTING
,
PROTECTING
,
RECORDING
,和
RESET
。
有关其含义的详细信息,请参阅的描述
sp_set_firewall_mode()
在
第6.4.7.4.2,“MySQL企业防火墙程序和功能”
。
在
INFORMATION_SCHEMA.MYSQL_FIREWALL_WHITELIST
与
mysql.firewall_whitelist
表列表中注册的防火墙账户和他们的白名单。
表格包含以下列:
USERHOST
在防火墙中注册的帐户。 格式与用户帐户表的格式相同。
RULE
标准化语句,指示帐户可接受的语句模式。 帐户白名单是其规则的结合。
ID
一个整数列,它是表的主键。 此列已添加到MySQL 8.0.12中。
MySQL Enterprise Firewall具有执行任务的存储过程,例如向防火墙注册MySQL帐户,建立其操作模式,以及管理缓存和底层系统表之间的防火墙数据传输。 它还有一组用户定义的函数(UDF),为较低级别的任务提供SQL级API,例如将缓存与底层系统表同步。
在正常操作下,存储过程实现用户界面。 UDF由存储过程调用,而不是由用户直接调用。
要在默认数据库不是包含该过程的数据库时调用存储过程,请使用数据库名称限定过程名称。 例如:
CALL mysql.sp_set_firewall_mode(user
,mode
);
以下列表描述了每个防火墙存储过程和UDF:
sp_reload_firewall_rules(
user
)
此存储过程使用防火墙UDF重置已注册的帐户,并从存储在
mysql.firewall_whitelist
表中
的规则重新加载内存中的规则
。
此过程可控制各个帐户的防火墙操作。
该
user
参数名受影响的帐户,作为一个字符串
格式。
user_name
@host_name
例:
CALL mysql.sp_reload_firewall_rules('fwuser @ localhost');
此过程将帐户模式设置为
RESET
,清除帐户白名单并将其模式设置为
OFF
。
如果帐户模式不在
呼叫
OFF
之前,
sp_reload_firewall_rules()
请
sp_set_firewall_mode()
在重新加载规则后用于恢复其先前的模式。
例如,如果帐户处于
PROTECTING
模式,则在调用后不再为真
sp_reload_firewall_rules()
,您必须
PROTECTING
再次
将其设置为
显式。
sp_set_firewall_mode(
user
,
mode
)
此存储过程向防火墙注册MySQL帐户并建立其操作模式。
该过程还根据需要调用防火墙UDF,以在缓存和底层系统表之间传输防火墙数据。
即使
mysql_firewall_mode
系统变量是
OFF
,
也可以调用此过程
,尽管在禁用防火墙时设置帐户模式没有操作效果。
该
user
参数名受影响的帐户,作为一个字符串
格式。
user_name
@host_name
这
mode
是用户的操作模式,作为字符串。
允许使用这些模式值:
OFF
:禁用该帐户的防火墙。
DETECTING
:入侵检测模式:将可疑(不匹配)语句写入错误日志但不拒绝访问。
PROTECTING
:通过将传入的语句与帐户白名单进行匹配来保护帐户。
RECORDING
:培训模式:记录帐户可接受的报表。
记录不会立即失败并出现语法错误的传入语句将成为帐户白名单规则的一部分。
RESET
:清除帐户白名单并将帐户模式设置为
OFF
。
将帐户模式切换到任何模式,但
RECORDING
将防火墙缓存数据同步到底层
mysql
系统数据库表以进行持久存储。
切换模式
OFF
以
RECORDING
将白名单从
mysql.firewall_whitelist
表
重新加载
到缓存中。
如果帐户具有空白名单,
PROTECTING
请将
其模式设置为
生成在结果集中返回的错误消息,但不会出现SQL错误:
MySQL的> CALL mysql.sp_set_firewall_mode('a@b','PROTECTING');
+ ------------------------------------------------- --------------------- +
| set_firewall_mode(arg_userhost,arg_mode)|
+ ------------------------------------------------- --------------------- +
| 错误:@ b请求的保护模式,但白名单为空。|
+ ------------------------------------------------- --------------------- +
1排(0.02秒)
查询OK,0行受影响(0.02秒)
mysql_firewall_flush_status()
此UDF将多个防火墙状态变量重置为0:
Firewall_access_denied Firewall_access_granted Firewall_access_suspicious
例:
SELECT mysql_firewall_flush_status();
normalize_statement(
stmt
)
此UDF将SQL语句规范化为用于白名单规则的摘要形式。
例:
SELECT normalize_statement('SELECT * FROM t1 WHERE c1> 2');
read_firewall_users(
user
,
mode
)
此聚合UDF通过
SELECT
表上的语句
更新防火墙用户缓存
mysql.firewall_users
。
例:
SELECT read_firewall_users('fwuser @ localhost','RECORDING') 来自mysql.firewall_users;
read_firewall_whitelist(
user
,
rule
)
此聚合UDF通过
SELECT
表上的
语句更新记录的语句高速缓存
mysql.firewall_whitelist
。
例:
SELECT read_firewall_whitelist('fwuser @ localhost','RECORDING') 来自mysql.firewall_whitelist;
set_firewall_mode(
user
,
mode
)
此UDF管理用户缓存并建立用户操作模式。
例:
SELECT set_firewall_mode('fwuser @ localhost','RECORDING');
MySQL Enterprise Firewall支持以下系统变量。 使用它们配置防火墙操作。 除非安装了防火墙,否则这些变量不可用(请参见 第6.4.7.2节“安装或卸载MySQL Enterprise Firewall” )。
属性 | 值 |
---|---|
命令行格式 | --mysql-firewall-mode[={OFF|ON}] |
介绍 | 8.0.11 |
系统变量 | mysql_firewall_mode |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 布尔 |
默认值 | ON |
是启用MySQL企业防火墙(默认)还是禁用。
属性 | 值 |
---|---|
命令行格式 | --mysql-firewall-trace[={OFF|ON}] |
介绍 | 8.0.11 |
系统变量 | mysql_firewall_trace |
范围 | 全球 |
动态 | 是 |
SET_VAR
提示适用
|
没有 |
类型 | 布尔 |
默认值 | OFF |
是启用还是禁用MySQL Enterprise Firewall跟踪(默认设置)。
当
mysql_firewall_trace
启用时,为
PROTECTING
模式,防火墙写入拒绝语句错误日志。
MySQL Enterprise Firewall支持以下状态变量。
使用它们获取有关防火墙操作状态的信息。
除非安装了防火墙,否则这些变量不可用(请参见
第6.4.7.2节“安装或卸载MySQL Enterprise Firewall”
)。
每当
MYSQL_FIREWALL
安装插件或启动服务器
时,防火墙状态变量都将设置为0
。
其中许多由
mysql_firewall_flush_status()
UDF
重置为零
(请参见
第6.4.7.4.2节“MySQL企业防火墙过程和函数”
)。
MySQL Enterprise Firewall拒绝的语句数。
MySQL Enterprise Firewall接受的语句数。
MySQL Enterprise Firewall记录的语句数对于处于
DETECTING
模式的
用户可疑
。
MySQL Enterprise Firewall记录的语句数,包括重复项。
MySQL企业数据屏蔽和去标识是MySQL企业版(一种商业产品)中包含的扩展。 要了解有关商业产品的更多信息, 请访问https://www.mysql.com/products/ 。
从MySQL 8.0.13开始,MySQL Enterprise Edition提供数据屏蔽和去识别功能:
转换现有数据以屏蔽它并删除识别特征,例如更改信用卡号码的所有数字,但最后四个更改为
'X'
字符
字符。
生成随机数据,例如电子邮件地址和支付卡号。
应用程序使用这些功能的方式取决于数据的使用目的以及访问数据的人员:
使用敏感数据的应用程序可以通过执行数据屏蔽并允许使用部分屏蔽数据进行客户端识别来保护它。 示例:呼叫中心可能会要求客户提供其最后四个社会安全号码。
需要格式正确的数据但不一定是原始数据的应用程序可以合成样本数据。 示例:正在测试数据验证程序但无法访问原始数据的应用程序开发人员可能会使用相同的格式合成随机数据。
例1:
医学研究机构可以保存包含个人和医疗数据混合的患者数据。 这可能包括遗传序列(长串),以JSON格式存储的测试结果以及其他数据类型。 虽然数据可能主要由自动分析软件使用,但仍然可以访问基因组数据或特定患者的测试结果。 在这种情况下,应使用数据屏蔽来提供此信息,而不是个人身份信息。
例2:
信用卡处理器公司使用敏感数据提供一组服务,例如:
每秒处理大量金融交易。
存储大量与交易相关的数据。
保护与交易相关的数据,严格要求个人数据。
使用可逆或部分屏蔽数据处理客户对交易的投诉。
典型的交易可能包括许多类型的敏感信息,包括:
信用卡号。
交易类型和金额。
商家类型。
交易密码(确认交易合法性)。
配备GPS的终端的地理位置(用于欺诈检测)。
然后,这些类型的信息可以在银行或其他发卡金融机构内与客户个人数据相结合,例如:
完整的客户名称(个人或公司)。
地址。
出生日期。
社会安全号码。
电子邮件地址。
电话号码。
卡处理公司和金融机构内的各种员工角色需要访问该数据。 其中一些角色可能只需要访问屏蔽数据。 其他角色可能需要根据具体情况访问原始数据,该数据记录在审计日志中。
屏蔽和去识别是法规遵从的核心,因此MySQL Enterprise Data Masking和De-Identification可以帮助应用程序开发人员满足隐私要求:
PCI - DSS:支付卡数据。
HIPAA:健康数据隐私,健康信息技术促进经济和临床健康法案(HITECH法案)。
欧盟通用数据保护指令(GDPR):保护个人数据。
数据保护法(英国):保护个人数据。
Sarbanes Oxley,GLBA,美国爱国者法案,1998年身份盗窃和假设威慑法案。
FERPA - 学生数据,NASD,CA SB1386和AB 1950,国家数据保护法,巴塞尔协议II。
以下部分描述了MySQL Enterprise Data Masking和De-Identification的组件,讨论了如何安装和使用它,并提供了其组件的参考信息。
MySQL Enterprise Data Masking和De-Identification基于一个实现这些组件的插件库:
一个名为的服务器端插件
data_masking
。
一组用户定义函数(UDF)提供用于执行屏蔽和去标识操作的SQL级API。
其中一些功能需要
SUPER
特权。
本节介绍如何安装或卸载MySQL Enterprise Data Masking和De-Identification,它是作为包含插件和用户定义函数(UDF)的插件库文件实现的。 有关安装或卸载插件和UDF的一般信息,请参见 第5.6.1节“安装和卸载插件” 和 第5.7.1节“安装和卸载用户定义的函数” 。
要使服务器可以使用,插件库文件必须位于MySQL插件目录(
plugin_dir
系统变量
指定的目录
)中。
如有必要,通过设置
plugin_dir
服务器启动时
的值来配置插件目录位置
。
插件库文件基本名称是
data_masking
。
文件名后缀因平台
.so
而异
(例如,
对于Unix和类Unix系统,
.dll
对于Windows)。
要安装MySQL Enterprise Data Masking和De-Identification插件和UDF,请使用
INSTALL PLUGIN
和
CREATE FUNCTION
语句(调整
.so
根据需要
平台
后缀):
INSTALL PLUGIN data_masking SONAME'data_masking.so'; 创建功能gen_blacklist返回字符串 SONAME'data_masking.so'; CREATE FUNCTION gen_dictionary返回STRING SONAME'data_masking.so'; 创建功能gen_dictionary_drop返回STRING SONAME'data_masking.so'; CREATE FUNCTION gen_dictionary_load RETURNS STRING SONAME'data_masking.so'; 创建功能gen_range返回INTEGER SONAME'data_masking.so'; 创建功能gen_rnd_email返回STRING SONAME'data_masking.so'; 创建功能gen_rnd_pan返回字符串 SONAME'data_masking.so'; 创建功能gen_rnd_ssn返回字符串 SONAME'data_masking.so'; 创建功能gen_rnd_us_phone返回字符串 SONAME'data_masking.so'; CREATE FUNCTION mask_inner RETURNS STRING SONAME'data_masking.so'; CREATE FUNCTION mask_outer RETURNS STRING SONAME'data_masking.so'; CREATE FUNCTION mask_pan RETURNS STRING SONAME'data_masking.so'; 创建功能mask_pan_relaxed RETURNS STRING SONAME'data_masking.so'; 创建功能mask_ssn RETURNS STRING SONAME'data_masking.so';
如果在主复制服务器上使用插件和UDF,请将它们安装在所有从属服务器上,以避免复制问题。
如上所述安装后,插件和UDF将保持安装状态,直到卸载为止。
要删除它们,请使用
UNINSTALL PLUGIN
和
DROP FUNCTION
语句:
UNINSTALL PLUGIN data_masking; DROP FUNCTION gen_blacklist; DROP FUNCTION gen_dictionary; DROP FUNCTION gen_dictionary_drop; DROP FUNCTION gen_dictionary_load; DROP FUNCTION gen_range; DROP FUNCTION gen_rnd_email; DROP FUNCTION gen_rnd_pan; DROP FUNCTION gen_rnd_ssn; DROP FUNCTION gen_rnd_us_phone; DROP FUNCTION mask_inner; DROP FUNCTION mask_outer; DROP FUNCTION mask_pan; DROP FUNCTION mask_pan_relaxed; DROP FUNCTION mask_ssn;
在使用MySQL Enterprise Data Masking和De-Identification之前,请按照 第6.4.8.2节“安装或卸载MySQL Enterprise Data Masking and De-Identification”中 提供的说明进行 安装 。
要在应用程序中使用MySQL Enterprise Data Masking和De-Identification,请调用适合您要执行的操作的函数。 有关详细的功能说明,请参见 第6.4.8.4节“MySQL企业数据屏蔽和取消标识用户定义的函数参考” 。 本节演示如何使用这些功能执行一些代表性任务。 它首先概述了可用的功能,然后是一些如何在现实环境中使用这些功能的示例:
MySQL提供掩盖任意字符串的通用掩码函数,以及掩盖特定类型值的特殊用途掩码函数。
mask_inner()
并且
mask_outer()
是通用函数,它根据字符串中的位置屏蔽任意字符串的部分:
mask_inner()
屏蔽其字符串参数的内部,使末端不被屏蔽。
其他参数指定未屏蔽结束的大小。
MySQL的>SELECT mask_inner('This is a string', 5, 1);
+ -------------------------------------- + | mask_inner('这是一个字符串',5,1)| + -------------------------------------- + | 这个XXXXXXXXXXg | + -------------------------------------- + MySQL的>SELECT mask_inner('This is a string', 1, 5);
+ -------------------------------------- + | mask_inner('这是一个字符串',1,5)| + -------------------------------------- + | TXXXXXXXXXXtring | + -------------------------------------- +
mask_outer()
反过来,屏蔽其字符串参数的末尾,使内部屏蔽。
其他参数指定蒙版末端的大小。
MySQL的>SELECT mask_outer('This is a string', 5, 1);
+ -------------------------------------- + | mask_outer('这是一个字符串',5,1)| + -------------------------------------- + | XXXXX是一个strinX | + -------------------------------------- + MySQL的>SELECT mask_outer('This is a string', 1, 5);
+ -------------------------------------- + | mask_outer('这是一个字符串',1,5)| + -------------------------------------- + | Xhis是一个sXXXXX | + -------------------------------------- +
默认情况下,
mask_inner()
与
mask_outer()
使用
'X'
作为掩蔽的性格,但允许一个可选的屏蔽字符参数:
MySQL的>SELECT mask_inner('This is a string', 5, 1, '*');
+ ------------------------------------------- + | mask_inner('这是一个字符串',5,1,'*')| + ------------------------------------------- + | 这个********** g | + ------------------------------------------- + MySQL的>SELECT mask_outer('This is a string', 5, 1, '#');
+ ------------------------------------------- + | mask_outer('这是一个字符串',5,1,'#')| + ------------------------------------------- + | #####是一个strin#| + ------------------------------------------- +
其他掩码函数需要一个表示特定类型值的字符串参数,并将其屏蔽以删除识别特征。
这里的示例使用返回适当类型值的随机值生成函数来提供函数参数。 有关生成函数的更多信息,请参阅 生成具有特定特征的随机数据 。
支付卡主帐号掩盖。 屏蔽功能提供严格和轻松的主帐号屏蔽。
mask_pan()
除了数字的最后四位数字外,其他所有数字:
MySQL的> SELECT mask_pan(gen_rnd_pan());
+ ------------------------- +
| mask_pan(gen_rnd_pan())|
+ ------------------------- +
| XXXXXXXXXXXX2461 |
+ ------------------------- +
mask_pan_relaxed()
类似但不掩盖表示支付卡发行人未屏蔽的前六位数字:
MySQL的> SELECT mask_pan_relaxed(gen_rnd_pan());
+ --------------------------------- +
| mask_pan_relaxed(gen_rnd_pan())|
+ --------------------------------- +
| 770630XXXXXX0807 |
+ --------------------------------- +
美国社会安全号码掩盖。
mask_ssn()
除了数字的最后四位数字外,其他所有数字:
MySQL的> SELECT mask_ssn(gen_rnd_ssn());
+ ------------------------- +
| mask_ssn(gen_rnd_ssn())|
+ ------------------------- +
| XXX-XX-1723 |
+ ------------------------- +
几个函数生成随机值。 这些值可用于测试,模拟等。
gen_range()
返回从给定范围中选择的随机整数:
MySQL的> SELECT gen_range(1, 10);
+ ------------------ +
| gen_range(1,10)|
+ ------------------ +
| 6 |
+ ------------------ +
gen_rnd_email()
返回
example.com
域中
的随机电子邮件地址
:
MySQL的> SELECT gen_rnd_email();
+ --------------------------- +
| gen_rnd_email()|
+ --------------------------- +
| ayxnq.xmkpvvy@example.com |
+ --------------------------- +
gen_rnd_pan()
返回随机支付卡主帐号:
MySQL的> SELECT gen_rnd_pan();
(
gen_rnd_pan()
函数结果未显示,因为其返回值应仅用于测试目的,而不是用于发布。不能保证该数字不会分配给合法的支付帐户。)
gen_rnd_ssn()
返回一个随机的美国社会安全号码,其第一和第二部分各自从不用于合法数字的范围中选择:
MySQL的> SELECT gen_rnd_ssn();
+ --------------- +
| gen_rnd_ssn()|
+ --------------- +
| 912-45-1615 |
+ --------------- +
gen_rnd_us_phone()
返回555区号中的随机美国电话号码,不用于合法号码:
MySQL的> SELECT gen_rnd_us_phone();
+ -------------------- +
| gen_rnd_us_phone()|
+ -------------------- +
| 1-555-747-5627 |
+ -------------------- +
MySQL Enterprise Data Masking和De-Identification使字典可用作随机值的来源。 要使用字典,必须首先从文件加载并给出名称。 每个加载的字典都成为字典注册表的一部分。 然后可以从已注册的词典中选择项目,并将其用作随机值或替换其他值。
有效的字典文件具有以下特征:
文件内容为纯文本,每行一个术语。
空行被忽略。
该文件必须至少包含一个术语。
假设一个名为的文件
de_cities.txt
在德国包含这些城市名称:
柏林 慕尼黑 不来梅
还假设一个名为的文件
us_cities.txt
在美国包含这些城市名称:
芝加哥 休斯顿 凤凰 埃尔帕索 底特律
假设
secure_file_priv
系统变量设置为
/usr/local/mysql/mysql-files
。
在这种情况下,将字典文件复制到该目录,以便MySQL服务器可以访问它们。
然后使用
gen_dictionary_load()
将字典加载到字典注册表中并为其指定名称:
MySQL的>SELECT gen_dictionary_load('/usr/local/mysql/mysql-files/de_cities.txt', 'DE_Cities');
+ ------------------------------------------------- ------------------------------- + | gen_dictionary_load('/ usr / local / mysql / mysql-files / de_cities.txt','DE_Cities')| + ------------------------------------------------- ------------------------------- + | 字典加载成功| + ------------------------------------------------- ------------------------------- + MySQL的>SELECT gen_dictionary_load('/usr/local/mysql/mysql-files/us_cities.txt', 'US_Cities');
+ ------------------------------------------------- ------------------------------- + | gen_dictionary_load('/ usr / local / mysql / mysql-files / us_cities.txt','US_Cities')| + ------------------------------------------------- ------------------------------- + | 字典加载成功| + ------------------------------------------------- ------------------------------- +
要从字典中选择随机项,请使用
gen_dictionary()
:
MySQL的>SELECT gen_dictionary('DE_Cities');
+ ----------------------------- + | gen_dictionary('DE_Cities')| + ----------------------------- + | 柏林| + ----------------------------- + MySQL的>SELECT gen_dictionary('US_Cities');
+ ----------------------------- + | gen_dictionary('US_Cities')| + ----------------------------- + | 凤凰城| + ----------------------------- +
要从多个词典中选择一个随机词,请随机选择其中一个词典,然后从中选择一个词:
MySQL的>SELECT gen_dictionary(ELT(gen_range(1,2), 'DE_Cities', 'US_Cities'));
+ ------------------------------------------------- -------------- + | gen_dictionary(ELT(gen_range(1,2),'DE_Cities','US_Cities'))| + ------------------------------------------------- -------------- + | 底特律| + ------------------------------------------------- -------------- + MySQL的>SELECT gen_dictionary(ELT(gen_range(1,2), 'DE_Cities', 'US_Cities'));
+ ------------------------------------------------- -------------- + | gen_dictionary(ELT(gen_range(1,2),'DE_Cities','US_Cities'))| + ------------------------------------------------- -------------- + | 不来梅| + ------------------------------------------------- -------------- +
该
gen_blacklist()
函数使得来自一个字典的术语可以被来自另一个字典的术语替换,该术语通过替换来实现掩蔽。
它的参数是要替换的术语,术语出现的字典,以及从中选择替换的字典。
例如,要将美国城市替换为德国城市,反之亦然,请使用
gen_blacklist()
如下:
MySQL的>SELECT gen_blacklist('Munich', 'DE_Cities', 'US_Cities');
+ ------------------------------------------------- - + | gen_blacklist('慕尼黑','DE_Cities','US_Cities')| + ------------------------------------------------- - + | 休斯顿| + ------------------------------------------------- - + MySQL的>SELECT gen_blacklist('El Paso', 'US_Cities', 'DE_Cities');
+ ------------------------------------------------- --- + | gen_blacklist('El Paso','US_Cities','DE_Cities')| + ------------------------------------------------- --- + | 不来梅| + ------------------------------------------------- --- +
如果要替换的术语不在第一个字典中,
gen_blacklist()
则将其保持不变:
MySQL的> SELECT gen_blacklist('Moscow', 'DE_Cities', 'US_Cities');
+ ------------------------------------------------- - +
| gen_blacklist('莫斯科','DE_Cities','US_Cities')|
+ ------------------------------------------------- - +
| 莫斯科|
+ ------------------------------------------------- - +
在客户服务呼叫中心,一种常见的身份验证技术是要求客户提供他们的最后四个社会安全号码(SSN)数字。
例如,客户可能会说她的名字是乔安娜邦德,而她的最后四个SSN数字是
0007
。
假设
customer
包含客户记录
的
表具有以下列:
id
:客户ID号。
first_name
:客户名。
last_name
:客户姓氏。
ssn
:客户社会安全号码。
客户服务代表用于检查客户SSN的应用程序可能会执行如下查询:
mysql>SELECT id, ssn
mysql>FROM customer
mysql>WHERE first_name = 'Joanna' AND last_name = 'Bond';
+ ----- + ------------- + | id | ssn | + ----- + ------------- + | 786 | 906-39-0007 | + ----- + ------------- +
但是,这会将SSN暴露给客户服务代表,客户服务代表除了最后四位数外无需查看任何内容。 相反,应用程序可以使用此查询仅显示屏蔽的SSN:
mysql>SELECT id, mask_ssn(CONVERT(ssn USING binary))
mysql>FROM customer
mysql>WHERE first_name = 'Joanna' AND last_name = 'Bond';
+ ----- + ------------------------------- + | id | mask_ssn(CONVERT(ssn使用二进制))| + ----- + ------------------------------- + | 786 | XXX-XX-0007 | + ----- + ------------------------------- +
现在,代表只看到了必要的内容,并保留了客户隐私。
为什么
CONVERT()
函数用于参数
mask_ssn()
?
因为
mask_ssn()
需要长度为11的参数,并且因为UDF将字符串参数视为二进制字符串,每个字符一个字节。
因此,即使
ssn
被定义为
VARCHAR(11)
,如果
ssn
列具有多字节字符集,则在传递给UDF时它似乎长于11个字节,并且发生错误。
将值转换为二进制字符串可确保UDF看到长度为11的参数。
当字符串参数没有单字节字符集时,其他数据屏蔽函数可能需要类似的技术。
如果表中的掩码数据用于多个查询,则定义生成掩码数据的视图可能很方便。 这样,应用程序可以从视图中进行选择,而无需在单个查询中执行屏蔽。
例如,
customer
可以像下面这样定义上一节中表格
的掩蔽视图
:
创建视图masked_customer AS SELECT id,first_name,last_name,mask_ssn(CONVERT(ssn USING binary))AS ssn 来自客户;
然后查询客户的查询变得更简单但仍返回屏蔽数据:
mysql>SELECT id, ssn
mysql>FROM masked_customer
mysql>WHERE first_name = 'Joanna' AND last_name = 'Bond';
+ ----- + ------------- + | id | ssn | + ----- + ------------- + | 786 | XXX-XX-0007 | + ----- + ------------- +
MySQL企业数据屏蔽和去标识插件库包括几个用户定义的函数(UDF),它们可以分为以下类别:
这些UDF将字符串参数视为二进制字符串,这意味着它们隐式区分大小写。
此外,字符串UDF返回值是二进制字符串。
如果字符串返回值应该在不同的字符集中,请转换它。
以下示例显示如何将结果转换
gen_rnd_email()
为
utf8mb4
字符集:
SET @email = CONVERT(gen_rnd_email()USING utf8mb4);
也可能需要转换字符串参数,如 使用屏蔽数据进行客户识别中所示 。
本节中的每个函数对其字符串参数执行屏蔽操作并返回屏蔽结果。
mask_inner(
str
,
margin1
,
margin2
[,
mask_char
])
掩盖字符串的内部部分,保持两端不变,并返回结果。 可以指定可选的屏蔽字符。
参数:
str
:要屏蔽的字符串。
margin1
:非负整数,指定要保持未屏蔽的字符串左端的字符数。
如果值为0,则不会取消屏蔽左端字符。
margin2
:非负整数,指定要保持未屏蔽的字符串右端的字符数。
如果值为0,则不会取消屏蔽右端字符。
mask_char
:(可选)用于屏蔽的单个字符。
默认值为
'X'
if
mask_char
未给出。
由于UDF字符串参数被视为二进制字符串,因此屏蔽字符必须是单字节字符。 尝试使用多字节字符会产生错误。
返回值:
屏蔽的字符串,或者
NULL
如果任一边距是负的。
如果边距值的总和大于参数长度,则不会发生屏蔽,并且参数将保持不变。
例:
MySQL的>SELECT mask_inner('abcdef', 1, 2), mask_inner('abcdef',0, 5);
+ ---------------------------- + -------------------- ------- + | mask_inner('abcdef',1,2)| mask_inner('abcdef',0,5)| + ---------------------------- + -------------------- ------- + | aXXXef | Xbcdef | + ---------------------------- + -------------------- ------- + MySQL的>SELECT mask_inner('abcdef', 1, 2, '*'), mask_inner('abcdef',0, 5, '#');
+ --------------------------------- + --------------- ----------------- + | mask_inner('abcdef',1,2,'*')| mask_inner('abcdef',0,5,'#')| + --------------------------------- + --------------- ----------------- + | a *** ef | #bcdef | + --------------------------------- + --------------- ----------------- +
mask_outer(
str
,
margin1
,
margin2
[,
mask_char
])
掩盖字符串的左端和右端,使内部不显示,并返回结果。 可以指定可选的屏蔽字符。
参数:
str
:要屏蔽的字符串。
margin1
:非负整数,指定要屏蔽的字符串左端的字符数。
如果值为0,则不会屏蔽左端字符。
margin2
:非负整数,指定要屏蔽的字符串右端的字符数。
如果值为0,则不会屏蔽右端字符。
mask_char
:(可选)用于屏蔽的单个字符。
默认值为
'X'
if
mask_char
未给出。
由于UDF字符串参数被视为二进制字符串,因此屏蔽字符必须是单字节字符。 尝试使用多字节字符会产生错误。
返回值:
屏蔽的字符串,或者
NULL
如果任一边距是负的。
如果边距值的总和大于参数长度,则会屏蔽整个参数。
例:
MySQL的>SELECT mask_outer('abcdef', 1, 2), mask_outer('abcdef',0, 5);
+ ---------------------------- + -------------------- ------- + | mask_outer('abcdef',1,2)| mask_outer('abcdef',0,5)| + ---------------------------- + -------------------- ------- + | XbcdXX | aXXXXX | + ---------------------------- + -------------------- ------- + MySQL的>SELECT mask_outer('abcdef', 1, 2, '*'), mask_outer('abcdef',0, 5, '#');
+ --------------------------------- + --------------- ----------------- + | mask_outer('abcdef',1,2,'*')| mask_outer('abcdef',0,5,'#')| + --------------------------------- + --------------- ----------------- + | * bcd ** | ##### | + --------------------------------- + --------------- ----------------- +
屏蔽支付卡主帐号并返回除最后四位数字以外的所有数字替换的数字
'X'
。
参数:
str
:要屏蔽的字符串。
字符串必须是主帐号的合适长度,但不会以其他方式检查。
返回值:
屏蔽的支付号码为字符串。 如果参数短于要求,则返回不变。
例:
MySQL的>SELECT mask_pan(gen_rnd_pan());
+ ------------------------- + | mask_pan(gen_rnd_pan())| + ------------------------- + | XXXXXXXXXXXX9102 | + ------------------------- + MySQL的>SELECT mask_pan(gen_rnd_pan(19));
+ --------------------------- + | mask_pan(gen_rnd_pan(19))| + --------------------------- + | XXXXXXXXXXXXXXX8268 | + --------------------------- + MySQL的>SELECT mask_pan('a*Z');
+ ----------------- + | mask_pan('a * Z')| + ----------------- + | a * Z | + ----------------- +
屏蔽支付卡主帐号并返回除前六个和后四个数字以外的所有数字替换的数字
'X'
。
前六位数字表示支付卡发行者。
参数:
str
:要屏蔽的字符串。
字符串必须是主帐号的合适长度,但不会以其他方式检查。
返回值:
屏蔽的支付号码为字符串。 如果参数短于要求,则返回不变。
例:
MySQL的>SELECT mask_pan_relaxed(gen_rnd_pan());
+ --------------------------------- + | mask_pan_relaxed(gen_rnd_pan())| + --------------------------------- + | 551279XXXXXX3108 | + --------------------------------- + MySQL的>SELECT mask_pan_relaxed(gen_rnd_pan(19));
+ ----------------------------------- + | mask_pan_relaxed(gen_rnd_pan(19))| + ----------------------------------- + | 462634XXXXXXXXX6739 | + ----------------------------------- + MySQL的>SELECT mask_pan_relaxed('a*Z');
+ ------------------------- + | mask_pan_relaxed('a * Z')| + ------------------------- + | a * Z | + ------------------------- +
屏蔽美国社会安全号码并返回除最后四位数之外的所有号码
'X'
。
参数:
str
:要屏蔽的字符串。
该字符串长度必须为11个字符,但不会以其他方式检查。
返回值:
被屏蔽的社会安全号码作为字符串,或者
NULL
如果参数不是正确的长度。
例:
MySQL的>SELECT mask_ssn('909-63-6922'), mask_ssn('abcdefghijk');
+ ------------------------- + ----------------------- - + | mask_ssn('909-63-6922')| mask_ssn('abcdefghijk')| + ------------------------- + ----------------------- - + | XXX-XX-6922 | XXX-XX-hijk | + ------------------------- + ----------------------- - + MySQL的>SELECT mask_ssn('909');
+ ----------------- + | mask_ssn('909')| + ----------------- + | NULL | + ----------------- +
本节中的函数为不同类型的数据生成随机值。
如果可能,生成的值具有为演示或测试值保留的特性,以避免将它们误认为是合法数据。
例如,
gen_rnd_us_phone()
返回使用555区号的美国电话号码,该号码未分配给实际使用中的电话号码。
各个功能描述描述了该原则的任何例外。
生成从指定范围中选择的随机数。
参数:
lower
:一个整数,指定范围的下边界。
upper
:一个整数,指定范围的上边界,该边界不得小于下边界。
返回值:
一个随机整数,范围从
lower
to
upper
,包括,或者
NULL
如果
upper
参数小于
lower
。
例:
MySQL的>SELECT gen_range(100, 200), gen_range(-1000, -800);
+ --------------------- + ------------------------ + | gen_range(100,200)| gen_range(-1000,-800)| + --------------------- + ------------------------ + | 177 | -917 | + --------------------- + ------------------------ + MySQL的>SELECT gen_range(1, 0);
+ ----------------- + | gen_range(1,0)| + ----------------- + | NULL | + ----------------- +
在
example.com
域中
生成随机电子邮件地址
。
参数:
没有。
返回值:
随机电子邮件地址作为字符串。
例:
MySQL的> SELECT gen_rnd_email();
+ --------------------------- +
| gen_rnd_email()|
+ --------------------------- +
| ijocv.mwvhhuf@example.com |
+ --------------------------- +
生成随机支付卡主帐号。 该数字通过Luhn检查(对校验位执行校验和验证的算法)。
返回的值
gen_rnd_pan()
应仅用于测试目的,不适合发布。
无法保证给定的退货值未分配给合法的付款帐户。
如果有必要发布
gen_rnd_pan()
结果,请考虑使用
mask_pan()
或
屏蔽它
mask_pan_relaxed()
。
参数:
size
:(可选)一个整数,指定结果的大小。
如果
size
未给出,
则默认值为16
。
如果给定,则
size
必须是12到19之间的整数。
返回值:
随机支付号码作为字符串,或者
NULL
如果
size
给出超出允许范围
的
参数。
例:
MySQL的>SELECT mask_pan(gen_rnd_pan());
+ ------------------------- + | mask_pan(gen_rnd_pan())| + ------------------------- + | XXXXXXXXXXXX5805 | + ------------------------- + MySQL的>SELECT mask_pan(gen_rnd_pan(19));
+ --------------------------- + | mask_pan(gen_rnd_pan(19))| + --------------------------- + | XXXXXXXXXXXXXXX5067 | + --------------------------- + MySQL的>SELECT mask_pan_relaxed(gen_rnd_pan());
+ --------------------------------- + | mask_pan_relaxed(gen_rnd_pan())| + --------------------------------- + | 398403XXXXXX9547 | + --------------------------------- + MySQL的>SELECT mask_pan_relaxed(gen_rnd_pan(19));
+ ----------------------------------- + | mask_pan_relaxed(gen_rnd_pan(19))| + ----------------------------------- + | 578416XXXXXXXXX6509 | + ----------------------------------- + MySQL的>SELECT gen_rnd_pan(11), gen_rnd_pan(20);
+ ----------------- + ----------------- + | gen_rnd_pan(11)| gen_rnd_pan(20)| + ----------------- + ----------------- + | NULL | NULL | + ----------------- + ----------------- +
以
格式
生成随机的美国社会安全号码
。
该
部分大于900和
AAA
-BB
-CCCC
AAA
BB
部分小于70,这些特征不用于合法的社会安全号码。
参数:
没有。
返回值:
随机社会安全号码作为字符串。
例:
MySQL的> SELECT gen_rnd_ssn();
+ --------------- +
| gen_rnd_ssn()|
+ --------------- +
| 951-26-0058 |
+ --------------- +
以
格式
生成随机的美国电话号码
。
555区号不用于合法的电话号码。
1-555-
AAA
-BBBB
参数:
没有。
返回值:
一个随机的美国电话号码作为字符串。
例:
MySQL的> SELECT gen_rnd_us_phone();
+ -------------------- +
| gen_rnd_us_phone()|
+ -------------------- +
| 1-555-682-5423 |
+ -------------------- +
本节中的函数处理术语的字典,并基于它们执行生成和屏蔽操作。
其中一些功能需要
SUPER
特权。
加载字典时,它将成为字典注册表的一部分,并为其他字典功能分配一个名称。 字典从纯文本文件加载,每行包含一个术语。 空行被忽略。 要有效,字典文件必须至少包含一个非空行。
gen_blacklist(
str
,
dictionary_name
,
replacement_dictionary_name
)
用一个来自第二个字典的术语替换一个字典中存在的术语并返回替换术语。 这通过替换掩盖了原始术语。
参数:
str
:一个字符串,指示要替换的术语。
dictionary_name
:一个字符串,用于命名包含要替换的术语的字典。
replacement_dictionary_name
:一个字符串,用于命名要从中选择替换术语的字典。
返回值:
随机选择的字符串,
replacement_dictionary_name
作为替换
字符串
str
,或者
str
如果它没有出现
dictionary_name
,或者
NULL
字典名称不在字典注册表中。
如果要替换的术语出现在两个词典中,则返回值可能是相同的术语。
例:
MySQL的> SELECT gen_blacklist('Berlin', 'DE_Cities', 'US_Cities');
+ ------------------------------------------------- - +
| gen_blacklist('柏林','DE_Cities','US_Cities')|
+ ------------------------------------------------- - +
| 凤凰城|
+ ------------------------------------------------- - +
gen_dictionary(
dictionary_name
)
从字典中返回一个随机项。
参数:
dictionary_name
:一个字符串,用于命名从中选择术语的字典。
返回值:
从字典中作为字符串的随机术语,或者
NULL
字典名称不在字典注册表中。
例:
MySQL的>SELECT gen_dictionary('mydict');
+ -------------------------- + | gen_dictionary('mydict')| + -------------------------- + | 我的用语| + -------------------------- + MySQL的>SELECT gen_dictionary('no-such-dict');
+ -------------------------------- + | gen_dictionary('no-such-dict')| + -------------------------------- + | NULL | + -------------------------------- +
gen_dictionary_drop(
dictionary_name
)
从字典注册表中删除字典。
此功能需要该
SUPER
权限。
参数:
dictionary_name
:一个字符串,用于命名要从字典注册表中删除的字典。
返回值:
一个字符串,指示放置操作是否成功。
Dictionary removed
表示成功。
Dictionary removal error
表示失败。
例:
MySQL的>SELECT gen_dictionary_drop('mydict');
+ ------------------------------- + | gen_dictionary_drop('mydict')| + ------------------------------- + | 删除字典| + ------------------------------- + MySQL的>SELECT gen_dictionary_drop('no-such-dict');
+ ------------------------------- + | gen_dictionary_drop('no-such-dict')| + ------------------------------- + | 字典删除错误| + ------------------------------- +
gen_dictionary_load(
dictionary_path
,
dictionary_name
)
将文件加载到字典注册表中,并为字典分配一个名称,以便与需要字典名称参数的其他函数一起使用。
此功能需要该
SUPER
权限。
字典不是持久的。 必须为每个服务器启动加载应用程序使用的任何字典。
一旦加载到注册表中,即使基础字典文件发生更改,也会按原样使用字典。
要重新加载字典,首先将其删除
gen_dictionary_drop()
,然后再次加载
gen_dictionary_load()
。
参数:
dictionary_path
:一个字符串,指定字典文件的路径名。
dictionary_name
:为字典提供名称的字符串。
返回值:
一个字符串,指示加载操作是否成功。
Dictionary load success
表示成功。
Dictionary load
error
表示失败。
字典加载失败可能有多种原因,包括:
已加载具有给定名称的字典。
找不到字典文件。
字典文件不包含任何术语。
该
secure_file_priv
系统变量设置和字典文件不位于由变量命名的目录。
例:
MySQL的>SELECT gen_dictionary_load('/usr/local/mysql/mysql-files/mydict','mydict');
+ ------------------------------------------------- -------------------- + | gen_dictionary_load('/ usr / local / mysql / mysql-files / mydict','mydict')| + ------------------------------------------------- -------------------- + | 字典加载成功| + ------------------------------------------------- -------------------- + MySQL的>SELECT gen_dictionary_load('/dev/null','null');
+ ----------------------------------------- + | gen_dictionary_load('/ dev / null','null')| + ----------------------------------------- + | 字典加载错误| + ----------------------------------------- +
如果使用OpenSSL编译,MySQL支持FIPS模式,并且运行时可以使用OpenSSL库和FIPS对象模块。
服务器端的FIPS模式适用于服务器执行的加密操作。 这包括在服务器内运行的复制(主/从和组复制)和X插件。 FIPS模式也适用于客户端连接到服务器的尝试。
以下部分描述了FIPS模式以及如何在MySQL中利用它:
联邦信息处理标准140-2(FIPS 140-2)描述了联邦(美国政府)机构可能需要的用于保护敏感或有价值信息的加密模块的安全标准。 要被视为联邦使用,加密模块必须经过FIPS 140-2认证。 如果用于保护敏感数据的系统缺少适当的FIPS 140-2证书,联邦机构则无法购买。
虽然OpenSSL库本身未针对FIPS进行验证,但OpenSSL等产品可用于FIPS模式。 相反,OpenSSL库与OpenSSL FIPS对象模块一起使用,以使基于OpenSSL的应用程序能够以FIPS模式运行。
有关FIPS及其在OpenSSL中的实现的一般信息,这些引用可能会有所帮助:
FIPS模式对加密操作施加了条件,例如对可接受的加密算法的限制或对更长密钥长度的要求。 对于OpenSSL,确切的FIPS行为取决于OpenSSL版本。 有关详细信息,请参阅“OpenSSL FIPS用户指南”。
要使MySQL支持FIPS模式,必须满足以下系统要求:
在构建时,必须使用OpenSSL编译MySQL。 如果编译使用不同的SSL库,则不能在MySQL中使用FIPS模式。
在运行时,OpenSSL库和OpenSSL FIPS对象模块必须可用作共享(动态链接)对象。 可以构建静态链接的OpenSSL对象,但MySQL不会使用它们。
FIPS模式已经在EL7上测试了MySQL,但可能适用于其他系统。
如果您的平台或操作系统提供OpenSSL FIPS对象模块,则可以使用它。 否则,您可以从源构建OpenSSL库和FIPS对象模块。 使用“OpenSSL FIPS用户指南”中的说明(请参阅 FIPS概述 )。
MySQL可以在服务器端和客户端控制FIPS模式:
所述
ssl_fips_mode
系统变量控制是否将服务器在FIPS模式操作。
该
--ssl-fips-mode
客户端选项控制一个给定的MySQL客户端是否在FIPS模式下运行。
该
ssl_fips_mode
系统变量和
--ssl-fips-mode
客户端选项允许这些值:
OFF
:禁用FIPS模式。
ON
:启用FIPS模式。
STRICT
:启用
“
严格
”
FIPS模式。
在服务器端,数字
ssl_fips_mode
的值0,1和2是等同于
OFF
,
ON
,和
STRICT
,respectivey。
一般来说,
STRICT
比限制更多的限制
ON
,但MySQL本身没有FIPS特定的代码,除了向OpenSSL指定FIPS模式值。
FIPS模式的确切行为
ON
或
STRICT
依赖于OpenSSL的版本。
有关详细信息,请参阅OpenSSL FIPS用户指南(请参阅
FIPS概述
)。
如果OpenSSL的FIPS对象模块不可用时,对于唯一的允许值
ssl_fips_mode
和
--ssl-fips-mode
是
OFF
。
尝试将FIPS模式设置为其他值时发生错误。
服务器端的FIPS模式适用于服务器执行的加密操作。 这包括在服务器内运行的复制(主/从和组复制)和X插件。
FIPS模式也适用于客户端连接到服务器的尝试。
在客户端或服务器端启用时,它会限制可以选择哪种受支持的加密密码。
但是,启用FIPS模式不要求必须使用加密连接,或者必须加密用户凭据。
例如,如果启用FIPS模式,则需要更强大的加密算法。
特别是,MD5受到限制,因此尝试使用加密密码建立加密连接,例如
RC4-MD5
不起作用。
但FIPS模式无法阻止建立未加密的连接。
(为此,您可以将该
REQUIRE
子句用于
CREATE
USER
或
ALTER
USER
对于特定用户帐户,或将
require_secure_transport
系统变量
设置
为影响所有帐户。)