MySQL8 中文参考(二十七),mysql8中文文档

MySQL8 中文参考(二十七) 原文:docs.oracle.com/javase/tutorial/reallybigindex.html 原文:dev.mysql.com/doc/refman/8.0/en

原文:docs.oracle.com/javase/tutorial/reallybigindex.html

原文:dev.mysql.com/doc/refman/8.0/en/sha256-pluggable-authentication.html

8.4.1.3 SHA-256 可插拔认证

MySQL 提供了两个身份验证插件,它们实现SHA-256 哈希算法来加密用户帐户密码。

sha256_password:实现基本SHA-256 身份验证。

caching_sha2_password:实现SHA-256 身份验证(如sha256_password),但使用服务器端缓存来提高性能,并具有更广泛适用的其他功能。

本节介绍原始的非缓存SHA-2 身份验证插件。有关插件缓存的更多信息,请参阅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 的加密功能。请参阅“使用加密连接”。

消息

sha256_password 中的“sha256”是指插件用于加密的256 位摘要长度。 caching_sha2_password 中的“sha2”更普遍地指的是SHA-2 类加密算法。 256 位加密就是一个例子。后一个名称选择为将来扩展可能的摘要长度留下了空间,而无需更改插件名称。

下表显示了服务器端和客户端插件名称。

表8.18 SHA-256 身份验证的插件和库名称

插件或文件插件或文件名服务器端插件sha256_password 客户端插件sha256_password 库文件无(包含插件)

以下部分提供特定于SHA-256 可插入身份验证的安装和使用信息。

安装SHA-256 可插入身份验证

使用SHA-256 的可插入身份验证

有关MySQL 中可插入身份验证的一般信息,请参阅第8.2.17 节“可插入身份验证”。

安装 SHA-256 可插拔认证

sha256_password 插件以服务器和客户端形式存在。

服务器端插件内置于服务器中,不需要显式加载,并且无法通过卸载来禁用。

客户端插件内置于libmysqlclient 客户端库中,可在链接到libmysqlclient 的任何程序中使用。

使用 SHA-256 可插拔认证

要将帐户配置为使用sha256_password 插件进行SHA-256 密码哈希,请使用以下语句:其中*password* 是所需的帐户密码。

创建用户“sha256user”@“localhost”

由sha256_password 通过\’*Password*\’ 识别。

服务器将sha256_password 插件分配给帐户,使用它使用SHA-256 加密密码,并将这些值存储在mysql.user 系统表的plugin 和authentication_string 列中。

上述步骤并不假设sha256_password 是默认的身份验证插件。如果sha256_password 是您的默认身份验证插件,您可以使用更简单的CREATE USER 语法。

要启动服务器并将服务器的默认身份验证插件设置为sha256_password,请将以下行添加到服务器选项文件中:

[mysqld]

default_authentication_plugin=sha256_password

这将导致新帐户默认使用sha256_password 插件。因此,您可以创建一个帐户并为其设置密码,而无需明确命名该插件。

创建由“*密码*”标识的用户“sha256user”@“localhost”;

将default_authentication_plugin 设置为sha256_password 的另一个后果是,您必须显式指定另一个插件才能使用它来创建帐户。例如,要使用mysql_native_password 插件,请使用以下语句:

创建用户“nativeuser”@“localhost”

由mysql_native_password BY \’*password*\’ 识别;

sha256_password 支持通过安全传输进行连接。如果MySQL 是使用OpenSSL 编译的,并且您要连接的MySQL 服务器配置为支持RSA(使用本节后面描述的RSA 配置步骤),则sha256_password 也支持使用RSA 进行加密密码交换。

RSA 支持包括以下功能:

在服务器端,两个系统变量命名RSA 私钥/公钥对文件:sha256_password_private_key_path 和sha256_password_public_key_path。如果您使用的密钥文件的名称与系统变量的默认值不同,则数据库管理员必须在启动服务器时设置这些变量。

服务器使用sha256_password_auto_generate_rsa_keys 系统变量来确定是否自动生成RSA 密钥对文件。请参阅创建SSL 和RSA 证书和密钥。

Rsa_public_key 状态变量显示sha256_password 身份验证插件使用的RSA 公钥的值。

拥有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 REPLICATION SOURCE TO 语句(MySQL 8.0.23 及更高版本)或CHANGE MASTER TO 语句(MySQL 8.0.23 之前的版本)和SOURCE_PUBLIC_KEY_PATH | MASTER_PUBLIC_KEY_PATH 选项来指定RSA 公钥文件。对于组复制,group_replication_recovery_get_public_key 系统变量具有相同的效果。

对于使用sha256_password 插件的客户端,连接到服务器时密码永远不会以明文形式暴露。密码的发送方式取决于是否使用安全连接或RSA 加密。

如果连接是安全的,则不需要或不使用RSA 密钥对。这适用于使用TLS 加密的连接。您的密码以明文形式发送,但您的连接是安全的并且无法被拦截。

消息

与caching_sha2_password 不同,sha256_password 插件不会将共享内存连接视为安全,即使共享内存传输默认情况下是安全的。

如果连接不安全并且存在RSA 密钥对,则连接将保持未加密状态。这适用于未使用TLS 加密的连接。 RSA仅用于客户端和服务器之间的密码交换,以防止密码窃听。当服务器收到加密的密码时,它会对其进行解密。加密使用一种混淆来防止重复攻击。

如果未使用安全连接并且RSA 加密不可用,则连接尝试将失败,因为密码必须以明文形式公开才能发送。

消息

要使用sha256_password 进行RSA 密码加密,必须使用OpenSSL 编译客户端和服务器,而不仅仅是其中之一。

假设MySQL 是使用OpenSSL 编译的,请使用以下步骤启用RSA 密钥对,以便在客户端连接期间进行密码交换。

按照创建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/local/mysql/myprivkey.pem

sha256_password_public_key_path=/usr/local/mysql/mypubkey.pem

重新启动服务器,连接到服务器,并检查Rsa_public_key 状态变量的值。显示的实际值将与此处显示的不同,但不应为空。

mysql 显示状态如“Rsa_public_key”\\G

************************** 1\\. 行****************** * **********

变量名称: Rsa_public_key

Value:—–公钥开始——

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO9nRUD+KvSZgY7cNBZMNpwX6

MvE1PbJFXO7u18nJ9lwc99Du/E7lw6CVXw7VKrXPeHbVQUzGyUNkf45Nz/ckaaJa

aLgJOBCIDmNVnyU54OT/1lcs2xiyfaDMe8fCJ64ZwTnKbY2gkt1IMjUAB5Ogd5kJ

g8aV7EtKwyhHb0c30QIDAQAB

—– 公钥结束—–

如果该值为空,则服务器检测到密钥文件有问题。检查错误日志以获取诊断信息。

服务器配置了RSA 密钥文件后,使用sha256_password 插件进行身份验证的帐户可以选择使用这些密钥文件连接到服务器。如前所述,这些帐户可以使用安全连接(在本例中没有RSA)或使用RSA 的未加密连接来执行密码交换。假设连接未加密。例如:

$ mysql –ssl-mode=禁用-u sha256user -p

请输入您的密码: *密码*

对于sha256user 的此连接尝试,服务器确定sha256_password 是适当的身份验证插件并调用它(因为它是在CREATE USER 期间指定的)。该插件检测到您的连接未加密,因此您必须使用RSA 加密发送密码。在这种情况下,插件将RSA 公钥发送到客户端,客户端使用它来加密密码并将结果返回到服务器。该插件使用RSA私钥在服务器端解密密码,并根据密码是否正确接受或拒绝连接。

服务器根据需要将RSA公钥发送给客户端。但是,如果客户端的文件包含服务器所需的RSA 公钥的本地副本,则可以使用–server-public-key-path 选项指定它。

$ mysql –ssl-mode=DISABLED -u sha256user -p –server-public-key-path=*文件名*

请输入您的密码: *密码*

–server-public-key-path 选项指定的文件中的公钥值必须与sha256_password_public_key_path 系统变量指定的服务器端文件中的密钥值相同。如果密钥文件包含有效的公钥值,但该值不正确,则会出现访问被拒绝错误。如果密钥文件不包含有效的公钥,则客户端程序无法使用它。在这种情况下,sha256_password 插件将公钥发送到客户端,就好像未指定–server-public-key-path 选项一样。

客户端用户可以通过两种方式获取RSA公钥:

您的数据库管理员可以为您提供公钥文件的副本。

客户端用户可以通过其他方式连接到服务器,例如使用SHOW STATUS LIKE \’Rsa_public_key\’ 语句并将返回的密钥值保存到文件中。

原文:dev.mysql.com/doc/refman/8.0/en/cleartext-pluggable-authentication.html

8.4.1.4 客户端端明文可插拔身份验证

客户端身份验证插件允许客户端以明文形式向服务器发送密码,无需散列或加密。该插件内置于MySQL 客户端库中。

下表显示了插件名称。

表8.19 明文认证插件名称和库名称

插件或文件插件或文件名服务器端插件无,请参阅讨论客户端插件mysql_clear_password 库文件无(包含插件)

许多客户端身份验证插件会在客户端将密码发送到服务器之前对其进行哈希或加密。这允许客户端避免以明文形式发送密码。

对于需要服务器接收客户端输入的密码的身份验证方法,无法对其进行哈希或加密。在这种情况下,客户端的mysql_clear_password 插件用于允许客户端以明文形式将密码发送到服务器。没有对应的服务器端插件。相反,mysql_clear_password 可以在客户端与需要明文密码的服务器端插件一起使用(例如PAM 或简单的LDAP 身份验证插件;请参阅第8.4.1.5 节,“PAM 可插入身份验证”)。以及第8.4.1.7 节“LDAP 可插入身份验证”)。

以下说明提供了特定于明文插件身份验证的使用信息。有关MySQL 中可插入身份验证的一般信息,请参阅第8.2.17 节“可插入身份验证”。

消息

在某些配置中,以明文形式发送密码可能会引起安全问题。为了避免出现问题,如果密码可以被截获,客户端应该使用保护密码的方法连接到MySQL 服务器。可能的方法包括SSL(请参阅使用加密连接)、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 选项来启用插件。

原文:dev.mysql.com/doc/refman/8.0/en/pam-pluggable-authentication.html

8.4.1.5 PAM 可插入认证

消息

PAM 可插拔身份验证是商业产品MySQL 企业版中包含的扩展。有关商业产品的更多信息,请访问www.mysql.com/products/。

MySQL企业版支持一种身份验证方法,允许MySQL服务器使用PAM(可插入身份验证模块)对MySQL用户进行身份验证。 PAM 允许系统使用标准接口访问多种身份验证方法,例如传统的Unix 密码和LDAP 目录。

PAM 可插入身份验证提供以下功能:

外部身份验证:PAM 身份验证允许MySQL 服务器接受来自MySQL 授权表外部定义的用户的连接,并使用PAM 支持的方法对它们进行身份验证。

支持代理用户:PAM 身份验证可以根据外部用户所属的PAM 组和提供的身份验证字符串,返回与客户端程序传递的外部用户名不同的MySQL 用户名。这意味着插件可以返回定义。外部PAM 身份验证用户需要特权MySQL 用户。例如,名为joe 的操作系统用户可以连接并拥有名为Developer 的MySQL 用户的权限。

PAM 可插拔认证已在Linux 和macOS 上进行了测试。请注意,Windows 不支持PAM。

下表显示了插件和库的文件名。文件名后缀可能会因您的系统而异。该文件必须放置在plugin_dir系统变量指定的目录中。有关安装详细信息,请参阅安装PAM 可插入身份验证。

表8.20 PAM 认证的插件和库名称

插件或文件插件或文件名服务器端插件authentication_pam 客户端插件mysql_clear_password 库文件authentication_pam.so

与服务器端PAM 插件通信的客户端mysql_clear_password 明文插件内置于libmysqlclient 客户端库中,并包含在所有发行版中,包括社区发行版。所有MySQL 发行版都包含客户端纯文本插件,允许任何发行版的客户端连接到加载了服务器端PAM 插件的服务器。

以下部分提供特定于PAM 可插入身份验证的安装和使用信息。

MySQL 用户PAM 身份验证的工作原理

安装PAM 可插入身份验证

卸载PAM 可插入身份验证

使用PAM 可插入身份验证

无代理用户的PAM Unix 密码身份验证

无代理用户的PAM LDAP 身份验证

使用代理用户和组映射的PAM Unix 密码身份验证

用于访问Unix 密码存储的PAM 身份验证

PAM 认证调试

有关MySQL 中可插入身份验证的一般信息,请参阅第8.2.17 节“可插入身份验证”。有关mysql_clear_password 插件的更多信息,请参阅客户端明文可插入身份验证。有关代理用户的更多信息,请参阅代理用户。

MySQL 用户的 PAM 认证工作原理

本节概述了MySQL 和PAM 如何协同工作来验证MySQL 用户。有关如何配置MySQL 帐户以使用特定PAM 服务的示例,请参阅使用PAM 可插入身份验证。

客户端程序与服务器进行通信,客户端将客户端用户名(默认为操作系统用户名)和密码发送给服务器。

客户端的用户名是外部用户名。

对于使用PAM服务器端身份验证插件的帐户,相应的客户端插件是mysql_clear_password。该客户端插件不执行密码散列,因此客户端以明文形式将密码发送到服务器。

服务器根据外部用户名和客户端连接的主机找到匹配的MySQL 帐户。 PAM 插件使用MySQL 服务器传递给它的信息,例如用户名、主机名、密码和身份验证字符串。定义使用PAM进行身份验证的MySQL帐户时,身份验证字符串包括:

PAM 服务名称。系统管理员可以用来指代特定应用程序的身份验证方法的名称。由于多个应用程序可以与单个数据库服务器实例关联,因此服务名称的选择留给SQL 应用程序开发人员。

或者,如果您使用代理,则可以将PAM 组映射到MySQL 用户名。

该插件使用身份验证字符串中指定的PAM 服务检查用户的凭据,并返回“身份验证成功。用户名是*user_name*”或“身份验证失败”。该密码必须适合PAM 服务使用的密码存储。例子:

对于传统的Unix 密码,该服务会查找/etc/shadow 文件中存储的密码。

对于LDAP,该服务搜索存储在LDAP 目录中的密码。

如果凭据检查失败,服务器将拒绝连接。

否则,身份验证字符串指示是否代理。如果该字符串不包含PAM 组映射,则不会发生代理。在这种情况下,MySQL 用户名与外部用户名相同。

否则,代理将针对PAM 组映射,并根据映射列表中的第一个匹配组确定MySQL 用户名。 “PAM 组”的含义因PAM 服务而异。例子:

对于传统的Unix 密码,组是/etc/group 文件中定义的Unix 组,可以用/etc/security/group.conf 等文件中的其他PAM 信息进行补充。

对于LDAP,组是LDAP 目录中定义的LDAP 组。

如果代理用户(外部用户)对被代理的MySQL 用户名具有PROXY 权限,则代理将运行,并且代理用户将承担被代理用户的权限。

安装 PAM 可插拔认证

