LDAP 可插拔身份验证是 MySQL 企业版中的扩展,MySQL 企业版是一款商业产品。要了解更多关于商业产品的信息,请访问 https://www.mysqlserver.cn/products/.
MySQL 企业版支持一种身份验证方法,使 MySQL 服务器能够使用 LDAP (轻量级目录访问协议) 通过访问 X.500 等目录服务来验证 MySQL 用户。MySQL 使用 LDAP 获取用户、凭据和组信息。
LDAP 可插拔身份验证提供以下功能
外部身份验证:LDAP 身份验证使 MySQL 服务器能够接受来自 LDAP 目录中定义的用户的连接,这些用户在 MySQL 授权表之外。
代理用户支持:LDAP 身份验证可以根据外部用户所属的 LDAP 组,将与客户端程序传递的外部用户名不同的用户名返回给 MySQL。这意味着 LDAP 插件可以返回定义外部 LDAP 验证用户应具有的权限的 MySQL 用户。例如,LDAP 用户名为
joe
的用户可以连接并拥有 MySQL 用户名为developer
的用户的权限,如果joe
的 LDAP 组为developer
。安全性:使用 TLS,连接到 LDAP 服务器可以是安全的。
服务器和客户端插件可用于简单和基于 SASL 的 LDAP 身份验证。在 Microsoft Windows 上,不支持基于 SASL 的 LDAP 身份验证的服务器插件,但支持客户端插件。
下表显示了用于简单和基于 SASL 的 LDAP 身份验证的插件和库文件名。文件名后缀可能在您的系统上有所不同。这些文件必须位于由 plugin_dir
系统变量命名的目录中。
表 8.20 用于简单 LDAP 身份验证的插件和库名称
插件或文件 | 插件或文件名 |
---|---|
服务器端插件名称 | authentication_ldap_simple |
客户端插件名称 | mysql_clear_password |
库文件名 | authentication_ldap_simple.so |
表 8.21 用于基于 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 身份验证。
MySQL 企业版才包含服务器端 LDAP 身份验证插件。MySQL 社区版中不包含这些插件。客户端 SASL LDAP 插件包含在所有发行版中,包括社区发行版,并且如前所述,客户端 mysql_clear_password
插件内置于 libmysqlclient
客户端库中,该库也包含在所有发行版中。这使来自任何发行版的客户端能够连接到已加载适当服务器端插件的服务器。
以下部分提供特定于 LDAP 可插拔身份验证的安装和使用信息。
有关 MySQL 中可插拔身份验证的常规信息,请参见 第 8.2.17 节,“可插拔身份验证”。有关 mysql_clear_password
插件的信息,请参见 第 8.4.1.3 节,“客户端明文可插拔身份验证”。有关代理用户的信息,请参见 第 8.2.19 节,“代理用户”。
如果您的系统支持 PAM 并且允许 LDAP 作为 PAM 身份验证方法,则使用 LDAP 对 MySQL 用户进行身份验证的另一种方法是使用服务器端 authentication_pam
插件。请参见 第 8.4.1.4 节,“PAM 可插拔身份验证”。
要对 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 帐户的示例,请参见 使用 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 身份验证插件。有关安装插件的常规信息,请参见 第 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.12 节,“可插拔身份验证系统变量”。
要加载插件并设置 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
。请参见 第 15.7.6.1 节,“SET 语法用于变量赋值”。
要验证插件安装,请检查 Information Schema PLUGINS
表,或者使用 SHOW PLUGINS
语句(请参见 第 7.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 可插拔身份验证。
在运行 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 身份验证插件的方法取决于您的安装方法。
如果您使用
--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
来删除这些设置。
对于使用 OpenLDAP 的安装,ldap.conf
文件为 LDAP 客户端提供全局默认值。可以在此文件中设置选项来影响 LDAP 客户端,包括 LDAP 身份验证插件。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)
手册页。
为了使 MySQL 帐户能够使用 LDAP 可插拔身份验证连接到 MySQL 服务器,LDAP 服务器必须可用并处于运行状态。MySQL 服务器和 LDAP 服务器之间的交互涉及两个步骤。首先,MySQL 服务器通过 TCP 建立与 LDAP 服务器的连接。其次,MySQL 服务器通过连接向 LDAP 服务器发送 LDAP 绑定请求,并在对帐户进行身份验证之前等待回复。如果任一步骤失败,MySQL 帐户将无法连接到 MySQL 服务器。
默认情况下,在连接和响应步骤中都会应用比主机系统超时值更短的超时时间。在所有情况下,如果超时时间到期,帐户用户会收到通知,告知其连接到 MySQL 的尝试被拒绝。客户端和服务器端日志可以提供更多信息。在客户端,设置以下环境变量以提高详细级别,然后重新启动 MySQL 客户端
AUTHENTICATION_LDAP_CLIENT_LOG=5
export AUTHENTICATION_LDAP_CLIENT_LOG
以下系统变量支持仅在 Linux 平台上针对基于 SASL 和简单 LDAP 身份验证的默认超时时间。
LDAP 身份验证的超时值可以在服务器启动时和运行时进行调整。如果您使用这些变量之一将超时时间设置为零,您将有效地将其禁用,并且 MySQL 服务器将恢复使用主机系统的默认超时时间。
在以下条件组合下,authentication_ldap_sasl_connect_timeout
设置的实际等待时间会加倍,因为(在内部)服务器必须两次调用 TCP 连接
LDAP 服务器处于脱机状态。
连接池正在使用中(具体而言,
authentication_ldap_sasl_max_pool_size
系统变量的值大于零,这将启用池)。
本节介绍如何启用 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 身份验证的 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_clear_password
插件来连接到 MySQL 服务器
$> mysql --user=betsy --password --enable-cleartext-plugin
Enter password: betsy_password (betsy_ldap LDAP password)
客户端端 mysql_clear_password
身份验证插件保持密码不变,因此客户端程序将其作为明文发送到 MySQL 服务器。这使密码能够按原样传递到 LDAP 服务器。使用服务器端 LDAP 库(不使用 SASL)需要明文密码,但在某些配置中可能存在安全问题。这些措施将风险降至最低
为了降低无意中使用
mysql_clear_password
插件的可能性,MySQL 客户端必须显式启用它(例如,使用--enable-cleartext-plugin
选项)。请参阅 第 8.4.1.3 节,“客户端端明文可插拔身份验证”。为了避免在启用
mysql_clear_password
插件的情况下公开密码,MySQL 客户端应使用加密连接连接到 MySQL 服务器。请参阅 第 8.3.1 节,“配置 MySQL 以使用加密连接”。
身份验证过程如下
客户端端插件将
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 身份验证的 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 身份验证插件支持代理,使用户能够以一个用户身份连接到 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 '
子句来命名 LDAP 用户 DN。因此auth_string
'
当客户端连接时,客户端用户名将成为要搜索的 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
插件已安装。有关说明,请参阅第 8.4.1.8 节,“无登录可插拔身份验证”。)有关保护代理帐户免遭直接使用的方法,请参阅阻止直接登录代理帐户。
为代理帐户授予每个代理帐户的PROXY
权限
GRANT PROXY
ON 'accounting'@'localhost'
TO ''@'%';
GRANT PROXY
ON 'front_office'@'localhost'
TO ''@'%';
使用mysql 命令行客户端以basha
身份连接到 MySQL 服务器。
$> 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 服务器返回的第一个组名作为 MySQL 代理用户帐户名。这种简单功能无法实现对 LDAP 服务器返回多个组名时使用哪个组名的任何优先级进行指定,也无法指定除了组名之外的任何名称作为代理用户名。
对于使用 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 服务器返回的组名集中选择作为匹配项的组名,这两种语法在效果上有所不同对于指定为
(带有用户名)的项目,组名映射到用户名,用户名用作 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 "my_group_name"="my_user_name"
若要转义字符,请在其前面加上反斜杠 (
\
)。这在特别需要包含文字双引号或反斜杠的情况下非常有用,否则它们将不会被文字包含。身份验证字符串中不必存在用户 DN,但如果存在,则必须位于组优先级和映射部分之前。用户 DN 可以作为完整的用户 DN 或作为带有
+
前缀字符的用户 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
)连接,在这种情况下,它与身份验证字符串一起被用作uid
属性来构建用户 DN:uid=accounting,ou=People,dc=example,dc=com
前面示例中的帐户具有非空的用户名,因此客户端始终使用帐户定义中指定的相同名称连接到 MySQL 服务器。如果帐户的用户名为空,例如使用代理的 LDAP 身份验证中描述的默认匿名''@'%'
代理帐户,客户端可能会使用不同的用户名连接到 MySQL 服务器。但是原理相同:如果身份验证字符串以+
开头,插件将使用客户端发送的用户名以及身份验证字符串来构建用户 DN。
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 进行身份验证以获取服务凭据,然后使用这些凭据反过来启用对其他服务的安全访问。
其中一项服务是 LDAP,客户端和服务器端 SASL LDAP 身份验证插件使用该服务。当authentication_ldap_sasl_auth_method_name
系统变量设置为GSSAPI
时,这些插件使用 GSSAPI/Kerberos 身份验证方法。在这种情况下,插件使用 Kerberos 安全通信,而不会直接使用 LDAP 消息。然后,服务器端插件与 LDAP 服务器通信以解释 LDAP 身份验证消息并检索 LDAP 组。
GSSAPI/Kerberos 作为 LDAP 身份验证方法,在 Linux 上的 MySQL 服务器和客户端中受支持。它在 Linux 环境中很有用,在这些环境中,应用程序可以通过 Microsoft Active Directory 访问 LDAP,默认情况下 Active Directory 启用了 Kerberos。
以下讨论提供了有关使用 GSSAPI 方法的配置要求的信息。假定熟悉 Kerberos 概念和操作。以下列表简要定义了几个常见的 Kerberos 术语。您可能还会发现RFC 4120的术语表部分有所帮助。
使用 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 的可用性
以下示例展示了如何测试 Active Directory 中 Kerberos 的可用性。该示例基于以下假设。
Active Directory 在名为
ldap_auth.example.com
且 IP 地址为198.51.100.10
的主机上运行。与 MySQL 相关的 Kerberos 身份验证和 LDAP 查找使用
MYSQL.LOCAL
域。名为
[email protected]
的主体已在 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 [email protected] Password for [email protected]: (enter password here)
该命令将为名为
[email protected]
的 Kerberos 主体进行身份验证。在命令提示输入密码时,输入主体密码。KDC 返回一个 TGT,该 TGT 会缓存在客户端,以便其他支持 Kerberos 的应用程序使用。使用klist检查 TGT 是否已正确获取。输出应类似于以下内容。
$> klist Ticket cache: FILE:/tmp/krb5cc_244306 Default principal: [email protected] Valid starting Expires Service principal 03/23/2021 08:18:33 03/23/2021 18:18:33 krbtgt/[email protected]
使用以下命令检查ldapsearch是否可以使用 Kerberos TGT,该命令将在
MYSQL.LOCAL
域中搜索用户。ldapsearch -h 198.51.100.10 -Y GSSAPI -b "dc=MYSQL,dc=LOCAL"
为 GSSAPI/Kerberos 配置服务器端 SASL LDAP 身份验证插件
假设 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 帐户
使用 SASL LDAP 身份验证插件(使用 GSSAPI/Kerberos 方法)进行 MySQL 身份验证基于一个用户,该用户是一个 Kerberos 主体。以下讨论使用名为[email protected]
的主体作为此用户,该主体必须在几个地方注册。
Kerberos 管理员应将用户名注册为 Kerberos 主体。此名称应包含域名称。客户端使用主体名称和密码向 Kerberos 进行身份验证并获取 TGT。
LDAP 管理员应将用户名注册到 LDAP 条目中。例如。
uid=bredon,dc=MYSQL,dc=LOCAL
注意在 Active Directory(使用 Kerberos 作为默认身份验证方法)中,创建用户会同时创建 Kerberos 主体和 LDAP 条目。
MySQL DBA 应创建一个帐户,该帐户的用户名为 Kerberos 主体名称,并使用 SASL LDAP 插件进行身份验证。
假设 Kerberos 主体和 LDAP 条目已由相应的服务管理员注册,并且如先前在 安装 LDAP 可插拔身份验证 和 为 GSSAPI/Kerberos 配置服务器端 SASL LDAP 身份验证插件 中所述,MySQL 服务器已启动并具有服务器端 SASL LDAP 插件的适当配置设置。然后,MySQL DBA 创建一个与 Kerberos 主体名称(包括域名)相对应的 MySQL 帐户。
SASL LDAP 插件对 Kerberos 身份验证使用常量用户 DN,并忽略 MySQL 配置的任何用户 DN。这有一些影响。
对于任何使用 GSSAPI/Kerberos 身份验证的 MySQL 帐户,
CREATE USER
或ALTER USER
语句中的身份验证字符串不应包含任何用户 DN,因为它们没有效果。由于身份验证字符串不包含用户 DN,因此它应该包含组映射信息,以使该用户能够被视为映射到所需代理用户的代理用户。有关使用 LDAP 身份验证插件进行代理的更多信息,请参阅 使用代理的 LDAP 身份验证。
以下语句创建一个名为 [email protected]
的代理用户,该用户假定名为 proxied_krb_usr
的代理用户的权限。其他应该具有相同权限的 GSSAPI/Kerberos 用户可以以类似方式作为同一代理用户的代理用户创建。
-- create proxy account
CREATE USER '[email protected]'
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 '[email protected]';
仔细观察第一个 CREATE USER
语句和 GRANT PROXY
语句中代理帐户名称的引用。
对于大多数 MySQL 帐户,用户和主机是帐户名称的独立部分,因此分别引用为
'
。user_name
'@'host_name
'对于 LDAP Kerberos 身份验证,帐户名称的用户部分包括主体域名,因此
'[email protected]'
引用为单个值。由于没有给出主机部分,因此完整的 MySQL 帐户名称使用默认值'%'
作为主机部分:'[email protected]'@'%'
。
当创建使用 authentication_ldap_sasl
SASL LDAP 身份验证插件和 GSSAPI/Kerberos 身份验证方法进行身份验证的帐户时,CREATE USER
语句包括 realm 作为用户名的一部分。这与创建使用 authentication_kerberos
Kerberos 插件的帐户不同。对于此类帐户,CREATE USER
语句不包括 realm 作为用户名的一部分。而是将 realm 指定为 BY
子句中的身份验证字符串。请参阅 创建使用 Kerberos 身份验证的 MySQL 帐户。
代理帐户使用 mysql_no_login
身份验证插件来阻止客户端使用该帐户直接登录到 MySQL 服务器。相反,预期使用 LDAP 进行身份验证的用户将使用 [email protected]
代理帐户。(这假设 mysql_no_login
插件已安装。有关说明,请参阅 第 8.4.1.8 节“No-Login 可插拔身份验证”)。有关保护代理帐户免遭直接使用的方法,请参阅 阻止直接登录代理帐户。
使用 MySQL 帐户连接到 MySQL 服务器
在设置使用 GSSAPI/Kerberos 进行身份验证的 MySQL 帐户后,客户端可以使用它连接到 MySQL 服务器。Kerberos 身份验证可以在 MySQL 客户端程序调用之前或时进行。
在调用 MySQL 客户端程序之前,客户端用户可以独立于 MySQL 从 KDC 获取 TGT。例如,客户端用户可以使用 kinit 通过提供 Kerberos 主体名称和主体密码来对 Kerberos 进行身份验证。
$> kinit [email protected] Password for [email protected]: (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 [email protected] --password
如果 Kerberos 缓存不包含 TGT 并且客户端命令未指定主体名称作为用户名,则身份验证将失败。
如果您不确定是否已存在 TGT,可以使用 klist 进行检查。
身份验证过程如下
客户端使用 TGT 使用 Kerberos 进行身份验证。
服务器找到主体的 LDAP 条目,并使用它为
[email protected]
MySQL 代理帐户对连接进行身份验证。代理帐户身份验证字符串中的组映射信息(
'#krb_grp=proxied_krb_user'
)表明已验证的代理用户应该是proxied_krb_user
。[email protected]
被视为proxied_krb_user
的代理,以下查询返回如所示的输出。mysql> SELECT USER(), CURRENT_USER(), @@proxy_user; +------------------------------+--------------------+--------------------------+ | USER() | CURRENT_USER() | @@proxy_user | +------------------------------+--------------------+--------------------------+ | [email protected]@localhost | proxied_krb_user@% | '[email protected]'@'%' | +------------------------------+--------------------+--------------------------+
USER()
值指示用于客户端命令的用户名([email protected]
)和客户端连接的来源主机(localhost
)。CURRENT_USER()
值是代理用户帐户的完整名称,它由proxied_krb_user
用户部分和%
主机部分组成。@@proxy_user
值指示用于连接到 MySQL 服务器的帐户的完整名称,它由[email protected]
用户部分和%
主机部分组成。这表明代理是通过
[email protected]
代理用户帐户进行的,并且[email protected]
承担了授予proxied_krb_user
代理用户帐户的权限。
一旦获得 TGT,它就会缓存在客户端,并且可以在它过期之前使用,而无需再次指定密码。无论如何获取 TGT,客户端插件都会使用它来获取服务票证并与服务器端插件通信。
当客户端身份验证插件本身获取 TGT 时,客户端用户可能不希望 TGT 被重复使用。如 LDAP 身份验证的客户端配置参数 中所述,本地 /etc/krb5.conf
文件可用于使客户端插件在完成 TGT 后将其销毁。
服务器端插件无法访问 TGT 本身或用于获取它的 Kerberos 密码。
LDAP 身份验证插件无法控制缓存机制(在本地文件中存储、在内存中存储等),但可能可以使用诸如 kswitch 之类的 Kerberos 实用程序来实现此目的。
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 后将其销毁。默认情况下,ldap_destroy_tgt
为false
,但可以设置为true
以避免 TGT 重用。(此设置仅适用于客户端插件创建的 TGT,不适用于其他插件或外部创建的 TGT。)
可以将 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 操作错误而失败。MySQL DBA 可能会希望避免 LDAP 身份验证插件出现此类引用错误,即使在 ldap.conf
配置文件中全局设置了 LDAP 引用。要在插件特定基础上配置 LDAP 服务器是否应在与每个插件通信时使用 LDAP 引用,请设置 authentication_ldap_simple_referral
和 authentication_ldap_sasl_referral
系统变量。将任一变量设置为 ON
或 OFF
会导致相应的 LDAP 身份验证插件告诉 LDAP 服务器在 MySQL 身份验证期间是否应使用引用。每个变量都有一个插件特定的效果,不会影响与 LDAP 服务器通信的其他应用程序。这两个变量默认都为 OFF
。