本节介绍如何安装服务器端PAM 身份验证插件。有关安装插件的一般信息,请参阅安装和卸载插件。

为了使插件库文件可供服务器使用,必须将其放置在MySQL插件目录(由plugin_dir系统变量指定的目录)中。 (可选)通过在启动服务器时设置plugin_dir 的值来配置插件目录的位置。

插件库文件的基本名称是authentication_pam,通常使用.so后缀进行编译。

要在服务器启动时加载插件,请使用名为include 的–plugin-load-add 选项。

插件的库文件。使用此插件加载方法,每次启动服务器都必须提供该选项。例如,在服务器my.cnf文件中放入以下行:

[mysqld]
plugin-load-add=authentication_pam.so

修改my.cnf后,重新启动服务器以使新设置生效。

或者,要在运行时加载插件,请使用以下语句,根据需要调整.so后缀:

INSTALL PLUGIN authentication_pam SONAME \’authentication_pam.so\’;

INSTALL PLUGIN立即加载插件,并在mysql.plugins系统表中注册它,以使服务器在每次后续正常启动时加载它,而无需–plugin-load-add。

要验证插件安装,请检查信息模式PLUGINS表或使用SHOW PLUGINS语句(参见 Section 7.6.2, “Obtaining Server Plugin Information”)。例如:

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 可插拔认证

卸载 PAM 认证插件的方法取决于您安装插件的方式:

如果您使用–plugin-load-add选项在服务器启动时安装了插件,请在不带该选项的情况下重新启动服务器。
如果您使用INSTALL PLUGIN语句在运行时安装了插件,则在服务器重新启动时仍保留安装。要卸载它,请使用UNINSTALL PLUGIN:
UNINSTALL PLUGIN authentication_pam;

使用 PAM 可插拔认证

本节概述了如何使用 PAM 认证插件从 MySQL 客户端程序连接到服务器。以下各节提供了使用 PAM 认证的具体方法的说明。假定服务器正在运行并启用了服务器端 PAM 插件,如安装 PAM 可插拔认证中所述。

要在CREATE USER语句的IDENTIFIED WITH子句中引用 PAM 认证插件,请使用名称authentication_pam。例如:

CREATE USER *user*
IDENTIFIED WITH 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 用户,可以使用类似以下语句:

CREATE USER *user*
IDENTIFIED WITH 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*值可以包含除等号、逗号或空格之外的任何内容。
如果*pam_service_name、pam_group_name或mysql_user_name*值用双引号引起来,引号之间的所有内容都是值的一部分。例如,如果值包含空格字符,则这是必要的。所有字符都是合法的,除了双引号和反斜杠(\\)。要包含这两个字符,用反斜杠进行转义。

如果插件成功验证外部用户名(客户端传递的名称),它会查找认证字符串中的 PAM 组映射列表,并且如果存在,则根据外部用户所属的 PAM 组返回不同的 MySQL 用户名给 MySQL 服务器:

如果认证字符串不包含 PAM 组映射列表,则插件返回外部名称。
如果认证字符串包含 PAM 组映射列表,则插件会从左到右检查列表中的每个*pam_group_name*=*mysql_user_name*对,并尝试在已认证用户分配的非 MySQL 目录中找到*pam_group_name值的匹配项,并返回找到的第一个匹配项的mysql_user_name*。如果插件找不到任何 PAM 组的匹配项,则返回外部名称。如果插件无法在目录中查找组,则会忽略 PAM 组映射列表并返回外部名称。

以下各节描述了如何设置使用 PAM 身份验证插件的几种身份验证方案:

没有代理用户。这仅使用 PAM 来检查登录名和密码。每个被允许连接到 MySQL 服务器的外部用户都应该有一个匹配的 MySQL 帐户,该帐户被定义为使用 PAM 身份验证。(为了使 MySQL 帐户\’*user_name*\’@\’*host_name*\’与外部用户匹配,*user_name必须是外部用户名,host_name*必须与客户端连接的主机匹配。)认证可以通过各种 PAM 支持的方法进行。后续讨论将展示如何使用传统的 Unix 密码和 LDAP 密码来验证客户端凭据。
PAM 身份验证,如果不通过代理用户或 PAM 组进行,需要 MySQL 用户名与操作系统用户名相同。 MySQL 用户名限制为 32 个字符(参见第 8.2.3 节,“授权表”),这限制了 PAM 非代理身份验证仅限于最多 32 个字符的 Unix 帐户。
仅代理用户,带有 PAM 组映射。对于这种情况,创建一个或多个定义不同权限集的 MySQL 帐户。(理想情况下,没有人应该直接使用这些帐户连接。)然后定义一个通过 PAM 进行身份验证的默认用户,使用某种映射方案(通常基于用户所属的外部 PAM 组)将所有外部用户名映射到持有权限集的少数 MySQL 帐户。任何连接并指定外部用户名作为客户端用户名的客户端都将映射到一个 MySQL 帐户并使用其权限。本讨论将展示如何使用传统的 Unix 密码设置此功能,但也可以使用其他 PAM 方法,如 LDAP。

这些方案的变体是可能的:

您可以允许一些用户直接登录(无需代理),但要求其他用户通过代理帐户连接。
您可以通过在 PAM 身份验证帐户之间使用不同的 PAM 服务名称,为一些用户使用一种 PAM 身份验证方法,为其他用户使用另一种方法。例如,您可以为一些用户使用mysql-unix PAM 服务,为其他用户使用mysql-ldap。

示例做出以下假设。如果您的系统设置不同,您可能需要进行一些调整。

登录名和密码分别为antonio和*antonio_password*。请将其更改为要进行身份验证的用户。
PAM 配置目录为/etc/pam.d。
PAM 服务名称对应于认证方法(在本讨论中为mysql-unix或mysql-ldap)。要使用给定的 PAM 服务,您必须在 PAM 配置目录中设置一个同名的 PAM 文件(如果不存在则创建该文件)。此外,您必须在使用该 PAM 服务进行认证的任何账户的CREATE USER语句的认证字符串中命名 PAM 服务。

PAM 认证插件在初始化时检查服务器启动环境中是否设置了AUTHENTICATION_PAM_LOG环境值。如果是,则插件会启用将诊断消息记录到标准输出的功能。根据服务器的启动方式,消息可能会显示在控制台上或错误日志中。这些消息对于调试描相关问题很有帮助。有关更多信息,请参阅 PAM 认证调试。

无代理用户的 PAM Unix 密码认证

这种认证场景使用 PAM 来检查以操作系统用户名和 Unix 密码定义的外部用户,而无需代理。每个被允许连接到 MySQL 服务器的外部用户都应该有一个匹配的 MySQL 账户,该账户被定义为通过传统的 Unix 密码存储使用 PAM 认证。

注意

传统的 Unix 密码是使用/etc/shadow文件进行检查的。有关与该文件相关的可能问题的信息,请参阅 PAM 认证访问 Unix 密码存储。

验证 Unix 认证是否允许使用用户名antonio和密码*antonio_password*登录到操作系统。
通过创建名为/etc/pam.d/mysql-unix的mysql-unix PAM 服务文件来设置 PAM 以使用传统的 Unix 密码对 MySQL 连接进行认证。文件内容取决于系统,因此请检查/etc/pam.d目录中现有的与登录相关的文件以查看其外观。在 Linux 上,mysql-unix文件可能如下所示:
#%PAM-1.0
auth include password-auth
account include password-auth
对于 macOS,请使用login而不是password-auth。
在某些系统上,PAM 文件格式可能有所不同。例如,在 Ubuntu 和其他基于 Debian 的系统上,使用以下文件内容:
@include common-auth
@include common-account
@include common-session-noninteractive
创建一个与操作系统用户名相同的 MySQL 账户,并定义其使用 PAM 插件和mysql-unix PAM 服务进行认证:
CREATE USER \’antonio\’@\’localhost\’
IDENTIFIED WITH authentication_pam
AS \’mysql-unix\’;
GRANT ALL PRIVILEGES
ON mydb.*
TO \’antonio\’@\’localhost\’;
在这里,认证字符串仅包含 PAM 服务名称,mysql-unix,用于验证 Unix 密码。
使用mysql命令行客户端作为antonio连接到 MySQL 服务器。例如:
$> mysql –user=antonio –password –enable-cleartext-plugin
Enter password: *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选项)。参见 Section 8.4.1.4, “Client-Side Cleartext Pluggable Authentication”。
为了避免启用mysql_clear_password插件时密码暴露,MySQL 客户端应该使用加密连接连接到 MySQL 服务器。参见 Section 8.3.1, “Configuring MySQL to Use Encrypted Connections”。

无代理用户的 PAM LDAP 认证

这种认证场景使用 PAM 来检查以操作系统用户名和 LDAP 密码定义的外部用户,而无需代理。每个被允许连接到 MySQL 服务器的外部用户都应该有一个匹配的 MySQL 账户,该账户被定义为通过 LDAP 进行 PAM 认证。

要使用 PAM LDAP 可插拔认证为 MySQL,必须满足以下先决条件:

PAM LDAP 服务必须与 LDAP 服务器通信。
每个要由 MySQL 进行认证的 LDAP 用户必须存在于由 LDAP 服务器管理的目录中。

注意

另一种使用 LDAP 进行 MySQL 用户认证的方法是使用特定于 LDAP 的认证插件。参见 Section 8.4.1.7, “LDAP Pluggable Authentication”。

配置 MySQL 以进行 PAM LDAP 认证如下:

验证 Unix 认证是否允许使用用户名antonio和密码*antonio_password*登录到操作系统。
通过创建一个名为/etc/pam.d/mysql-ldap的mysql-ldap PAM 服务文件来设置 PAM 以使用 LDAP 认证 MySQL 连接。文件内容取决于系统,因此请检查/etc/pam.d目录中现有的与登录相关的文件以查看其内容。在 Linux 上,mysql-ldap文件可能如下所示:
#%PAM-1.0
auth required pam_ldap.so
account required pam_ldap.so
如果在您的系统上,PAM 对象文件的后缀与.so不同,请替换正确的后缀。
PAM 文件格式可能在某些系统上有所不同。
创建一个与操作系统用户名相同的 MySQL 账户,并定义其使用 PAM 插件和mysql-ldap PAM 服务进行验证:
CREATE USER \’antonio\’@\’localhost\’
IDENTIFIED WITH authentication_pam
AS \’mysql-ldap\’;
GRANT ALL PRIVILEGES
ON mydb.*
TO \’antonio\’@\’localhost\’;
这里,认证字符串仅包含 PAM 服务名称mysql-ldap,用 LDAP 进行验证。
连接到服务器的方式与 PAM Unix 密码认证无代理用户中描述的相同。

使用代理用户和组映射的 PAM Unix 密码认证

此处描述的认证方案使用代理和 PAM 组映射,将使用 PAM 进行验证的连接 MySQL 用户映射到定义了不同权限集的其他 MySQL 账户上。用户不直接通过定义权限的账户连接。相反,他们通过使用 PAM 进行身份验证的默认代理账户连接,以便将所有外部用户映射到具有权限的 MySQL 账户。使用代理账户连接的任何用户都将映射到这些 MySQL 账户之一,其权限确定了允许外部用户执行的数据库操作。

此处所示的过程使用 Unix 密码认证。要改用 LDAP,请参阅 PAM LDAP 认证无代理用户的早期步骤。

注意

传统的 Unix 密码使用/etc/shadow文件进行检查。有关与该文件相关的可能问题的信息,请参阅 PAM 认证访问 Unix 密码存储。

验证 Unix 认证是否允许使用用户名antonio和密码*antonio_password*登录操作系统。
验证antonio是否是root或users PAM 组的成员。
通过创建名为/etc/pam.d/mysql-unix的文件,设置 PAM 通过操作系统用户验证mysql-unix PAM 服务。文件内容取决于系统,因此请查看/etc/pam.d目录中现有的与登录相关的文件以了解其内容。在 Linux 上,mysql-unix文件可能如下所示:
#%PAM-1.0
auth include password-auth
account include password-auth
对于 macOS,请使用login而不是password-auth。
在某些系统上,PAM 文件格式可能有所不同。例如,在 Ubuntu 和其他基于 Debian 的系统上,使用以下文件内容:
@include common-auth
@include common-account
@include common-session-noninteractive
创建一个默认的代理用户(\’\’@\’\’),将外部 PAM 用户映射到代理账户:
CREATE USER \’\’@\’\’
IDENTIFIED WITH 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 安装中存在匿名用户,则可能会与默认代理用户发生冲突。有关此问题的更多信息以及处理方法,请参见 Default Proxy User and Anonymous User Conflicts。
创建被代理账户并为每个账户授予应具有的权限:
CREATE USER \’developer\’@\’localhost\’
IDENTIFIED WITH mysql_no_login;
CREATE USER \’data_entry\’@\’localhost\’
IDENTIFIED WITH mysql_no_login;
GRANT ALL PRIVILEGES
ON mydevdb.*
TO \’developer\’@\’localhost\’;
GRANT ALL PRIVILEGES
ON mydb.*
TO \’data_entry\’@\’localhost\’;
代理账户使用mysql_no_login认证插件,以防止客户端直接使用这些账户登录到 MySQL 服务器。相反,使用 PAM 进行身份验证的用户应该通过代理使用基于他们的 PAM 组的developer或data_entry账户。(假设插件已安装。有关说明,请参见 Section 8.4.1.9, “No-Login Pluggable Authentication”。)有关保护代理账户免受直接使用的替代方法,请参见 Preventing Direct Login to Proxied Accounts。
为每个被代理账户授予PROXY权限:
GRANT PROXY
ON \’developer\’@\’localhost\’
TO \’\’@\’\’;
GRANT PROXY
ON \’data_entry\’@\’localhost\’
TO \’\’@\’\’;
使用mysql命令行客户端作为安东尼奥连接到 MySQL 服务器。
$> mysql –user=antonio –password –enable-cleartext-plugin
Enter password: *antonio_password*
服务器使用默认的\’\’@\’\’代理账户对连接进行身份验证。安东尼奥的权限取决于他是哪些 PAM 组的成员。如果安东尼奥是root PAM 组的成员,PAM 插件将root映射到developer MySQL 用户名并将该名称返回给服务器。服务器验证\’\’@\’\’是否具有developer的PROXY权限,并允许连接。以下查询返回如下输出:
mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
+——————-+———————+————–+
| USER() | CURRENT_USER() | @@proxy_user |
+——————-+———————+————–+
| antonio@localhost | developer@localhost | \’\’@\’\’ |
+——————-+———————+————–+
这表明安东尼奥操作系统用户被验证具有授予developer MySQL 用户的权限,并且通过默认代理账户进行代理。
如果安东尼奥不是root PAM 组的成员,但是users PAM 组的成员,类似的过程会发生,但插件将user PAM 组成员映射到data_entry MySQL 用户名并将该名称返回给服务器:
mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
+——————-+———————-+————–+
| USER() | CURRENT_USER() | @@proxy_user |
+——————-+———————-+————–+
| antonio@localhost | data_entry@localhost | \’\’@\’\’ |
+——————-+———————-+————–+
这表明安东尼奥操作系统用户被验证具有data_entry MySQL 用户的权限,并且通过默认代理账户进行代理。

注意

客户端端的mysql_clear_password认证插件保持密码不变,因此客户端程序将其以明文形式发送到 MySQL 服务器。这使得密码可以原样传递给 PAM。在某些配置中,明文密码是使用服务器端 PAM 库所必需的,但可能在某些配置中存在安全问题。以下措施可最小化风险:

为了减少意外使用mysql_clear_password插件的可能性,MySQL 客户端必须显式启用它(例如,使用–enable-cleartext-plugin选项)。参见 Section 8.4.1.4, “Client-Side Cleartext Pluggable Authentication”。
启用mysql_clear_password插件以避免密码暴露,MySQL 客户端应该使用加密连接连接到 MySQL 服务器。参见 Section 8.3.1, “Configuring MySQL to Use Encrypted Connections”。

PAM 身份验证访问 Unix 密码存储

在某些系统上,Unix 身份验证使用密码存储,例如/etc/shadow,这是一个通常具有受限访问权限的文件。这可能导致 MySQL 基于 PAM 的身份验证失败。不幸的是,PAM 实现不允许区分“密码无法检查”(例如,由于无法读取/etc/shadow)和“密码不匹配”。如果您正在使用 Unix 密码存储进行 PAM 身份验证,您可以通过以下方法之一启用 MySQL 对其的访问:

假设 MySQL 服务器是从mysql操作系统帐户运行的,请将该帐户放入具有/etc/shadow访问权限的shadow组中:

在/etc/group中创建���个shadow组。
将mysql操作系统用户添加到/etc/group中的shadow组。
将/etc/group分配给shadow组并启用组读权限:
chgrp shadow /etc/shadow
chmod g+r /etc/shadow
重新启动 MySQL 服务器。
如果您正在使用pam_unix模块和unix_chkpwd实用程序,请按以下方式启用密码存储访问:
chmod u-s /usr/sbin/unix_chkpwd
setcap cap_dac_read_search+ep /usr/sbin/unix_chkpwd
根据您的平台调整unix_chkpwd的路径。

PAM 身份验证调试

PAM 身份验证插件在初始化时检查AUTHENTICATION_PAM_LOG环境值是否已设置。在 MySQL 8.0.35 及更早版本中,该值无关紧要。如果是,则插件将启用将诊断消息记录到标准输出的功能。这些消息可能有助于调试插件执行身份验证时出现的与 PAM 相关的问题。您应该知道,在这些版本中,这些消息中包含密码。

从 MySQL 8.0.36 开始,设置AUTHENTICATION_PAM_LOG=1(或其他任意值)会产生相同的诊断消息,但不包含任何密码。如果您希望在这些消息中包含密码,请设置AUTHENTICATION_PAM_LOG=PAM_LOG_WITH_SECRET_INFO。

一些消息包含对 PAM 插件源文件和行号的引用,这使得插件操作与其发生的代码位置更紧密地联系在一起。

用于调试连接失败并确定连接尝试期间发生的情况的另一种技术是配置 PAM 认证以允许所有连接,然后检查系统日志文件。这种技术应仅在临时基础上使用,而不是在生产服务器上使用。

使用以下内容配置名为 /etc/pam.d/mysql-any-password 的 PAM 服务文件(在某些系统上格式可能有所不同):

#%PAM-1.0
auth required pam_permit.so
account required pam_permit.so

创建一个使用 PAM 插件并命名为 mysql-any-password PAM 服务的帐户:

CREATE USER \’testuser\’@\’localhost\’
IDENTIFIED WITH 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 服务文件以禁用任意密码访问。

原文:dev.mysql.com/doc/refman/8.0/en/windows-pluggable-authentication.html

8.4.1.6 Windows 可插拔认证

注意

Windows 可插拔认证是 MySQL 企业版中包含的扩展,这是一个商业产品。要了解更多关于商业产品的信息,请查看www.mysql.com/products/。

Windows 版 MySQL 企业版支持一种在 Windows 上执行外部认证的认证方法,使 MySQL 服务器能够使用本机 Windows 服务对客户端连接进行认证。已登录到 Windows 的用户可以根据其环境中的信息从 MySQL 客户端程序连接到服务器,而无需指定额外的密码。

客户端和服务器在认证握手中交换数据包。由于这种交换,服务器创建一个代表客户端在 Windows OS 中身份的安全上下文对象。这个身份包括客户端账户的名称。Windows 可插拔认证使用客户端的身份来检查它是否是给定账户或组的成员。默认情况下,协商使用 Kerberos 进行认证,如果 Kerberos 不可用,则使用 NTLM。

Windows 可插拔认证提供了以下功能:

外部认证:Windows 认证使 MySQL 服务器能够接受来自在 Windows 登录的 MySQL 授权表之外定义的用户的连接。
代理用户支持:Windows 认证可以将一个与客户端程序传递的外部用户名不同的用户名返回给 MySQL。这意味着插件可以返回定义外部 Windows 认证用户应具有的权限的 MySQL 用户。例如,一个名为joe的 Windows 用户可以连接并具有名为developer的 MySQL 用户的权限。

以下表格显示了插件和库文件的名称。文件必须位于由plugin_dir系统变量命名的目录中。

表 8.21 Windows 认证的插件和库名称

插件或文件插件或文件名服务器端插件authentication_windows客户端插件authentication_windows_client库文件authentication_windows.dll
库文件仅包含服务器端插件。客户端插件内置于libmysqlclient客户端库中。

服务器端 Windows 认证插件仅包含在 MySQL 企业版中。它不包含在 MySQL 社区发行版中。客户端插件包含在所有发行版中,包括社区发行版。这使得来自任何发行版的客户端都能连接到加载了服务器端插件的服务器。

以下部分提供了特定于 Windows 可插拔认证的安装和使用信息:

安装 Windows 可插拔认证
卸载 Windows 可插拔认证
使用 Windows 可插拔认证

有关 MySQL 中可插拔认证的一般信息,请参阅 Section 8.2.17, “Pluggable Authentication”。有关代理用户信息,请参阅 Section 8.2.19, “Proxy Users”。

安装 Windows 可插拔认证

本节描述了如何安装服务器端 Windows 认证插件。有关安装插件的一般信息,请参阅 Section 7.6.1, “Installing and Uninstalling Plugins”。

要被服务器使用,插件库文件必须位于 MySQL 插件目录中(由plugin_dir系统变量命名的目录)。如果需要,通过在服务器启动时设置plugin_dir的值来配置插件目录位置。

要在服务器启动时加载插件,请使用–plugin-load-add选项命名包含插件的库文件。使用此插件加载方法,每次服务器启动时都必须提供该选项。例如,将以下行放入服务器my.cnf文件中:

[mysqld]
plugin-load-add=authentication_windows.dll

修改my.cnf后,重新启动服务器以使新设置生效。

或者,要在运行时加载插件,请使用以下语句:

INSTALL PLUGIN authentication_windows SONAME \’authentication_windows.dll\’;

INSTALL PLUGIN立即加载插件,并在mysql.plugins系统表中注册它,以使服务器在每次后续正常启动时加载它,而无需–plugin-load-add。

要验证插件安装,请检查信息模式PLUGINS表,或使用SHOW PLUGINS语句(参见 Section 7.6.2, “Obtaining Server Plugin Information”)。例如:

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 可插拔认证。 通过authentication_windows_use_principal_name和authentication_windows_log_level系统变量提供了额外的插件控制。 请参阅第 7.1.8 节,“服务器系统变量”。

卸载 Windows 可插拔认证

卸载 Windows 认证插件的方法取决于您安装它的方式:

如果您在服务器启动时使用–plugin-load-add选项安装插件,请在不带该选项的情况下重新启动服务器。
如果您使用INSTALL PLUGIN语句在运行时安装插件,则插件将在服务器重新启动时保持安装状态。 要卸载它,请使用UNINSTALL PLUGIN:
UNINSTALL PLUGIN authentication_windows;

另外,删除任何设置 Windows 插件相关系统变量的启动选项。

使用 Windows 可插拔认证

Windows 认证插件支持使用 MySQL 帐户,使得已登录 Windows 的用户可以连接到 MySQL 服务器,而无需指定额外的密码。 假定服务器正在运行并启用了服务器端插件,如安装 Windows 可插拔认证中所述。 一旦 DBA 启用了服务器端插件并设置了要使用它的帐户,客户端就可以使用这些帐户连接,而无需进行其他设置。

在CREATE USER语句的IDENTIFIED WITH子句中引用 Windows 认证插件,请使用名称authentication_windows。 假设 Windows 用户Rafal和Tasha应被允许连接到 MySQL,以及Administrators或Power Users组中的任何用户。 要设置这一点,请创建一个名为sql_admin的 MySQL 帐户,该帐户使用 Windows 插件进行身份验证:

CREATE USER sql_admin
IDENTIFIED WITH authentication_windows
AS \’Rafal, Tasha, Administrators, \”Power Users\”\’;

插件名称为authentication_windows。 AS关键字后面的字符串是认证字符串。 它指定了名为Rafal或Tasha的 Windows 用户被允许作为 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
IDENTIFIED WITH authentication_windows
AS \’Rafal, Tasha, Administrators, \”Power Users\”\’;
CREATE USER sql_admin
IDENTIFIED WITH 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*值可以包含除等号、逗号或空格之外的任何内容。
如果*win_user_or_group_name和/或mysql_user_name*值用双引号引起来,那么引号之间的所有内容都是值的一部分。例如,如果名称包含空格字符,则这是必要的。双引号内的所有字符都是合法的,除了双引号和反斜杠。要包含这两个字符,需要用反斜杠进行转义。
*win_user_or_group_name*值使用 Windows 主体的传统语法,可以是本地的或域中的。示例(注意反斜杠的加倍):
domain\\\\user
.\\\\user
domain\\\\group
.\\\\group
BUILTIN\\\\WellKnownGroup

当服务器调用插件来验证客户端时,插件从左到右扫描认证字符串,以查找与 Windows 用户匹配的用户或组。如果有匹配,插件将相应的*mysql_user_name*返回给 MySQL 服务器。如果没有匹配,则认证失败。

用户名称匹配优先于组名称匹配。假设名为win_user的 Windows 用户是win_group的成员,并且认证字符串如下所示:

\’win_group = sql_user1, win_user = sql_user2\’

当win_user连接到 MySQL 服务器时,既与win_group匹配,也与win_user匹配。插件将用户验证为sql_user2,因为更具体的用户匹配优先于组匹配,即使组在认证字符串中首先列出。

Windows 身份验证始终适用于从运行服务器的同一台计算机发起的连接。对于跨计算机连接,两台计算机必须在 Microsoft Active Directory 中注册。如果它们在同一个 Windows 域中,则无需指定域名。也可以允许来自不同域的连接,就像这个例子中一样:

CREATE USER sql_accounting
IDENTIFIED WITH authentication_windows
AS \’SomeDomain\\\\Accounting\’;

这里 SomeDomain 是另一个域的名称。反斜杠字符被加倍,因为它是字符串中的 MySQL 转义字符。

MySQL 支持代理用户的概念,即客户端可以使用一个账户连接和认证到 MySQL 服务器,但在连接时具有另一个账户的权限(参见 Section 8.2.19, “Proxy Users”)。假设您希望 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
IDENTIFIED WITH authentication_windows
AS \’local_user = local_wlad,
MyDomain\\\\domain_user = local_wlad,
MyDomain\\\\Developers = local_dev,
BUILTIN\\\\Administrators = local_admin\’;
为了使代理工作,代理账户必须存在,因此创建它们:
CREATE USER local_wlad
IDENTIFIED WITH mysql_no_login;
CREATE USER local_dev
IDENTIFIED WITH mysql_no_login;
CREATE USER local_admin
IDENTIFIED WITH mysql_no_login;
代理账户使用 mysql_no_login 认证插件,以防止客户端直接使用这些账户登录到 MySQL 服务器。相反,使用 Windows 进行身份验证的用户应该使用 win_proxy 代理账户。(这假定插件已安装。有关说明,请参见 Section 8.4.1.9, “No-Login Pluggable Authentication”。)有关保护代理账户免受直接使用的替代方法,请参见 Preventing Direct Login to Proxied Accounts。
您还应该执行 GRANT 语句(未显示),为每个代理账户授予所需的 MySQL 访问权限。
为代理账户授予 PROXY 权限,以代表每个代理账户:
GRANT PROXY ON local_wlad TO win_proxy;
GRANT PROXY ON local_dev TO win_proxy;
GRANT PROXY ON local_admin TO win_proxy;

现在,Windows 用户local_user和MyDomain\\domain_user可以作为win_proxy连接到 MySQL 服务器,并在经过身份验证后具有身份验证字符串中指定帐户(在本例中为local_wlad)的权限。以win_proxy身份连接的MyDomain\\Developers组中的用户具有local_dev帐户的权限。BUILTIN\\Administrators组中的用户具有local_admin帐户的权限。

要配置身份验证,使所有没有自己的 MySQL 帐户的 Windows 用户通过代理帐户进行身份验证,请在上述说明中将默认代理帐户(\’\’@\’\’)替换为win_proxy。有关默认代理帐户的信息,请参阅 Section 8.2.19, “Proxy Users”。

注意

如果您的 MySQL 安装中存在匿名用户,则它们可能与默认代理用户发生冲突。有关此问题的更多信息以及处理方法,请参阅 Default Proxy User and Anonymous User Conflicts。

要在 Connector/NET 8.0 及更高版本中使用 Windows 身份验证插件与 Connector/NET 连接字符串,请参阅 Connector/NET Authentication。

原文:dev.mysql.com/doc/refman/8.0/en/ldap-pluggable-authentication.html

8.4.1.7 LDAP 可插拔身份验证

注意

LDAP 可插拔身份验证是 MySQL 企业版中包含的扩展,是一种商业产品。要了解更多关于商业产品的信息,请参见www.mysql.com/products/。

MySQL 企业版支持一种身份验证方法,使 MySQL 服务器能够使用 LDAP(轻量级目录访问协议)通过访问目录服务(如 X.500)对 MySQL 用户进行身份验证。MySQL 使用 LDAP 获取用户、凭据和组信息。

LDAP 可插拔身份验证提供以下功能:

外部身份验证:LDAP 身份验证使 MySQL 服务器能够接受来自 LDAP 目录中定义的用户的连接,而不是在 MySQL 授权表中定义的用户。
代理用户支持:LDAP 身份验证可以根据外部用户所属的 LDAP 组返回一个与客户端程序传递的外部用户名不同的 MySQL 用户名给 MySQL,这意味着 LDAP 插件可以返回定义外部 LDAP 身份验证用户应具有的特权的 MySQL 用户。例如,名为joe的 LDAP 用户可以连接并具有名为developer的 MySQL 用户的特权,如果joe的 LDAP 组是developer。
安全性:使用 TLS,连接到 LDAP 服务器可以是安全的。

服务器端和客户端插件可用于简单和基于 SASL 的 LDAP 身份验证。在 Microsoft Windows 上,不支持基于 SASL 的 LDAP 身份验证的服务器端插件,但支持客户端插件。

以下表格显示了简单和基于 SASL 的 LDAP 身份验证的插件和库文件名称。文件名后缀可能在您的系统上有所不同。这些文件必须位于由plugin_dir系统变量指定的目录中。

表 8.22 简单 LDAP 身份验证的插件和库名称

插件或文件插件或文件名称服务器端插件名称authentication_ldap_simple客户端插件名称mysql_clear_password库文件名称authentication_ldap_simple.so
表 8.23 基于 SASL 的 LDAP 身份验证的插件和库名称

插件或文件插件或文件名称服务器端插件名称authentication_ldap_sasl客户端插件名称authentication_ldap_sasl_client库文件名称authentication_ldap_sasl.so,authentication_ldap_sasl_client.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 客户端和服务器之间发送明文密码。
注意
在 Microsoft Windows 上,不支持基于 SASL 的 LDAP 认证的服务器插件,但支持客户端插件。在其他平台上,服务器和客户端插件都受支持。

服务器端的 LDAP 认证插件仅包含在 MySQL 企业版中。它们不包含在 MySQL 社区发行版中。客户端端的 SASL LDAP 插件包含在所有发行版中,包括社区发行版,并且如前所述,客户端的mysql_clear_password插件内置于libmysqlclient客户端库中,该库也包含在所有发行版中。这使得来自任何发行版的客户端都可以连接到加载了适当服务器端插件的服务器。

以下各节提供了特定于 LDAP 可插拔认证的安装和使用信息:

LDAP 可插拔认证的先决条件
MySQL 用户的 LDAP 认证工作原理
安装 LDAP 可插拔认证
卸载 LDAP 可插拔认证
LDAP 可插拔认证和 ldap.conf
使用 LDAP 可插拔认证
简单 LDAP 认证
基于 SASL 的 LDAP 认证
代理 LDAP 认证
LDAP 认证组偏好和映射规范
LDAP 认证用户 DN 后缀
LDAP 认证方法
GSSAPI/Kerberos 认证方法
LDAP 搜索引荐

有关 MySQL 中可插拔认证的一般信息,请参见第 8.2.17 节,“可插拔认证”。有关mysql_clear_password插件的信息,请参见第 8.4.1.4 节,“客户端明文可插拔认证”。有关代理用户信息,请参见第 8.2.19 节,“代理用户”。

注意

如果您的系统支持 PAM 并允许 LDAP 作为 PAM 认证方法,另一种使用 LDAP 进行 MySQL 用户认证的方法是使用服务器端authentication_pam插件。请参见第 8.4.1.5 节,“PAM 可插拔认证”。

LDAP 可插拔认证的先决条件

要为 MySQL 使用 LDAP 可插拔认证,必须满足以下先决条件:

必须有 LDAP 服务器可用,以便 LDAP 认证插件与之通信。
要由 MySQL 进行认证的 LDAP 用户必须存在于 LDAP 服务器管理的目录中。
在使用服务器端authentication_ldap_sasl或authentication_ldap_simple插件的系统上必须有 LDAP 客户端库可用。目前支持的库是 Windows 本机 LDAP 库,或非 Windows 系统上的 OpenLDAP 库。
要使用基于 SASL 的 LDAP 认证:

LDAP 服务器必须配置为与 SASL 服务器通信。
在使用客户端端authentication_ldap_sasl_client插件的系统上必须有 SASL 客户端库可用。目前,唯一支持的库是 Cyrus SASL 库。
要使用特定的 SASL 认证方法,必须提供该方法所需的任何其他服务。例如,要使用 GSSAPI/Kerberos,必须提供 GSSAPI 库和 Kerberos 服务。

MySQL 用户的 LDAP 认证工作原理

本节概述了 MySQL 和 LDAP 如何共同工作以对 MySQL 用户进行认证。有关如何设置 MySQL 账户以使用特定 LDAP 认证插件的示例,请参见使用 LDAP 可插拔认证。有关 LDAP 插件可用的认证方法的信息,请参见 LDAP 认证方法。

客户端连接到 MySQL 服务器,提供 MySQL 客户端用户名和密码:

对于简单的 LDAP 认证,客户端和服务器端插件以明文形式传输密码。建议在 MySQL 客户端和服务器之间建立安全连接,以防止密码泄露。
对于基于 SASL 的 LDAP 认证,客户端和服务器端插件避免在 MySQL 客户端和服务器之间发送明文密码。例如,插件可能使用 SASL 消息来在 LDAP 协议内安全传输凭据。对于 GSSAPI 认证方法,客户端和服务器端插件使用 Kerberos 进行安全通信,而不直接使用 LDAP 消息。

如果客户端用户名和主机名与任何 MySQL 账户不匹配,则连接将被拒绝。

如果存在匹配的 MySQL 账户,则进行 LDAP 认证。LDAP 服务器查找与用户匹配的条目,并根据 LDAP 密码对该条目进行认证:

如果 MySQL 账户指定了 LDAP 用户的区分名称(DN),则 LDAP 认证将使用该值和客户端提供的 LDAP 密码。(要将 LDAP 用户 DN 与 MySQL 账户关联,包括在创建账户的CREATE USER语句中指定认证字符串的BY子句。)
如果 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 可插入认证

本节描述了如何安装服务器端 LDAP 认证插件。有关安装插件的一般信息,请参见第 7.6.1 节,“安装和卸载插件”。

要被服务器使用,插件库文件必须位于 MySQL 插件目录中(由plugin_dir系统变量命名的目录)。如有必要,通过在服务器启动时设置plugin_dir的值来配置插件目录位置。

服务器端插件库文件的基本名称为authentication_ldap_simple和authentication_ldap_sasl。文件名后缀因平台而异(例如,对于 Unix 和类 Unix 系统,为.so,对于 Windows 为.dll)。

注意

在 Microsoft Windows 上,不支持基于 SASL 的 LDAP 认证的服务器插件,但支持客户端插件。在其他平台上,服务器和客户端插件都受支持。

要在服务器启动时加载插件,使用–plugin-load-add选项命名包含插件的库文件。使用此插件加载方法,选项必须在每次服务器启动时给出。还要为您希望配置的任何插件提供的系统变量指定值。

每个服务器端 LDAP 插件都公开一组系统变量,以使其操作可以配置。设置大多数这些变量是可选的,但您必须设置指定 LDAP 服务器主机(以便插件知道在哪里连接)和 LDAP 绑定操作的基本区分名称(以限制搜索范围并获得更快的搜索)的变量。有关所有 LDAP 系统变量的详细信息,请参见第 8.4.1.13 节,“可插入认证系统变量”。

要加载插件并设置 LDAP 服务器主机和 LDAP 绑定操作的基本区分名称,需要在您的my.cnf文件中添加类似以下的行,根据需要调整.so后缀以适应您的平台:

[mysqld]
plugin-load-add=authentication_ldap_simple.so
authentication_ldap_simple_server_host=127.0.0.1
authentication_ldap_simple_bind_base_dn=\”dc=example,dc=com\”
plugin-load-add=authentication_ldap_sasl.so
authentication_ldap_sasl_server_host=127.0.0.1
authentication_ldap_sasl_bind_base_dn=\”dc=example,dc=com\”

修改my.cnf后,重新启动服务器以使新设置生效。

或者,要在运行时加载插件,请使用以下语句,根据需要调整您平台的.so后缀:

INSTALL PLUGIN authentication_ldap_simple
SONAME \’authentication_ldap_simple.so\’;
INSTALL PLUGIN authentication_ldap_sasl
SONAME \’authentication_ldap_sasl.so\’;

INSTALL PLUGIN立即加载插件,并在mysql.plugins系统表中注册它,以使服务器在每次后续正常启动时加载它,而无需–plugin-load-add。

在运行时安装插件后,它们公开的系统变量变得可用,您可以将其设置添加到您的my.cnf文件中,以配置插件以供后续重新启动。例如:

[mysqld]
authentication_ldap_simple_server_host=127.0.0.1
authentication_ldap_simple_bind_base_dn=\”dc=example,dc=com\”
authentication_ldap_sasl_server_host=127.0.0.1
authentication_ldap_sasl_bind_base_dn=\”dc=example,dc=com\”

修改my.cnf后,重新启动服务器以使新设置生效。

要在运行时设置和持久化每个值,而不是在启动时,请使用以下语句:

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 authentication_ldap_sasl_server_host=\’127.0.0.1\’;
SET PERSIST authentication_ldap_sasl_bind_base_dn=\’dc=example,dc=com\’;

SET PERSIST为运行中的 MySQL 实例设置一个值。它还保存该值,导致其在后续服务器重新启动时保留。要更改运行中的 MySQL 实例的值,而不使其在后续重新启动时保留,请使用GLOBAL关键字而不是PERSIST。参见 Section 15.7.6.1, “SET Syntax for Variable Assignment”。

要验证插件安装,请检查信息模式PLUGINS表或使用SHOW PLUGINS语句(参见 Section 7.6.2, “Obtaining Server Plugin Information”)。例如:

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 或启用 SELinux 的 EL 系统上,需要更改 SELinux 策略以启用 MySQL LDAP 插件与 LDAP 服务通信:

创建一个包含以下内容的文件mysqlldap.te:
module mysqlldap 1.0;
require {
type ldap_port_t;
type mysqld_t;
class tcp_socket name_connect;
}
#============= mysqld_t ==============
allow 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 可插拔认证

卸载 LDAP 认证插件的方法取决于您如何安装它们:

如果您在服务器启动时使用–plugin-load-add选项安装了插件,请在没有这些选项的情况下重新启动服务器。
如果您在运行时使用 INSTALL PLUGIN 安装了插件,则它们将在服务器重新启动时保持安装状态。要卸载它们,请使用 UNINSTALL PLUGIN:
UNINSTALL PLUGIN authentication_ldap_simple;
UNINSTALL PLUGIN authentication_ldap_sasl;

另外,从您的 my.cnf 文件中删除任何设置 LDAP 插件相关系统变量的启动选项。如果您使用 SET PERSIST 来持久化 LDAP 系统变量,请使用 RESET PERSIST 来删除这些设置。

LDAP 可插拔认证和 ldap.conf

对于使用 OpenLDAP 的安装,ldap.conf 文件为 LDAP 客户端提供全局默认值。可以在此文件中设置选项以影响 LDAP 客户端,包括 LDAP 认证插件。OpenLDAP 使用以下优先顺序的配置选项:

由 LDAP 客户端指定的配置。
在 ldap.conf 文件中指定的配置。要禁用此文件的使用,请设置 LDAPNOINIT 环境变量。
OpenLDAP 库内置默认值。

如果库默认值或 ldap.conf 值不能产生适当的选项值,则 LDAP 认证插件可能能够设置相关变量以直接影响 LDAP 配置。例如,LDAP 插件可以覆盖 ldap.conf 中的参数,如:

TLS 配置:系统变量可用于启用 TLS 并控制 CA 配置,例如 authentication_ldap_simple_tls 和 authentication_ldap_simple_ca_path 用于简单 LDAP 认证,以及 authentication_ldap_sasl_tls 和 authentication_ldap_sasl_ca_path 用于 SASL LDAP 认证。
LDAP 引荐。请参阅 LDAP 搜索引荐。

有关 ldap.conf 的更多信息,请参阅 ldap.conf(5) 手册页。

使用 LDAP 可插拔认证

本节描述了如何启用 MySQL 帐户使用 LDAP 可插拔认证连接到 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 帐户关联,包括在创建帐户的CREATE USER语句中包含一个BY子句。)如果帐户未命名任何 LDAP 字符串,则 LDAP 身份验证将使用客户端指定的用户名查找 LDAP 条目。
客户端程序使用适用于 MySQL 帐户使用的服务器端身份验证插件的连接方法进行连接。 对于 LDAP 身份验证,连接需要 MySQL 用户名和 LDAP 密码。 此外,对于使用服务器端authentication_ldap_simple插件的帐户,使用–enable-cleartext-plugin选项调用客户端程序以启用客户端端mysql_clear_password插件。

此处的说明假定以下场景:

MySQL 用户betsy和boris分别对betsy_ldap和boris_ldap的 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=People,dc=example,dc=com
uid=boris_ldap,ou=People,dc=example,dc=com
CREATE USER 语句创建 MySQL 账户时,在 BY 子句中指定 LDAP 用户,以指示 MySQL 账户进行身份验证的 LDAP 条目。

使用 LDAP 认证设置帐户的说明取决于使用的服务器端 LDAP 插件。 以下各节描述了几种使用场景。

简单 LDAP 认证

要为简单 LDAP 认证配置 MySQL 账户,CREATE USER 语句指定 authentication_ldap_simple 插件,并可选择命名 LDAP 用户的区分名称(DN):

CREATE USER *user*
IDENTIFIED WITH authentication_ldap_simple
[BY \’*LDAP user DN*\’];

假设 MySQL 用户 betsy 在 LDAP 目录中有以下条目:

uid=betsy_ldap,ou=People,dc=example,dc=com

然后创建 betsy 的 MySQL 账户的语句如下:

CREATE USER \’betsy\’@\’localhost\’
IDENTIFIED WITH authentication_ldap_simple
AS \’uid=betsy_ldap,ou=People,dc=example,dc=com\’;

在 BY 子句中指定的认证字符串不包括 LDAP 密码。 客户端用户必须在连接时提供密码。

客户端通过提供 MySQL 用户名和 LDAP 密码连接到 MySQL 服务器,并启用客户端端 mysql_clear_password 插件:

$> mysql –user=betsy –password –enable-cleartext-plugin
Enter password: *betsy_password* *(betsy_ldap LDAP password)*

注意

客户端端 mysql_clear_password 认证插件不会更改密码,因此客户端程序将其作为明文发送到 MySQL 服务器。 这使得密码可以原样传递到 LDAP 服务器。 在没有 SASL 的情况下使用服务器端 LDAP 库需要明文密码,但在某些配置中可能存在安全问题。 这些措施最小化了风险:

为了减少意外使用 mysql_clear_password 插件的可能性,MySQL 客户端必须显式启用它(例如,使用 –enable-cleartext-plugin 选项)。 请参见 Section 8.4.1.4, “Client-Side Cleartext Pluggable Authentication”。
为了避免启用 mysql_clear_password 插件时密码暴露,MySQL 客户端应该使用加密连接连接到 MySQL 服务器。 请参见 Section 8.3.1, “Configuring MySQL to Use Encrypted Connections”。

认证过程如下进行:

客户端插件将 betsy 和 betsy_password 作为客户端用户名和 LDAP 密码发送到 MySQL 服务器。
连接尝试匹配 \’betsy\’@\’localhost\’ 账户。 服务器端 LDAP 插件发现该账户具有一个认证字符串 \’uid=betsy_ldap,ou=People,dc=example,dc=com\’ 用于命名 LDAP 用户 DN。 该插件将此字符串和 LDAP 密码发送到 LDAP 服务器。
LDAP 服务器找到了 betsy_ldap 的 LDAP 条目,并且密码匹配,因此 LDAP 认证成功。
LDAP 条目没有组属性,因此服务器端插件将客户端用户名(betsy)作为经过身份验证的用户返回。这与客户端提供的相同用户名,因此不会发生代理,并且客户端会话使用\’betsy\’@\’localhost\’账户进行权限检查。

如果匹配的 LDAP 条目包含组属性,该属性值将成为经过身份验证的用户名,并且如果该值与betsy不同,则将发生代理。有关使用组属性的示例,请参阅具有代理功能的 LDAP 认证。

如果CREATE USER语句中没有包含BY子句来指定betsy_ldap LDAP 专有名称,认证尝试将使用客户端提供的用户名(在本例中为betsy)。在没有betsy的 LDAP 条目的情况下,认证将失败。

基于 SASL 的 LDAP 认证

要为 SASL LDAP 认证配置 MySQL 账户,CREATE USER 语句指定authentication_ldap_sasl插件,并可选择命名 LDAP 用户的专有名称(DN):

CREATE USER *user*
IDENTIFIED WITH authentication_ldap_sasl
[BY \’*LDAP user DN*\’];

假设 MySQL 用户boris在 LDAP 目录中有以下条目:

uid=boris_ldap,ou=People,dc=example,dc=com

然后创建boris的 MySQL 账户的语句如下:

CREATE USER \’boris\’@\’localhost\’
IDENTIFIED WITH authentication_ldap_sasl
AS \’uid=boris_ldap,ou=People,dc=example,dc=com\’;

BY子句中指定的认证字符串不包括 LDAP 密码。这必须由客户端用户在连接时提供。

客户端通过提供 MySQL 用户名和 LDAP 密码连接到 MySQL 服务器:

$> mysql –user=boris –password
Enter password: *boris_password* *(boris_ldap LDAP password)*

对于服务器端的authentication_ldap_sasl插件,客户端使用客户端的authentication_ldap_sasl_client插件。如果客户端程序找不到客户端插件,请指定一个–plugin-dir选项,指定安装插件库文件的目录。

boris的认证过程与之前描述的betsy的简单 LDAP 认证类似,只是客户端和服务器端的 SASL LDAP 插件使用 SASL 消息来在 LDAP 协议中安全传输凭据,以避免在 MySQL 客户端和服务器之间发送明文密码。

具有代理功能的 LDAP 认证

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=basha,ou=People,dc=example,dc=com,cn=accounting
uid=basil,ou=People,dc=example,dc=com,cn=front_office
在连接时,组属性值成为经过身份验证的用户名称,因此它们命名了accounting和front_office代理账户。
示例假定使用 SASL LDAP 身份验证。对于简单 LDAP 身份验证,请进行适当调整。

创建默认的代理 MySQL 账户:

CREATE USER \’\’@\’%\’
IDENTIFIED WITH authentication_ldap_sasl;

代理账户定义中没有AS \’*auth_string*\’子句来命名 LDAP 用户 DN。因此:

当客户端连接时,客户端用户名将成为要搜索的 LDAP 用户名。
预期匹配的 LDAP 条目将包括命名定义客户端应具有的权限的代理 MySQL 账户的组属性。

注意

如果您的 MySQL 安装中存在匿名用户,则可能会与默认代理用户发生冲突。有关此问题的更多信息以及处理方法,请参阅默认代理用户和匿名用户冲突。

创建代理账户并授予每个账户应具有的权限:

CREATE USER \’accounting\’@\’localhost\’
IDENTIFIED WITH mysql_no_login;
CREATE USER \’front_office\’@\’localhost\’
IDENTIFIED WITH mysql_no_login;
GRANT ALL PRIVILEGES
ON accountingdb.*
TO \’accounting\’@\’localhost\’;
GRANT ALL PRIVILEGES
ON frontdb.*
TO \’front_office\’@\’localhost\’;

代理帐户使用mysql_no_login身份验证插件防止客户端直接使用帐户登录到 MySQL 服务器。相反,使用 LDAP 进行身份验证的用户应该使用默认的\’\’@\’%\’代理帐户。(这假定安装了mysql_no_login插件。有关说明,请参见 Section 8.4.1.9, “No-Login Pluggable Authentication”。)有关保护代理帐户免受直接使用的替代方法,请参见 Preventing Direct Login to Proxied Accounts。

为每个代理帐户授予PROXY权限:

GRANT PROXY
ON \’accounting\’@\’localhost\’
TO \’\’@\’%\’;
GRANT PROXY
ON \’front_office\’@\’localhost\’
TO \’\’@\’%\’;

使用mysql命令行客户端连接到 MySQL 服务器作为basha。

$> mysql –user=basha –password
Enter password: *basha_password* *(basha LDAP password)*

认证过程如下:

服务器使用默认的\’\’@\’%\’代理帐户对客户端用户basha进行连接认证。
匹配的 LDAP 条目是:
uid=basha,ou=People,dc=example,dc=com,cn=accounting
匹配的 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:

$> mysql –user=basil –password
Enter password: *basil_password* *(basil LDAP password)*

对于basil的身份验证过程与先前描述的basha类似:

服务器使用默认的\’\’@\’%\’代理帐户对客户端用户basil进行连接认证。
匹配的 LDAP 条目是:
uid=basil,ou=People,dc=example,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 |
+—————–+————————+————–+
| basil@localhost | front_office@localhost | \’\’@\’%\’ |
+—————–+————————+————–+

这表明basil使用授予代理front_office MySQL 帐户的权限,并且代理通过默认代理用户帐户进行。

LDAP 认证组首选项和映射规范

如 LDAP 代理认证中所述,基本的 LDAP 认证代理工作原理是插件使用 LDAP 服务器返回的第一个组名作为 MySQL 代理用户账户名。这种简单的功能不允许指定任何偏好,关于如果 LDAP 服务器返回多个组名该使用哪个,或者指定任何名称而不是组名作为代理用户名称。

截至 MySQL 8.0.14,对于使用 LDAP 认证的 MySQL 账户,认证字符串可以指定以下信息以实现更大的代理灵活性:

一组按照偏好顺序排列的组,使得插件使用列表中与 LDAP 服务器返回的组匹配的第一个组名。
从组名到代理用户名称的映射,使得匹配的组名可以提供指定的名称作为代理用户使用。这提供了一个替代方案,不使用组名作为代理用户。

考虑以下 MySQL 代理账户定义:

CREATE USER \’\’@\’%\’
IDENTIFIED WITH authentication_ldap_sasl
AS \’+ou=People,dc=example,dc=com#grp1=usera,grp2,grp3=userc\’;

认证字符串有一个以+字符为前缀的用户 DN 后缀ou=People,dc=example,dc=com。因此,如 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 组偏好和映射信息,应遵循以下原则:

用 # 前缀字符开始认证字符串的组偏好和映射部分。
组偏好和映射规范是由逗号分隔的一个或多个项目的列表。每个项目的形式为 *group_name*=*user_name* 或 group_name。项目应按组名偏好顺序列出。对于插件从 LDAP 服务器返回的组名集合中选择的组名,两种语法在效果上有所不同:

对于指定为 *group_name*=*user_name*(带有用户名)的项目,组名映射到用户名,该用户名用作 MySQL 代理用户名称。
对于指定为 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
\”my_group_name\”=\”my_user_name\”
要转义字符,请在其前面加上反斜杠 (\\)。这对于包含文字双引号或反斜杠(否则不会被字面包含)特别有用。
用户 DN 不一定要出现在认证字符串中,但如果出现,必须在组偏好和映射部分之前。用户 DN 可以作为完整用户 DN 给出,也可以作为带有 + 前缀字符的用户 DN 后缀给出。(参见 LDAP 认证用户 DN 后缀.)

LDAP 认证用户 DN 后缀

LDAP 认证插件允许提供用户 DN 信息的认证字符串以 + 前缀字符开头:

在没有 + 字符的情况下,认证字符串值将按原样处理,不做修改。
如果认证字符串以+开头,插件将从客户端发送的用户名和认证字符串中指定的 DN(去除+)构造完整的用户 DN 值。在构造的 DN 中,客户端用户名成为指定 LDAP 用户名的属性值。默认情况下为uid;要更改属性,请修改相应的系统变量(authentication_ldap_simple_user_search_attr或authentication_ldap_sasl_user_search_attr)。认证字符串存储在mysql.user系统表中,认证之前动态构造完整的用户 DN。

此帐户认证字符串不以+开头,因此被视为完整的用户 DN:

CREATE USER \’baldwin\’
IDENTIFIED WITH authentication_ldap_simple
AS \’uid=admin,ou=People,dc=example,dc=com\’;

客户端使用帐户中指定的用户名(baldwin)连接。在这种情况下,该名称未被使用,因为认证字符串没有前缀,因此完全指定了用户 DN。

此帐户认证字符串以+开头,因此被视为用户 DN 的一部分:

CREATE USER \’accounting\’
IDENTIFIED WITH authentication_ldap_simple
AS \’+ou=People,dc=example,dc=com\’;

客户端使用帐户中指定的用户名(accounting)连接,该用户名与认证字符串一起用作构造用户 DN 的uid属性:uid=accounting,ou=People,dc=example,dc=com

前面示例中的帐户具有非空用户名,因此客户端始终使用帐户定义中指定的相同名称连接到 MySQL 服务器。如果帐户具有空用户名,例如使用代理进行 LDAP 认证中描述的默认匿名\’\’@\’%\’代理帐户,客户端可能使用不同的用户名连接到 MySQL 服务器。但原则是相同的:如果认证字符串以+开头,插件将使用客户端发送的用户名和认证字符串一起构造用户 DN。

LDAP 认证方法

LDAP 认证插件使用可配置的认证方法。适当的系统变量和可用的方法选择是特定于插件的:

对于authentication_ldap_simple插件:设置authentication_ldap_simple_auth_method_name系统变量以配置方法。允许的选择是SIMPLE和AD-FOREST。
对于 authentication_ldap_sasl 插件:设置 authentication_ldap_sasl_auth_method_name 系统变量以配置方法。允许的选择是 SCRAM-SHA-1、SCRAM-SHA-256 和 GSSAPI。(要确定主机系统上实际可用的 SASL LDAP 方法,请检查 Authentication_ldap_sasl_supported_methods 状态变量的值。)

有关每种允许方法的信息,请参阅系统变量描述。此外,根据方法的不同,可能需要额外的配置,如下面的部分所述。

GSSAPI/Kerberos 认证方法

通用安全服务应用程序接口(GSSAPI)是一个安全抽象接口。Kerberos 是可以通过该抽象接口使用的特定安全协议的一个实例。使用 GSSAPI,应用程序通过 Kerberos 进行身份验证以获取服务凭证,然后再使用这些凭证来实现对其他服务的安全访问。

其中一种服务是 LDAP,它被客户端和服务器端的 SASL LDAP 认证插件使用。当 authentication_ldap_sasl_auth_method_name 系统变量设置为 GSSAPI 时,这些插件使用 GSSAPI/Kerberos 认证方法。在这种情况下,插件通过 Kerberos 安全通信,而不直接使用 LDAP 消息。服务器端插件然后与 LDAP 服务器通信以解释 LDAP 认证消息并检索 LDAP 组。

GSSAPI/Kerberos 在 Linux 上作为 MySQL 服务器和客户端的 LDAP 认证方法得到支持。在 Linux 环境中,当应用程序通过默认启用 Kerberos 的 Microsoft Active Directory 访问 LDAP 时,这是非常有用的。

以下讨论提供了使用 GSSAPI 方法的配置要求信息。假定熟悉 Kerberos 概念和操作。以下列表简要定义了几个常见的 Kerberos 术语。您还可以在 RFC 4120 的术语表部分找到有用的信息。

主体:一个命名实体,比如用户或服务器。
KDC:密钥分发中心,包括 AS 和 TGS:

AS:认证服务器;提供获取额外票证所需的初始票证授予票证。
TGS:票证授予服务器;为拥有有效 TGT 的 Kerberos 客户端提供额外票证。
TGT:票据授予票据;提交给 TGS 以获取用于服务访问的服务票据。

使用 Kerberos 进行 LDAP 身份验证需要 KDC 服务器和 LDAP 服务器。可以通过不同方式满足此要求:

Active Directory 包括两个服务器,Active Directory LDAP 服务器默认启用 Kerberos 身份验证。
OpenLDAP 提供了一个 LDAP 服务器,但可能需要一个单独的 KDC 服务器,并需要额外的 Kerberos 设置。

客户端主机上也必须可用 Kerberos。客户端使用密码联系 AS 以获取 TGT。然后,客户端使用 TGT 从 TGS 获取其他服务的访问权限,例如 LDAP。

以下各节讨论了在 MySQL 中使用 GSSAPI/Kerberos 进行 SASL LDAP 身份验证的配置步骤:

验证 Kerberos 和 LDAP 的可用性
为 GSSAPI/Kerberos 配置服务器端 SASL LDAP 身份验证插件
创建一个使用 GSSAPI/Kerberos 进行 LDAP 身份验证的 MySQL 帐户
使用 MySQL 帐户连接到 MySQL 服务器
LDAP 身份验证的客户端配置参数

验证 Kerberos 和 LDAP 的可用性

以下示例显示如何在 Active Directory 中测试 Kerberos 的可用性。示例做出以下假设:

Active Directory 运行在名为ldap_auth.example.com的主机上,IP 地址为198.51.100.10。
与 MySQL 相关的 Kerberos 身份验证和 LDAP 查找使用MYSQL.LOCAL域。
名为bredon@MYSQL.LOCAL的主体已在 KDC 中注册。(在后续讨论中,此主体名称还与使用 GSSAPI/Kerberos 对 MySQL 服务器进行身份验证的 MySQL 帐户相关联。)

在满足这些假设的情况下,按照以下步骤操作:

验证操作系统中 Kerberos 库是否已安装和配置正确。例如,要为 MySQL 身份验证期间使用MYSQL.LOCAL域,/etc/krb5.conf Kerberos 配置文件应包含类似于以下内容:
[realms]
MYSQL.LOCAL = {
kdc = ldap_auth.example.com
admin_server = ldap_auth.example.com
default_domain = MYSQL.LOCAL
}
您可能需要为服务器主机在/etc/hosts中添加一个条目:
198.51.100.10 ldap_auth ldap_auth.example.com
检查 Kerberos 身份验证是否正常工作:

使用kinit进行 Kerberos 身份验证:
$> kinit bredon@MYSQL.LOCAL
Password for bredon@MYSQL.LOCAL: *(enter password here)*
该命令用于验证名为bredon@MYSQL.LOCAL的 Kerberos 主体。当命令提示时,请输入主体的密码。KDC 返回一个 TGT,该 TGT 在客户端缓存中供其他支持 Kerberos 的应用程序使用。
使用klist检查 TGT 是否正确获取。输出应类似于以下内容:
$> klist
Ticket cache: FILE:/tmp/krb5cc_244306
Default principal: bredon@MYSQL.LOCAL
Valid starting Expires Service principal
03/23/2021 08:18:33 03/23/2021 18:18:33 krbtgt/MYSQL.LOCAL@MYSQL.LOCAL
使用此命令检查ldapsearch是否与 Kerberos TGT 一起工作,该命令在MYSQL.LOCAL域中搜索用户:
ldapsearch -h 198.51.100.10 -Y GSSAPI -b \”dc=MYSQL,dc=LOCAL\”

配置服务器端 SASL LDAP 认证插件以使用 GSSAPI/Kerberos

假设 LDAP 服务器可以通过上述方式访问 Kerberos,配置服务器端 SASL LDAP 认证插件以使用 GSSAPI/Kerberos 认证方法。(有关一般 LDAP 插件安装信息,请参阅安装 LDAP 可插入认证。)以下是服务器my.cnf文件可能包含的插件相关设���示例:

[mysqld]
plugin-load-add=authentication_ldap_sasl.so
authentication_ldap_sasl_auth_method_name=\”GSSAPI\”
authentication_ldap_sasl_server_host=198.51.100.10
authentication_ldap_sasl_server_port=389
authentication_ldap_sasl_bind_root_dn=\”cn=admin,cn=users,dc=MYSQL,dc=LOCAL\”
authentication_ldap_sasl_bind_root_pwd=\”*password*\”
authentication_ldap_sasl_bind_base_dn=\”cn=users,dc=MYSQL,dc=LOCAL\”
authentication_ldap_sasl_user_search_attr=\”sAMAccountName\”

这些选项文件设置配置了 SASL LDAP 插件如下:

–plugin-load-add选项加载插件(根据需要调整.so后缀以适应您的平台)。如果之前使用INSTALL PLUGIN语句加载了插件,则此选项是不必要的。
authentication_ldap_sasl_auth_method_name必须设置为GSSAPI以使用 GSSAPI/Kerberos 作为 SASL LDAP 认证方法。
authentication_ldap_sasl_server_host和authentication_ldap_sasl_server_port指示用于身份验证的 Active Directory 服务器主机的 IP 地址和端口号。
authentication_ldap_sasl_bind_root_dn和authentication_ldap_sasl_bind_root_pwd配置了用于组搜索功能的根 DN 和密码。此功能是必需的,但用户可能没有搜索权限。在这种情况下,有必要提供根 DN 信息:

在 DN 选项值中,admin应该是具有执行用户搜索权限的管理 LDAP 帐户的名称。
在密码选项值中,*password*应该是admin帐户的密码。
authentication_ldap_sasl_bind_base_dn指示用户 DN 基本路径,以便搜索在MYSQL.LOCAL域中的用户。
authentication_ldap_sasl_user_search_attr 指定了一个标准的 Active Directory 搜索属性,sAMAccountName。此属性用于搜索以匹配登录名;属性值与用户 DN 值不同。

创建一个使用 GSSAPI/Kerberos 进行 LDAP 认证的 MySQL 账户

使用 GSSAPI/Kerberos 方法的 SASL LDAP 认证插件进行 MySQL 认证是基于一个作为 Kerberos 主体的用户。以下讨论使用一个名为 bredon@MYSQL.LOCAL 的主体作为此用户,必须在多个地方注册:

Kerberos 管理员应该将用户名称注册为 Kerberos 主体。此名称应包括域名。客户端使用主体名称和密码进行 Kerberos 认证并获取 TGT。
LDAP 管理员应在 LDAP 条目中注册用户名称。例如:
uid=bredon,dc=MYSQL,dc=LOCAL
注意
在 Active Directory(默认使用 Kerberos 作为认证方法),创建用户会同时创建 Kerberos 主体和 LDAP 条目。
MySQL DBA 应创建一个账户,其用户名称为 Kerberos 主体名称,并使用 SASL LDAP 插件进行认证。

假设适当的服务管理员已经注册了 Kerberos 主体和 LDAP 条目,并且,如前面在 Installing LDAP Pluggable Authentication 和 Configure the Server-Side SASL LDAP Authentication Plugin for GSSAPI/Kerberos 中描述的那样,MySQL 服务器已经以适当的配置设置启动了服务器端 SASL LDAP 插件。然后 MySQL DBA 创建一个对应于 Kerberos 主体名称的 MySQL 账户,包括域名。

注意

SASL LDAP 插件对于 Kerberos 认证使用一个固定的用户 DN,并忽略从 MySQL 配置的任何用户 DN。这有一定的影响:

对于使用 GSSAPI/Kerberos 认证的任何 MySQL 账户,在 CREATE USER 或 ALTER USER 语句中的认证字符串不应包含用户 DN,因为它没有任何效果。
因为认证字符串不包含用户 DN,所以应包含组映射信息,以使用户能够作为映射到所需代理用户的代理用户进行处理。有关使用 LDAP 认证插件进行代理的信息,请参阅 LDAP Authentication with Proxying。

以下语句创建一个名为bredon@MYSQL.LOCAL的代理用户,该用户假定了被代理用户proxied_krb_usr的权限。其他应具有相同权限的 GSSAPI/Kerberos 用户可以类似地为同一被代理用户创建代理用户。

— create proxy account
CREATE USER \’bredon@MYSQL.LOCAL\’
IDENTIFIED WITH authentication_ldap_sasl
BY \’#krb_grp=proxied_krb_user\’;
— create proxied account and grant its privileges;
— use mysql_no_login plugin to prevent direct login
CREATE USER \’proxied_krb_user\’
IDENTIFIED WITH mysql_no_login;
GRANT ALL
ON krb_user_db.*
TO \’proxied_krb_user\’;
— grant to proxy account the
— PROXY privilege for proxied account
GRANT PROXY
ON \’proxied_krb_user\’
TO \’bredon@MYSQL.LOCAL\’;

仔细观察第一个CREATE USER语句和GRANT PROXY语句中代理账户名称的引用:

对于大多数 MySQL 账户,用户和主机是账户名称的独立部分,因此分别引用为\’*user_name*\’@\’*host_name*\’。
对于 LDAP Kerberos 认证,账户名称的用户部分包括主体域,因此\’bredon@MYSQL.LOCAL\’被引用为单个值。因为没有给出主机部分,所以完整的 MySQL 账户名称使用默认的\’%\’作为主机部分:\’bredon@MYSQL.LOCAL\’@\’%\’

注意

当创建一个使用 GSSAPI/Kerberos 认证方法的authentication_ldap_sasl SASL LDAP 认证插件进行身份验证的账户时,CREATE USER语句将领域作为用户名的一部分。这与使用authentication_kerberos Kerberos 插件创建账户不同。对于这样的账户,CREATE USER语句不包括领域作为用户名的一部分。而是在BY子句中指定领域作为认证字符串。请参阅创建使用 Kerberos 认证的 MySQL 账户。

被代理账户使用mysql_no_login认证插件防止客户端直接使用该账户登录到 MySQL 服务器。相反,预期使用 LDAP 进行身份验证的用户使用bredon@MYSQL.LOCAL代理账户。(这假设已安装mysql_no_login插件。有关说明,请参见第 8.4.1.9 节,“无登录可插入认证”。)有关保护被代理账户免受直接使用的替代方法,请参见防止直接登录到被代理账户。

使用 MySQL 账户连接到 MySQL 服务器

设置使用 GSSAPI/Kerberos 进行身份验证的 MySQL 账户后,客户端可以使用它连接到 MySQL 服务器。Kerberos 认证可以在 MySQL 客户端程序调用之前或同时进行:

在调用 MySQL 客户端程序之前,客户端用户可以独立于 MySQL 从 KDC 获取 TGT。例如,客户端用户可以使用kinit通过提供 Kerberos 主体名称和主体密码来对 Kerberos 进行身份验证:
$> kinit bredon@MYSQL.LOCAL
Password for bredon@MYSQL.LOCAL: *(enter password here)*
结果的 TGT 被缓存并可供其他了解 Kerberos 的应用程序使用,例如使用客户端端 SASL LDAP 认证插件的程序。在这种情况下,MySQL 客户端程序使用 TGT 对 MySQL 服务器进行认证,因此调用客户端时不需要指定用户名或密码:
mysql –default-auth=authentication_ldap_sasl_client
正如刚才所描述的,当 TGT 被缓存时,在客户端命令中不需要用户名称和密码选项。如果命令中仍然包含它们,则处理如下:

如果命令包含用户名,如果该名称与 TGT 中的主体名称不匹配,则认证失败。
如果命令包含密码,客户端插件会忽略它。因为认证是基于 TGT 的,即使用户提供的密码不正确,也可以成功。因此,如果找到有效的 TGT 导致密码被忽略,插件会产生警告。
如果 Kerberos 缓存中不包含 TGT,则客户端端 SASL LDAP 认证插件本身可以从 KDC 获取 TGT。使用与 MySQL 账户关联的 Kerberos 主体的名称和密码选项调用客户端(在提示时输入主体密码):
mysql –default-auth=authentication_ldap_sasl_client
–user=bredon@MYSQL.LOCAL
–password
如果 Kerberos 缓存中不包含 TGT,并且客户端命令未指定主体名称作为用户名,则认证失败。

如果您不确定是否存在 TGT,可以使用 klist 进行检查。

认证过程如下:

客户端使用 TGT 使用 Kerberos 进行认证。
服务器找到主体的 LDAP 条目并用它来认证连接到 bredon@MYSQL.LOCAL MySQL 代理账户。
代理账户认证字符串中的组映射信息(\’#krb_grp=proxied_krb_user\’)表示认证的被代理用户应该是 proxied_krb_user。
bredon@MYSQL.LOCAL 被视为 proxied_krb_user 的代理,并且以下查询返回如下输出:
mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
+——————————+——————–+————————–+
| USER() | CURRENT_USER() | @@proxy_user |
+——————————+——————–+————————–+
| bredon@MYSQL.LOCAL@localhost | proxied_krb_user@% | \’bredon@MYSQL.LOCAL\’@\’%\’ |
+——————————+——————–+————————–+
USER() 值表示用于客户端命令的用户名(bredon@MYSQL.LOCAL)和客户端连接的主机(localhost)。
CURRENT_USER() 值是被代理用户账户的全名,由 proxied_krb_user 用户部分和 % 主机部分组成。
@@proxy_user 值表示用于连接到 MySQL 服务器的账户的全名,由 bredon@MYSQL.LOCAL 用户部分和 % 主机部分组成。
这表明代理是通过 bredon@MYSQL.LOCAL 代理用户账户进行的,并且 bredon@MYSQL.LOCAL 承担了授予 proxied_krb_user 被代理用户账户的权限。

一旦获得 TGT,客户端会将其缓存在本地,并且在不再需要重新输入密码的情况下可以一直使用直到过期。无论如何获取 TGT,客户端插件都会使用它来获取服务票据并与服务器端插件通信。

注意

当客户端身份验证插件本身获取 TGT 时,客户端用户可能不希望 TGT 被重复使用。如 LDAP 身份验证的客户端配置参数所述,本地的/etc/krb5.conf文件可用于使客户端插件在完成后销毁 TGT。

服务器端插件无法访问 TGT 本身或用于获取 TGT 的 Kerberos 密码。

LDAP 身份验证插件无法控制缓存机制(存储在本地文件中、内存中等),但 Kerberos 实用程序如kswitch可能可用于此目的。

LDAP 身份验证的客户端配置参数

authentication_ldap_sasl_client客户端端 SASL LDAP 插件会读取本地的/etc/krb5.conf文件。如果该文件丢失或无法访问,将会出现错误。假设该文件可访问,它可以包含一个可选的[appdefaults]部分,提供插件使用的信息。将信息放在部分的mysql部分内。例如:

[appdefaults]
mysql = {
ldap_server_host = \”ldap_host.example.com\”
ldap_destroy_tgt = true
}

客户端插件在mysql部分识别这些参数:

ldap_server_host值指定 LDAP 服务器主机,当该主机与[realms]部分指定的 KDC 服务器主机不同时,这可能很有用。默认情况下,插件使用 KDC 服务器主机作为 LDAP 服务器主机。
ldap_destroy_tgt值指示客户端插件在获取和使用 TGT 后是否销毁 TGT。默认情况下,ldap_destroy_tgt为false,但可以设置为true以避免 TGT 重复使用。(此设置仅适用于由客户端插件创建的 TGT,不适用于由 MySQL 的其他插件或外部创建的 TGT。)

LDAP 搜索引荐

LDAP 服务器可以配置为将 LDAP 搜索委派给另一个 LDAP 服务器,这种功能称为 LDAP 引荐。假设服务器a.example.com拥有一个\”dc=example,dc=com\”根 DN,并希望将搜索委派给另一个服务器b.example.com。为了启用这个功能,a.example.com将被配置为具有以下属性的命名引荐对象:

dn: dc=subtree,dc=example,dc=com
objectClass: referral
objectClass: extensibleObject
dc: subtree
ref: ldap://b.example.com/dc=subtree,dc=example,dc=com

启用 LDAP 引荐的一个问题是,当搜索基本 DN 为根 DN 且未设置引荐对象时,搜索可能会因 LDAP 操作错误而失败。即使在ldap.conf配置文件中全局设置了 LDAP 引荐,MySQL DBA 可能希望避免 LDAP 认证插件出现此类引荐错误。要根据插件特定的基础配置 LDAP 服务器在与每个插件通信时是否应使用 LDAP 引荐,需设置authentication_ldap_simple_referral和authentication_ldap_sasl_referral系统变量。将任一变量设置为ON或OFF会导致相应的 LDAP 认证插件告知 LDAP 服务器在 MySQL 认证期间是否使用引荐。每个变量具有插件特定的效果,不会影响与 LDAP 服务器通信的其他应用程序。这两个变量默认为OFF。

原文:dev.mysql.com/doc/refman/8.0/en/kerberos-pluggable-authentication.html

8.4.1.8 Kerberos 可插拔认证

注意

Kerberos 可插拔认证是 MySQL 企业版中包含的扩展,这是一个商业产品。要了解更多关于商业产品的信息,请参见www.mysql.com/products/。

MySQL 企业版支持一种认证方法,允许用户使用 Kerberos 对 MySQL 服务器进行身份验证,前提是有适当的 Kerberos 票证可用或可以获取。

该认证方法适用于 MySQL 8.0.26 及更高版本,在 Linux 上的 MySQL 服务器和客户端。在 Linux 环境中,应用程序可以访问默认启用 Kerberos 的 Microsoft Active Directory 时,这是非常有用的。从 MySQL 8.0.27 开始(MIT Kerberos 的 MySQL 8.0.32),客户端端插件也在 Windows 上受支持。服务器端插件仍然只在 Linux 上受支持。

Kerberos 可插拔认证提供了以下功能:

外部认证:Kerberos 认证使 MySQL 服务器能够接受来自 MySQL 授权表之外定义的用户的连接,这些用户已经获得了适当的 Kerberos 票证。
安全性:Kerberos 使用票证与对称密钥加密结合,实现了在网络上传输密码的身份验证。Kerberos 认证支持无用户和无密码的场景。

以下表显示了插件和库文件名称。文件名后缀可能在您的系统上有所不同。该文件必须位于由plugin_dir系统变量命名的目录中。有关安装信息,请参见安装 Kerberos 可插拔认证。

表 8.24 Kerberos 认证的插件和库名称

插件或文件插件或文件名服务器端插件authentication_kerberos客户端插件authentication_kerberos_client库文件authentication_kerberos.so,authentication_kerberos_client.so
服务器端 Kerberos 认证插件仅包含在 MySQL 企业版中。它不包含在 MySQL 社区发行版中。客户端插件包含在所有发行版中,包括社区发行版。这使得来自任何发行版的客户端都可以连接到加载了服务器端插件的服务器。

以下各节提供了特定于 Kerberos 可插拔认证的安装和使用信息:

Kerberos 可插拔认证的先决条件
MySQL 用户的 Kerberos 认证工作原理
安装 Kerberos 可插拔认证
使用 Kerberos 可插拔认证
Kerberos 认证调试

有关 MySQL 中可插拔认证的一般信息,请参阅 第 8.2.17 节,“可插拔认证”。

Kerberos 可插拔认证的先决条件

要在 MySQL 中使用可插拔的 Kerberos 认证,必须满足以下先决条件:

必须提供一个 Kerberos 服务,以便 Kerberos 认证插件进行通信。
MySQL 要对其进行认证的每个 Kerberos 用户(主体)必须存在于 KDC 服务器管理的数据库中。
在使用服务器端或客户端 Kerberos 认证插件的系统上必须提供 Kerberos 客户端库。此外,GSSAPI 用作访问 Kerberos 认证的接口,因此必须提供 GSSAPI 库。

MySQL 用户的 Kerberos 认证工作原理

本节概述了 MySQL 和 Kerberos 如何共同工作以对 MySQL 用户进行认证。有关如何设置 MySQL 帐户以使用 Kerberos 认证插件的示例,请参阅 使用 Kerberos 可插拔认证。

假定读者熟悉 Kerberos 的概念和操作。以下列表简要定义了几个常见的 Kerberos 术语。您还可以在 RFC 4120 的术语表部分找到有用的信息。

主体:命名实体,如用户或服务器。在本讨论中,某些与主体相关的术语经常出现:

SPN:服务主体名称;代表服务的主体名称。
UPN:用户主体名称;代表用户的主体名称。
KDC:密钥分发中心,包括 AS 和 TGS:

AS:认证服务器;提供获取额外票证所需的初始票证授予票证。
TGS:票据授予服务器;为拥有有效 TGT 的 Kerberos 客户端提供额外的票据。
TGT:票据授予票据;提交给 TGS 以获取用于服务访问的服务票据。
ST:服务票据;提供对 MySQL 服务器等服务的访问。

使用 Kerberos 进行身份验证需要一个 KDC 服务器,例如,由 Microsoft Active Directory 提供。

MySQL 中的 Kerberos 认证使用通用安全服务应用程序接口(GSSAPI),这是一个安全抽象接口。Kerberos 是可以通过该抽象接口使用的特定安全协议的一个实例。使用 GSSAPI,应用程序进行身份验证以获取服务凭据,然后依次使用这些凭据来启用对其他服务的安全访问。

在 Windows 上,authentication_kerberos_client 认证插件支持两种模式,客户端用户可以在运行时设置或在选项文件中指定:

SSPI 模式:安全支持提供程序接口(SSPI)实现了 GSSAPI(参见 SSPI 模式下的 Windows 客户端命令)。SSPI 在传输层面与 GSSAPI 兼容,但仅支持 Windows 单点登录场景,并且专门指代已登录用户。SSPI 是大多数 Windows 客户端的默认模式。
GSSAPI 模式:在 Windows 上通过 MIT Kerberos 库支持 GSSAPI(参见 GSSAPI 模式下的 Windows 客户端命令)。

使用 Kerberos 认证插件,应用程序和 MySQL 服务器能够使用 Kerberos 认证协议相互认证用户和 MySQL 服务。这样,用户和服务器都能够验证彼此的身份。不会通过网络发送密码,并且 Kerberos 协议消息受到窃听和重放攻击的保护。

MySQL 中的 Kerberos 认证遵循这些步骤,其中服务器端和客户端部分分别使用 authentication_kerberos 和 authentication_kerberos_client 认证插件执行:

MySQL 服务器向客户端应用程序发送其服务主体名称。此 SPN 必须在 Kerberos 系统中注册,并且在服务器端使用 authentication_kerberos_service_principal 系统变量进行配置。
使用 GSSAPI,客户端应用程序创建一个 Kerberos 客户端端身份验证会话,并与 Kerberos KDC 交换 Kerberos 消息:

客户端从认证服务器获取票据授予票据。
使用 TGT,客户端从票据授予服务获取 MySQL 的服务票据。
如果 TGT、ST 或两者都已在本地缓存,则可以跳过或部分跳过此步骤。客户端可以选择使用客户端 keytab 文件来获取 TGT 和 ST,而无需提供密码。
使用 GSSAPI,客户端应用程序向 MySQL 服务器呈现 MySQL ST。
使用 GSSAPI,MySQL 服务器创建一个 Kerberos 服务器端认证会话。服务器验证用户身份和用户请求的有效性。它使用其服务 keytab 文件中配置的服务密钥验证 ST,以确定身份验证成功或失败,并将身份验证结果返回给客户端。

应用程序可以使用提供的用户名和密码进行身份验证,也可以使用本地缓存的 TGT 或 ST(例如,使用 kinit 或类似方法创建)。因此,此设计涵盖了各种用例,从完全无用户和无密码连接,其中 Kerberos 服务票据是从本地存储的 Kerberos 缓存获取的,到提供并使用用户名和密码以获取有效的 Kerberos 服务票据从 KDC 发送到 MySQL 服务器的连接。

如前述描述所示,MySQL 的 Kerberos 认证使用两种类型的 keytab 文件:

在客户端主机上,可以使用客户端 keytab 文件来获取 TGT 和 ST,而无需提供密码。请参阅 Client Configuration Parameters for Kerberos Authentication。
在 MySQL 服务器主机上,使用服务器端服务 keytab 文件来验证 MySQL 服务器从客户端接收的服务票据。 keytab 文件名是使用 authentication_kerberos_service_key_tab 系统变量配置的。

有关 keytab 文件的信息,请参阅 web.mit.edu/kerberos/krb5-latest/doc/basic/keytab_def.html。

安装 Kerberos 可插拔认证

本节描述了如何安装服务器端 Kerberos 认证插件。有关安装插件的一般信息,请参阅 Section 7.6.1, “Installing and Uninstalling Plugins”。

注意

服务器端插件仅在 Linux 系统上受支持。在 Windows 系统上,仅支持客户端端插件(截至 MySQL 8.0.27),可以在 Windows 系统上用于连接使用 Kerberos 认证的 Linux 服务器。

要使服务器可用,插件库文件必须位于 MySQL 插件目录中(由plugin_dir系统变量命名的目录)。必要时,通过设置plugin_dir的值来配置插件目录位置以在服务器启动时生效。

服务器端插件库文件基本名称为authentication_kerberos。Unix 和类 Unix 系统的文件名后缀为.so。

要在服务器启动时加载插件,请使用–plugin-load-add选项命名包含插件的库文件。使用此插件加载方法,每次服务器启动时都必须提供该选项。还要为您希望配置的任何插件提供的系统变量指定值。插件公开这些系统变量,使其操作可以配置:

authentication_kerberos_service_principal: MySQL 服务主体名称(SPN)。此名称将发送给尝试使用 Kerberos 进行身份验证的客户端。SPN 必须存在于 KDC 服务器管理的数据库中。默认值为mysql/*host_name*@*realm_name*。
authentication_kerberos_service_key_tab: 用于验证从客户端接收到的票证的 keytab 文件。此文件必须存在并包含 SPN 的有效密钥,否则客户端的身份验证将失败。默认值为数据目录中的mysql.keytab。

有关所有 Kerberos 身份验证系统变量的详细信息,请参见 Section 8.4.1.13, “Pluggable Authentication System Variables”。

要加载插件并配置它,请在您的my.cnf文件中放入类似以下行的内容,使用适合您安装的系统变量的值:

[mysqld]
plugin-load-add=authentication_kerberos.so
authentication_kerberos_service_principal=mysql/krbauth.example.com@MYSQL.LOCAL
authentication_kerberos_service_key_tab=/var/mysql/data/mysql.keytab

修改my.cnf后,重新启动服务器以使新设置生效。

或者,要在运行时加载插件,请使用以下语句:

INSTALL PLUGIN authentication_kerberos
SONAME \’authentication_kerberos.so\’;

INSTALL PLUGIN立即加载插件,并在mysql.plugins系统表中注册它,以使服务器在每次后续正常启动时加载它,而无需–plugin-load-add。

当您在运行时安装插件而没有在my.cnf文件中配置其系统变量时,系统变量 authentication_kerberos_service_key_tab 将设置为数据目录中的默认值mysql.keytab。此系统变量的值不能在运行时更改,因此如果需要指定不同的文件,您需要将设置添加到您的my.cnf文件,然后重新启动 MySQL 服务器。例如:

[mysqld]
authentication_kerberos_service_key_tab=/var/mysql/data/mysql.keytab

如果 keytab 文件不在正确的位置或不包含有效的 SPN 密钥,则 MySQL 服务器不会验证此问题,但客户端会返回身份验证错误,直到您解决问题。

authentication_kerberos_service_principal 系统变量可以在运行时使用 SET PERSIST 语句设置和持久化,而无需重新启动服务器:

SET PERSIST authentication_kerberos_service_principal=\’mysql/krbauth.example.com@MYSQL.LOCAL\’;

SET PERSIST 为运行中的 MySQL 实例设置一个值。它还保存该值,导致其在后续服务器重启时保留。要更改运行中的 MySQL 实例的值,而不使其在后续重启中保留,使用GLOBAL关键字而不是PERSIST。参见 Section 15.7.6.1, “变量赋值的 SET 语法”。

要验证插件安装,请检查信息模式 PLUGINS 表或使用 SHOW PLUGINS 语句(参见 Section 7.6.2, “获取服务器插件信息”)。例如:

mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME = \’authentication_kerberos\’;
+————————-+—————+
| PLUGIN_NAME | PLUGIN_STATUS |
+————————-+—————+
| authentication_kerberos | ACTIVE |
+————————-+—————+

如果插件初始化失败,请检查服务器错误日志以获取诊断信息。

要将 MySQL 帐户与 Kerberos 插件关联,请参见 使用 Kerberos 可插拔认证。

使用 Kerberos 可插拔认证

本节描述了如何启用 MySQL 帐户使用 Kerberos 可插拔认证连接到 MySQL 服务器。假定服务器正在运行并启用了服务器端插件,如 安装 Kerberos 可插拔认证 中所述,并且客户端主机上可用客户端插件。

验证 Kerberos 可用性
创建一个使用 Kerberos 身份验证的 MySQL 帐户
使用 MySQL 帐户连接到 MySQL 服务器
Kerberos 身份验证的客户端配置参数

验证 Kerberos 的可用性

以下示例显示如何测试 Active Directory 中 Kerberos 的可用性。该示例做出以下假设:

Active Directory 正在名为krbauth.example.com的主机上运行,IP 地址为198.51.100.11。
与 MySQL 相关的 Kerberos 身份验证使用MYSQL.LOCAL域,并且还使用MYSQL.LOCAL作为领域名称。
名为karl@MYSQL.LOCAL的主体已在 KDC 中注册。(在后续讨论中,此主体名称与使用 Kerberos 身份验证连接到 MySQL 服务器的 MySQL 帐户相关联。)

在满足这些假设的情况下,按照以下步骤进行:

验证操作系统中是否正确安装和配置了 Kerberos 库。例如,要在 MySQL 身份验证期间使用MYSQL.LOCAL域和领域,/etc/krb5.conf Kerberos 配置文件应包含类似于以下内容:
[realms]
MYSQL.LOCAL = {
kdc = krbauth.example.com
admin_server = krbauth.example.com
default_domain = MYSQL.LOCAL
}
您可能需要为服务器主机在/etc/hosts中添加一个条目:
198.51.100.11 krbauth krbauth.example.com
检查 Kerberos 身份验证是否正常工作:

使用kinit进行 Kerberos 身份验证:
$> kinit karl@MYSQL.LOCAL
Password for karl@MYSQL.LOCAL: *(enter password here)*
该命令对名为karl@MYSQL.LOCAL的 Kerberos 主体进行身份验证。当命令提示时输入主体密码。KDC 返回一个 TGT,该 TGT 在客户端缓存以供其他了解 Kerberos 的应用程序使用。
使用klist检查 TGT 是否正确获取。输出应类似于以下内容:
$> klist
Ticket cache: FILE:/tmp/krb5cc_244306
Default principal: karl@MYSQL.LOCAL
Valid starting Expires Service principal
03/23/2021 08:18:33 03/23/2021 18:18:33 krbtgt/MYSQL.LOCAL@MYSQL.LOCAL

创建一个使用 Kerberos 身份验证的 MySQL 帐户

使用authentication_kerberos身份验证插件进行 MySQL 身份验证基于 Kerberos 用户主体名称(UPN)。这里的说明假设一个名为karl的 MySQL 用户使用 Kerberos 进行 MySQL 身份验证,Kerberos 领域命名为MYSQL.LOCAL,用户主体名称为karl@MYSQL.LOCAL。这个 UPN 必须在几个地方注册:

Kerberos 管理员应将用户名称注册为 Kerberos 主体。此名称包括领域名称。客户端使用主体名称和密码进行 Kerberos 身份验证,并获取票据授予票据(TGT)。
MySQL DBA 应创建一个与 Kerberos 主体名称对应并使用 Kerberos 插件进行身份验证的帐户。

假设适当的服务管理员已注册了 Kerberos 用户主体名称,并且如前所述在安装 Kerberos 可插拔认证中,MySQL 服务器已使用适当的配置设置启动了服务器端 Kerberos 插件。要创建与 Kerberos UPN *user*@*realm_name*对应的 MySQL 帐户,MySQL DBA 使用类似于以下语句:

CREATE USER *user*
IDENTIFIED WITH authentication_kerberos
BY \’*realm_name*\’;

由*user指定的帐户可以包含或省略主机名部分。如果省略主机名,则通常默认为%。realm_name*存储为mysql.user系统表中帐户的authentication_string值。

要创建与 UPN karl@MYSQL.LOCAL对应的 MySQL 帐户,请使用此语句:

CREATE USER \’karl\’
IDENTIFIED WITH authentication_kerberos
BY \’MYSQL.LOCAL\’;

如果 MySQL 必须为此帐户构造 UPN,例如获取或验证票证(TGT 或 ST),则通过组合帐户名(忽略任何主机名部分)和领域名来执行此操作。例如,从前述CREATE USER语句中得到的完整帐户名为\’karl\’@\’%\’。MySQL 从用户名部分karl(忽略主机名部分)和领域名MYSQL.LOCAL构造 UPN,以生成karl@MYSQL.LOCAL。

注意

请注意,当创建使用authentication_kerberos进行身份验证的帐户时,CREATE USER语句不包括 UPN 领域作为用户名的一部分。而是在BY子句中指定领域(在本例中为MYSQL.LOCAL)作为认证字符串。这与使用 GSSAPI/Kerberos 认证方法的authentication_ldap_sasl SASL LDAP 认证插件创建帐户不同。对于这样的帐户,CREATE USER语句包括 UPN 领域作为用户名的一部分。请参阅创建使用 GSSAPI/Kerberos 进行 LDAP 认证的 MySQL 帐户。

设置好帐户后,客户端可以使用它连接到 MySQL 服务器。该过程取决于客户端主机是运行 Linux 还是 Windows,如下面的讨论所示。

使用authentication_kerberos受到限制,即不支持具有相同用户部分但不同领域部分的 UPN。例如,您不能创建对应于以下这两个 UPN 的 MySQL 帐户:

kate@MYSQL.LOCAL
kate@EXAMPLE.COM

两个 UPN 都具有kate的用户部分,但领域部分不同(MYSQL.LOCAL与EXAMPLE.COM)。这是不允许的。

使用 MySQL 帐户连接到 MySQL 服务器

设置了使用 Kerberos 进行身份验证的 MySQL 帐户后,客户端可以按以下方式连接到 MySQL 服务器:

使用用户主体名称(UPN)和其密码对 Kerberos 进行身份验证,以获取票据授予票据(TGT)。
使用 TGT 获取 MySQL 的服务票据(ST)。
通过呈现 MySQL ST 向 MySQL 服务器进行身份验证。

第一步(向 Kerberos 进行身份验证)可以通过各种方式执行:

在连接到 MySQL 之前:

在 Linux 或在GSSAPI模式下的 Windows 上,调用kinit以获取 TGT 并将其保存在 Kerberos 凭据缓存中。
在SSPI模式下的 Windows 中,认证可能已在登录时完成,这会将登录用户的 TGT 保存在 Windows 内存缓存中。kinit不会被使用,也没有 Kerberos 缓存。
连接到 MySQL 时,客户端程序本身可以获取 TGT,如果它可以确定所需的 Kerberos UPN 和密码:

信息可以来自诸如命令选项或操作系统之类的来源。
在 Linux 上,客户端还可以使用 keytab 文件或/etc/krb5.conf配置文件。在GSSAPI模式下的 Windows 客户端使用配置文件。在SSPI模式下��Windows 客户端两者都不使用。

连接到 MySQL 服务器的客户端命令的详细信息因 Linux 和 Windows 而异,因此每个主机类型都会单独讨论,但这些命令属性适用于所有主机类型:

每个显示的命令都包括以下选项,但在某些情况下可以省略每个选项:

–default-auth选项指定客户端端身份验证插件的名称(authentication_kerberos_client)。当指定–user选项时,可以省略此选项,因为在这种情况下,MySQL 可以从 MySQL 服务器发送的用户帐户信息中确定插件。
–plugin-dir选项指示客户端程序authentication_kerberos_client插件的位置。如果插件安装在默认(编译内)位置,则可以省略此选项。
命令还应包括任何其他选项,如–host或–port,以指定连接到哪个 MySQL 服务器。
每个命令都要单独输入一行。如果命令包括–password选项以获取密码,请在提示时输入与 MySQL 用户关联的 Kerberos UPN 的密码。

Linux 客户端连接命令

在 Linux 上,连接到 MySQL 服务器的适当客户端命令因命令是使用来自 Kerberos 缓存的 TGT 进行身份验证,还是基于 MySQL 用户名和 UPN 密码的命令选项而异:

在调用 MySQL 客户端程序之前,客户端用户可以独立于 MySQL 从 KDC 获取 TGT。例如,客户端用户可以使用kinit通过提供 Kerberos 用户主体名称和主体密码来对 Kerberos 进行身份验证:
$> kinit karl@MYSQL.LOCAL
Password for karl@MYSQL.LOCAL: *(enter password here)*
生成的 UPN 的 TGT 被缓存,并可供其他了解 Kerberos 的应用程序使用,例如使用客户端端 Kerberos 认证插件的程序。在这种情况下,调用客户端时不指定用户名称或密码选项:
mysql
–default-auth=authentication_kerberos_client
–plugin-dir=*path/to/plugin/directory*
客户端插件在缓存中找到 TGT,使用它获取 MySQL ST,并使用 ST 对 MySQL 服务器进行身份验证。
正如刚才描述的,当 UPN 的 TGT 被缓存时,在客户端命令中不需要用户名称和密码选项。如果命令仍然包含它们,则处理如下:

此命令包括一个用户名选项:
mysql
–default-auth=authentication_kerberos_client
–plugin-dir=*path/to/plugin/directory*
–user=karl
在这种情况下,如果选项指定的用户名与 TGT 中的 UPN 的用户名部分不匹配,则身份验证将失败。
此命令包括一个密码选项,在提示时输入:
mysql
–default-auth=authentication_kerberos_client
–plugin-dir=*path/to/plugin/directory*
–password
在这种情况下,客户端端插件会忽略密码。因为身份验证是基于 TGT 的,即使用户提供的密码不正确,也可以成功*。因此,如果找到导致密码被忽略的有效 TGT,插件会产生警告。
如果 Kerberos 缓存中不包含 TGT,则客户端端 Kerberos 认证插件本身可以从 KDC 获取 TGT。使用 MySQL 用户名和密码的选项调用客户端,然后在提示时输入 UPN 密码:
mysql –default-auth=authentication_kerberos_client
–plugin-dir=*path/to/plugin/directory*
–user=karl
–password
客户端端的 Kerberos 认证插件将用户名称(karl)与用户帐户中指定的领域(MYSQL.LOCAL)结合起来构建 UPN(karl@MYSQL.LOCAL)。客户端插件使用 UPN 和密码获取 TGT,使用 TGT 获取 MySQL ST,并使用 ST 对 MySQL 服务器进行身份验证。
或者,假设 Kerberos 缓存中不包含 TGT,并且命令指定了密码选项但没有用户名称选项:
mysql –default-auth=authentication_kerberos_client
–plugin-dir=*path/to/plugin/directory*
–password
客户端端 Kerberos 认证插件使用操作系统登录名作为 MySQL 用户名。它将该用户名与用户的 MySQL 帐户中的领域结合起来构建 UPN。客户端插件使用 UPN 和密码获取 TGT,使用 TGT 获取 MySQL ST,并使用 ST 对 MySQL 服务器进行身份验证。

如果您不确定是否存在 TGT,可以使用klist进行检查。

注意

当客户端端 Kerberos 认证插件本身获取 TGT 时,客户端用户可能不希望 TGT 被重用。如用于 Kerberos 认证的客户端配置参数中所述,本地/etc/krb5.conf文件可用于使客户端插件在完成后销毁 TGT。

SSPI 模式下 Windows 客户端的连接命令

在 Windows 上,使用默认的客户端插件选项(SSPI),连接到 MySQL 服务器的适当客户端命令取决于命令是基于 MySQL 用户名和 UPN 密码的命令选项进行身份验证,还是使用 Windows 内存缓存中的 TGT。有关 Windows 上 GSSAPI 模式的详细信息,请参阅 GSSAPI 模式下 Windows 客户端的命令。

一个命令可以明确指定 MySQL 用户名和 UPN 密码的选项,也可以省略这些选项:

此命令包括 MySQL 用户名和 UPN 密码的选项:
mysql –default-auth=authentication_kerberos_client
–plugin-dir=*path/to/plugin/directory*
–user=karl
–password
客户端端的 Kerberos 认证插件将用户名称(karl)和用户帐户中指定的领域(MYSQL.LOCAL)结合起来构建 UPN(karl@MYSQL.LOCAL)。客户端插件使用 UPN 和密码获取 TGT,使用 TGT 获取 MySQL ST,并使用 ST 对 MySQL 服务器进行身份验证。
Windows 内存缓存中的任何信息都将被忽略;用户名称和密码选项值优先。
此命令包括 UPN 密码选项,但不包括 MySQL 用户名选项:
mysql
–default-auth=authentication_kerberos_client
–plugin-dir=*path/to/plugin/directory*
–password
客户端端的 Kerberos 认证插件使用已登录用户名称作为 MySQL 用户名,并将该用户名与用户 MySQL 帐户中的领域结合起来构建 UPN。客户端插件使用 UPN 和密码获取 TGT,使用 TGT 获取 MySQL ST,并使用 ST 对 MySQL 服务器进行身份验证。
此命令不包括 MySQL 用户名或 UPN 密码的选项:
mysql
–default-auth=authentication_kerberos_client
–plugin-dir=*path/to/plugin/directory*
客户端端插件从 Windows 内存缓存中获取 TGT,使用 TGT 获取 MySQL ST,并使用 ST 对 MySQL 服务器进行身份验证。
这种方法要求客户端主机是 Windows Server Active Directory (AD) 域的一部分。如果不是这种情况,请通过手动输入 AD 服务器和领域作为 DNS 服务器和前缀来帮助 MySQL 客户端发现 AD 域的 IP 地址:

启动 console.exe 并选择网络和共享中心。
从网络和共享中心窗口的侧边栏中,选择更改适配器设置。
在网络连接窗口中,右键单击要配置的网络或 VPN 连接,然后选择属性。
从网络选项卡中,找到并单击 Internet 协议版本 4 (TCP/IPv4),然后单击属性。
在 Internet 协议版本 4 (TCP/IPv4) 属性对话框中,单击高级。打开高级 TCP/IP 设置对话框。
从 DNS 选项卡中,将 Active Directory 服务器和领域添加为 DNS 服务器和前缀。
此命令包括 MySQL 用户名选项,但不包括 UPN 密码选项:
mysql
–default-auth=authentication_kerberos_client
–plugin-dir=*path/to/plugin/directory*
–user=karl
客户端端的 Kerberos 身份验证插件将由用户名称选项指定的名称与登录用户名进行比较。如果名称相同,则插件使用登录用户的 TGT 进行身份验证。如果名称不同,则身份验证失败。

在 GSSAPI 模式下的 Windows 客户端连接命令

在 Windows 上,客户端用户必须明确使用 plugin_authentication_kerberos_client_mode 插件选项指定 GSSAPI 模式,以通过 MIT Kerberos 库启用支持。默认模式为 SSPI(请参阅 SSPI 模式下 Windows 客户端的命令)。

可以指定 GSSAPI 模式:

在运行 Windows 主机上始终从 MIT Kerberos 缓存中检索或放置票证。
[mysql]
plugin_authentication_kerberos_client_mode=GSSAPI
或:
[mysql]
plugin-authentication-kerberos-client-mode=GSSAPI
在运行时从命令行使用 mysql 或 mysqldump 客户端程序。例如,以下命令(带有下划线或破折号)使 mysql 通过 MIT Kerberos 库连接到 Windows 上的服务器。
mysql *[connection-options]* –plugin_authentication_kerberos_client_mode=GSSAPI
或:
mysql *[connection-options]* –plugin-authentication-kerberos-client-mode=GSSAPI
客户端用户可以从 MySQL Workbench 和一些 MySQL 连接器中选择 GSSAPI 模式。在运行 Windows 的客户端主机上,您可以覆盖默认位置:

通过设置 KRB5_CONFIG 环境变量来配置 Kerberos 配置文件。
使用 KRB5CCNAME 环境变量设置默认凭据缓存名称(例如,KRB5CCNAME=DIR:/mydir/)。
有关特定客户端插件信息,请参阅 dev.mysql.com/doc/ 文档。

连接到 MySQL 服务器的适当客户端命令因命令是使用 MIT Kerberos 缓存中的 TGT 进行身份验证,还是基于 MySQL 用户名称和 UPN 密码的命令选项而异。在 Windows 上通过 MIT 库支持的 GSSAPI 与 Linux 上的 GSSAPI 类似(请参阅 Linux 客户端命令),但有以下例外:

在运行 MySQL 客户端程序之前,在选项文件中。插件变量名称可以使用下划线或破折号:
kinit 在 Windows 上以具有狭窄权限和特定角色的功能帐户运行。客户端用户不知道 kinit 密码。有关概述,请参阅 docs.oracle.com/en/java/javase/11/tools/kinit.html。
如果客户端用户提供密码,MIT Kerberos 库在 Windows 上决定是使用密码还是依赖现有票证。
描述在用于 Kerberos 认证的客户端配置参数中的destroy_tickets参数不受支持,因为 Windows 上的 MIT Kerberos 库不支持所需的 API 成员(get_profile_boolean)来从配置文件中读取其值。

用于 Kerberos 认证的客户端配置参数

本节仅适用于运行 Linux 的客户端主机,不适用于运行 Windows 的客户端主机。

注意

运行 Windows 的客户端主机,将authentication_kerberos_client客户端 Kerberos 插件设置为GSSAPI模式支持客户端配置参数,但 Windows 上的 MIT Kerberos 库不支持本节中描述的destroy_tickets参数。

如果在 MySQL 客户端应用程序调用时不存在有效的票证授予票证(TGT),应用程序本身可以获取并缓存 TGT。如果在 Kerberos 认证过程中,客户端应用程序导致 TGT 被缓存,任何添加的 TGT 在不再需要时可以通过设置适当的配置参数销毁。

authentication_kerberos_client客户端 Kerberos 插件读取本地的/etc/krb5.conf文件。如果该文件丢失或无法访问,将会出现错误。假设文件可访问,它可以包含一个可选的[appdefaults]部分,提供插件使用的信息。将信息放在该部分的mysql部分内。例如:

[appdefaults]
mysql = {
destroy_tickets = true
}

客户端插件在mysql部分识别这些参数:

destroy_tickets值指示客户端插件在获取和使用 TGT 后是否销毁 TGT。默认情况下,destroy_tickets为false,但可以设置为true以避免 TGT 重用。(此设置仅适用于由客户端插件创建的 TGT,不适用于由其他插件或外部 MySQL 创建的 TGT。)
在客户端主机上,可以使用客户端 keytab 文件来获取 TGT 和 TS 而无需提供密码。有关 keytab 文件的信息,请参阅web.mit.edu/kerberos/krb5-latest/doc/basic/keytab_def.html。

Kerberos 认证调试

AUTHENTICATION_KERBEROS_CLIENT_LOG环境变量用于启用或禁用 Kerberos 认证的调试输出。

注意

尽管AUTHENTICATION_KERBEROS_CLIENT_LOG中包含CLIENT,但同一环境变量也适用于服务器端插件以及客户端插件。

在服务器端,允许的值为 0(关闭)和 1(开启)。日志消息写入服务器错误日志,受服务器错误日志详细级别的影响。例如,如果您正在使用基于优先级的日志过滤,log_error_verbosity 系统变量控制详细程度,如第 7.4.2.5 节“基于优先级的错误日志过滤(log_filter_internal)”中所述。

在客户端,允许的值为 1 到 5,并写入标准错误输出。以下表格显示了每个日志级别值的含义。

日志级别含义1 或未设置无日志记录2错误消息3错误和警告消息4错误、警告和信息消息5错误、警告、信息和调试消息

#以上关于MySQL8 中文参考(二十七)的相关内容来源网络仅供参考,相关信息请以官方公告为准!

原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/92419.html

Like (0)
CSDN的头像CSDN
Previous 2024年6月27日
Next 2024年6月27日

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注