Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  LDAP Pluggable Authentication

8.4.1.7 LDAP 可插拔身份验证

Note

LDAP 可插拔身份验证是 MySQL Enterprise Edition 中的一个扩展,一个商业产品。要了解更多关于商业产品的信息,请参阅 https://www.mysql.com/products/

MySQL Enterprise Edition 支持一种身份验证方法,允许 MySQL Server 使用 LDAP(轻量级目录访问协议)来验证 MySQL 用户,通过访问目录服务,如 X.500。MySQL 使用 LDAP 来获取用户、凭据和组信息。

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

  • 外部身份验证:LDAP 身份验证使 MySQL Server 能够接受来自外部定义的用户的连接,在 LDAP 目录中。

  • 代理用户支持:LDAP 身份验证可以根据外部用户所属的 LDAP 组,返回到 MySQL 的用户名不同于客户端程序传递的外部用户名。这意味着 LDAP 插件可以返回 MySQL 用户,定义了外部 LDAP 验证用户应有的权限。例如,LDAP 用户名为 joe 的用户可以连接,并拥有 MySQL 用户名为 developer 的权限,如果 LDAP 组为 joedeveloper

  • 安全性:使用 TLS,连接到 LDAP 服务器可以是安全的。

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

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

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

Plugin or File Plugin or File Name
服务器端插件名 authentication_ldap_simple
客户端插件名 mysql_clear_password
库文件名 authentication_ldap_simple.so

表 8.23 基于 SASL 的 LDAP 身份验证的插件和库文件名

Plugin or File Plugin or File Name
服务器端插件名 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 消息来安全地传输凭据,避免在 MySQL 客户端和服务器之间发送明文密码。

    在 MySQL 8.3.0 及更高版本中,在 Microsoft Windows 上,服务器插件和客户端插件都支持基于 SASL 的 LDAP 身份验证。

服务器端 LDAP 身份验证插件仅包含在 MySQL Enterprise Edition 中,不包含在 MySQL 社区发行版中。客户端 SASL LDAP 插件包含在所有发行版中,包括社区发行版中,并且客户端 mysql_clear_password 插件是内置在 libmysqlclient 客户端库中的。这使得来自任何发行版的客户端都可以连接到具有适当服务器端插件的服务器。

以下部分提供了 LDAP 可插拔身份验证的安装和使用信息:

关于MySQL中可插拔身份验证的常规信息,请参阅第 8.2.17 节,“可插拔身份验证”。关于 mysql_clear_password 插件的信息,请参阅第 8.4.1.4 节,“客户端明文可插拔身份验证”。关于代理用户信息,请参阅第 8.2.19 节,“代理用户”

Note

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

LDAP可插拔身份验证先决条件

要使用LDAP可插拔身份验证,必须满足以下先决条件:

  • LDAP服务器必须可用,以便LDAP身份验证插件与其通信。

  • 要由MySQL身份验证的LDAP用户必须存在于LDAP服务器管理的目录中。

  • LDAP客户端库必须在使用服务器端 authentication_ldap_saslauthentication_ldap_simple 插件的系统上可用。当前,支持的库是Windows本机LDAP库或非Windows系统上的OpenLDAP库。

  • 要使用基于SASL的LDAP身份验证:

    • LDAP服务器必须配置为与SASL服务器通信。

    • SASL客户端库必须在使用客户端 authentication_ldap_sasl_client 插件的系统上可用。当前,唯一支持的库是Cyrus SASL库。

    • 要使用特定的SASL身份验证方法,任何其他服务都必须可用。例如,要使用GSSAPI/Kerberos,GSSAPI库和Kerberos服务必须可用。

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 和密码作为凭据来查找用户 DN,基于客户端用户名,然后对该用户 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_simpleauthentication_ldap_sasl。文件名后缀因平台而异(例如,Unix 和 Unix-like 系统上的 .so,Windows 上的 .dll)。

Note

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

要在服务器启动时加载插件,请使用 --plugin-load-add 选项来指定包含它们的库文件。使用这种插件加载方法,每次服务器启动时都必须指定这些选项。此外,还需要指定要配置的任何插件提供的系统变量的值。

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

要加载插件并设置 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 语法 for 变量赋值”

要验证插件安装,请检查 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 可插拔身份验证

Additional Notes for SELinux

在启用 SELinux 的 EL6 或 EL 系统上,需要对 SELinux 策略进行更改,以便 MySQL LDAP 插件可以与 LDAP 服务通信:

  1. 创建一个名为 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;
  2. 将安全策略模块编译成二进制表示形式:

    checkmodule -M -m mysqlldap.te -o mysqlldap.mod
  3. 创建一个 SELinux 策略模块包:

    semodule_package -m mysqlldap.mod  -o mysqlldap.pp
  4. 安装模块包:

    semodule -i mysqlldap.pp
  5. 当 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 配置等:

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

设置 LDAP 可插拔身份验证超时

要使用 LDAP 可插拔身份验证连接到 MySQL 服务器,LDAP 服务器必须可用且运作正常。MySQL 服务器与 LDAP 服务器之间的交互涉及两个步骤。首先,MySQL 服务器与 LDAP 服务器建立 TCP 连接。其次,MySQL 服务器通过连接发送 LDAP 绑定请求,并等待 LDAP 服务器的响应,以便身份验证账户。如果这两个步骤中的任何一个失败,MySQL 账户将无法连接到 MySQL 服务器。

在 MySQL 8.1.0 之前,LDAP 可插拔身份验证依赖于主机操作系统的超时值,以确定等待连接和响应步骤完成的时间。具体来说,用户尝试连接 MySQL 可能会遇到以下情况:

  • 用户提供用户名和密码给 MySQL 客户端,然后 MySQL 客户端变得无响应。最终,客户端显示类似于以下错误消息:

    ERROR 1045 (28000): Access denied for user 'user_name' (using password: YES)

    该错误消息在 LDAP 可插拔身份验证的范围内通常表明 LDAP 服务器不可用,无法建立连接。该消息出现前的等待时间可能很长(在四分钟范围内)。

  • 用户提供用户名和密码给 MySQL 客户端,然后 MySQL 客户端变得无响应,且无限期地等待。在这种情况下,表明 LDAP 服务器响应了 LDAP 绑定请求。

从 MySQL 8.1.0 开始,默认情况下将应用短暂超时,以超越主机系统的超时值。这将在连接和响应步骤中应用。在所有情况下,如果超时到期,账户用户将收到连接 MySQL 被拒绝的通知。客户端和服务器端日志记录可以提供更多信息。在客户端上,设置以下环境变量以提高详细级别,然后重新启动 MySQL 客户端:

AUTHENTICATION_LDAP_CLIENT_LOG=5
export AUTHENTICATION_LDAP_CLIENT_LOG

以下系统变量支持 SASL 基础和简单 LDAP 身份验证的默认超时,在 Linux 平台上仅适用。

表 8.24 SASL 基础和简单 LDAP 身份验证的系统变量

System Variable Name Default Timeout Value
authentication_ldap_sasl_connect_timeout 30 秒
LDAP SASL 响应超时 30 秒
LDAP 简单连接超时 30 秒
LDAP 简单响应超时 30 秒

LDAP 身份验证超时值可以在服务器启动和运行时调整。如果您将超时设置为零,则 effectively 禁用它,MySQL 服务器将使用主机系统的默认超时。

Note

在以下组合条件下,LDAP SASL 连接超时设置的实际等待时间将加倍,因为(在内部)服务器必须两次调用 TCP 连接:

使用 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 消息来安全地传输凭证,以避免在 MySQL 客户端和服务器之间发送明文密码。

LDAP 身份验证 MySQL 用户的总体要求:

  • 每个用户都必须在 LDAP 目录中有一个条目。

  • 每个 MySQL 帐户都必须指定服务器端 LDAP 身份验证插件,并可选地命名关联的 LDAP 用户区分名称(DN)。(要将 LDAP 用户 DN 与 MySQL 帐户关联,请在创建帐户的 CREATE USER 语句中包含 BY 子句。如果帐户未命名 LDAP 字符串,LDAP 身份验证将使用客户端指定的用户名来查找 LDAP 条目。

  • 客户端程序使用适合服务器端身份验证插件的连接方法。对于 LDAP 身份验证,连接需要 MySQL 用户名和 LDAP 密码。此外,对于使用服务器端 authentication_ldap_simple 插件的帐户,客户端程序需要使用 --enable-cleartext-plugin 选项来启用客户端 mysql_clear_password 插件。

以下说明假设以下场景:

  • MySQL 用户 betsyboris 分别对应 LDAP 条目 betsy_ldapboris_ldap。(不需要 MySQL 和 LDAP 用户名不同。使用不同的名称在这里有助于澄清操作上下文是 MySQL 还是 LDAP。)

  • LDAP 条目使用 uid 属性指定用户名。这可能取决于 LDAP 服务器的一些 LDAP 服务器使用 cn 属性来指定用户名,而不是 uid。要更改属性,请修改 authentication_ldap_simple_user_search_attrauthentication_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 语句在 BY 子句中指定 LDAP 用户,以指示哪个 LDAP 条目 MySQL 帐户对应。

设置使用 LDAP 身份验证的帐户的说明取决于使用的服务器端 LDAP 插件。以下部分描述了几种使用场景。

简单 LDAP 身份验证

要配置 MySQL 帐户以进行简单 LDAP 身份验证,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

然后,创建 MySQL 帐户的语句 betsy 看起来像这样:

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

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

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

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

客户端 mysql_clear_password 身份验证插件将密码保持不变,因此客户端程序将其作为明文发送到 MySQL 服务器。这使得密码可以被传递给 LDAP 服务器,而不需要加密。但是,这可能会在某些配置中引发安全问题。这些措施可以减少风险:

身份验证过程如下:

  1. 客户端插件将 betsybetsy_password 作为客户用户名和 LDAP 密码发送到 MySQL 服务器。

  2. 连接尝试匹配 'betsy'@'localhost' 帐户。服务器端 LDAP 插件找到该帐户的身份验证字符串为 'uid=betsy_ldap,ou=People,dc=example,dc=com',以命名 LDAP 用户 DN。插件将该字符串和 LDAP 密码发送到 LDAP 服务器。

  3. LDAP 服务器找到 LDAP 条目 betsy_ldap,密码匹配,因此 LDAP 身份验证成功。

  4. LDAP 条目没有组属性,因此服务器端插件返回客户用户名 (betsy) 作为已验证用户。这与客户提供的用户名相同,因此不发生代理,并且客户会话使用 'betsy'@'localhost' 帐户进行权限检查。

如果匹配的 LDAP 条目包含组属性,那么该属性值将是已验证用户名称,并且如果该值不同于 betsy,则将发生代理。有关使用组属性的示例,请参阅 LDAP 身份验证 with 代理

如果 CREATE USER 语句不包含指定 betsy_ldap LDAP 区分名称的 BY 子句,那么身份验证尝试将使用客户端提供的用户名(在这种情况下为 betsy)。在缺少 betsy LDAP 条目的情况下,身份验证将失败。

SASL 基于 LDAP 的身份验证

要配置 MySQL 帐户以使用 SASL LDAP 身份验证,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

然后,创建 MySQL 帐户的语句 boris 看起来像这样:

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

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

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

$> 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 消息来安全地传输凭证,而不是在 MySQL 客户端和服务器之间发送明文密码。

LDAP 身份验证代理

LDAP 身份验证插件支持代理,允许用户以一个用户身份连接到 MySQL 服务器,但假设另一个用户的权限。这一节描述基本的 LDAP 插件代理支持。LDAP 插件还支持组首选项和代理用户映射规格;请参阅 LDAP 身份验证组首选项和映射规格

这里描述的代理实现基于使用 LDAP 组属性值将连接到 MySQL 服务器的用户映射到其他 MySQL 帐户,这些帐户定义了不同的权限集。用户不直接连接到定义权限的帐户,而是通过默认的代理帐户连接,所有外部登录都映射到代理的 MySQL 帐户,权限确定了外部用户允许的数据库操作。

以下说明假设以下场景:

  • LDAP 条目使用 uidcn 属性指定用户名和组值。要使用不同的用户和组属性名称,请设置相应的插件特定系统变量:

  • 这些 LDAP 条目在 LDAP 服务器管理的目录中可用,以提供唯一标识每个用户的区分名称值:

    uid=basha,ou=People,dc=example,dc=com,cn=accounting
    uid=basil,ou=People,dc=example,dc=com,cn=front_office

    在连接时,组属性值变为身份验证用户名,因此它们命名了 accountingfront_office 代理帐户。

  • 这些示例假设使用 SASL LDAP 身份验证。对于简单 LDAP 身份验证,请进行相应的调整。

创建默认的代理 MySQL 帐户:

CREATE USER ''@'%'
  IDENTIFIED WITH authentication_ldap_sasl;

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

  • 当客户端连接时,客户端用户名变为 LDAP 用户名以供搜索。

  • 匹配的 LDAP 条目期望包括一个组属性,命名代理的 MySQL 账户,该账户定义了客户端应该拥有的权限。

Note

如果您的 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.9 节,“无登录可插拔认证”。)有关保护代理账户免受直接使用的替代方法,请参阅 防止代理账户直接登录

授予代理账户 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)

身份验证过程如下:

  1. 服务器使用默认 ''@'%' 代理账户对客户端用户 basha 进行身份验证。

  2. 匹配的 LDAP 条目是:

    uid=basha,ou=People,dc=example,dc=com,cn=accounting
  3. 匹配的 LDAP 条目具有组属性 cn=accounting,因此 accounting 成为认证的代理用户。

  4. 认证用户与客户端用户名 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 相似:

  1. 服务器使用默认 ''@'%' 代理账户对客户端用户 basil 进行身份验证。

  2. 匹配的 LDAP 条目是:

    uid=basil,ou=People,dc=example,dc=com,cn=front_office
  3. 匹配的 LDAP 条目具有组属性 cn=front_office,因此 front_office 成为认证的代理用户。

  4. 认证用户与客户端用户名 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 服务器返回多个组名,或者指定其他名称作为代理用户名称。

对于使用 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 属性构建。

身份验证字符串的剩余部分以 # 开头,表示组首选项和映射信息的开始。这部分身份验证字符串列出了组名,以 grp1grp2grp3 的顺序。LDAP 插件将该列表与 LDAP 服务器返回的组名集进行比较,按照列表顺序查找匹配的组名。插件使用第一个匹配项,如果没有匹配项,身份验证将失败。

假设 LDAP 服务器返回组 grp3grp2grp7。LDAP 插件使用 grp2,因为它是身份验证字符串中第一个匹配的组名,尽管它不是 LDAP 服务器返回的第一个组名。如果 LDAP 服务器返回 grp4grp2grp1,插件使用 grp1,因为它在身份验证字符串中的优先级高于 grp2

假设插件找到组名匹配项,它将执行从该组名到 MySQL 代理用户名的映射,如果存在。

  • 例如,对于代理账户,如果匹配的组名是 grp1grp3,它们在身份验证字符串中分别关联用户名 userauserc。插件使用相应关联的用户名作为代理用户名。

  • 如果匹配的组名是 grp2,身份验证字符串中没有关联的用户名。插件使用 grp2 作为代理用户名。

如果 LDAP 服务器返回组 DN,LDAP 插件将解析组 DN 以提取组名。

要指定 LDAP 组首选项和映射信息,以下原则适用:

  • # 前缀字符开始组首选项和映射部分。

  • 组首选项和映射规范是一个或多个项目的列表,以逗号分隔。每个项目的形式为 group_name=user_namegroup_name。项目应按照组名首选项顺序列出。对于插件从 LDAP 服务器返回的组名集中选择的组名,两种语法的效果如下:

    • 对于指定为 group_name=user_name 的项目(带有用户名),组名映射到用户名,该用户名用作 MySQL 代理用户名。

    • 对于指定为 group_name 的项目(无用户名),组名用作 MySQL 代理用户名。

  • 要引用包含特殊字符(如空格)的组或用户名,使用双引号 (") 字符将其括起来。例如,如果项目的组和用户名分别为 my group namemy user name,则必须在组映射中使用引号:

    "my group name"="my user name"

    如果项目的组和用户名分别为 my_group_namemy_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 中,客户端用户名将成为指定 LDAP 用户名的属性值。这默认为 uid;要更改该属性,请修改适当的系统变量(authentication_ldap_simple_user_search_attrauthentication_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 认证方法

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

请参阅系统变量描述以获取每个允许方法的信息。此外,根据方法,可能需要额外的配置,如下一节所述。

GSSAPI/Kerberos 认证方法

通用安全服务应用程序接口(GSSAPI)是一个安全抽象接口。Kerberos 是一个特定的安全协议,可以通过该抽象接口使用。使用 GSSAPI,应用程序可以认证到 Kerberos,以获取服务凭证,然后使用这些凭证来启用安全访问其他服务。

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

GSSAPI/Kerberos支持作为MySQL服务器和客户端的LDAP身份验证方法,在Linux环境中非常有用,其中应用程序可以通过Microsoft Active Directory访问LDAP,该目录默认启用了Kerberos。

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

  • 主体:一个命名的实体,例如用户或服务器。

  • KDC:密钥分发中心,由AS和TGS组成:

    • AS:身份验证服务器;提供初始票据授予票据,以获取其他票据。

    • TGS:票据授予服务器;为Kerberos客户端提供其他票据,以访问服务。

  • TGT:票据授予票据;呈现给TGS,以获取服务票据以访问服务。

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

  • Active Directory包括这两个服务器,默认情况下在Active Directory LDAP服务器中启用了Kerberos身份验证。

  • OpenLDAP提供了LDAP服务器,但可能需要单独的KDC服务器,并需要额外的Kerberos设置。

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

以下部分讨论了使用GSSAPI/Kerberos进行SASL LDAP身份验证的配置步骤:

Verify Kerberos and LDAP Availability

以下示例显示了如何在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账户相关联。)

满足这些假设后,按照以下步骤操作:

  1. 验证Kerberos库是否正确安装和配置在操作系统中。例如,要配置MYSQL.LOCAL域以便在MySQL身份验证期间使用,/etc/krb5.conf Kerberos配置文件应包含类似以下内容:

    [realms]
      MYSQL.LOCAL = {
        kdc = ldap_auth.example.com
        admin_server = ldap_auth.example.com
        default_domain = MYSQL.LOCAL
      }
  2. 你可能需要在/etc/hosts中添加服务器主机的条目:

    198.51.100.10 ldap_auth ldap_auth.example.com
  3. 检查Kerberos身份验证是否正确工作:

    1. 使用kinit身份验证到Kerberos:

      $> kinit bredon@MYSQL.LOCAL
      Password for bredon@MYSQL.LOCAL: (enter password here)

      该命令对 Kerberos 主体名为 bredon@MYSQL.LOCAL 进行身份验证。当命令提示输入密码时,输入主体的密码。KDC 将返回一个 TGT,该 TGT 将被缓存在客户端上,以便其他 Kerberos 感知应用程序使用。

    2. 使用 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
  4. 检查 ldapsearch 是否使用 Kerberos TGT 工作,使用以下命令,该命令在 MYSQL.LOCAL 域中搜索用户:

    ldapsearch -h 198.51.100.10 -Y GSSAPI -b "dc=MYSQL,dc=LOCAL"
Configure the Server-Side SASL LDAP Authentication Plugin for 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 插件配置为:

Create a MySQL Account That Uses GSSAPI/Kerberos for LDAP Authentication

使用 SASL LDAP 身份验证插件和 GSSAPI/Kerberos 方法的 MySQL 身份验证基于 Kerberos 主体用户。以下讨论使用名为 bredon@MYSQL.LOCAL 的主体用户,该用户必须在多个地方注册:

  • Kerberos 管理员应该将用户名注册为 Kerberos 主体。该名称应该包括域名。客户端使用主体名称和密码来与 Kerberos 进行身份验证并获取 TGT。

  • LDAP 管理员应该将用户名注册到 LDAP 条目中。例如:

    uid=bredon,dc=MYSQL,dc=LOCAL
    Note

    在 Active Directory 中(默认情况下使用 Kerberos 作为身份验证方法),创建用户将同时创建 Kerberos 主体和 LDAP 条目。

  • MySQL DBA 应该创建一个帐户,该帐户的用户名是 Kerberos 主体名称,并使用 SASL LDAP 插件进行身份验证。

假设 Kerberos 主体和 LDAP 条目已经由适当的服务管理员注册,并且按照之前在 安装 LDAP 可插拔身份验证配置服务器端 SASL LDAP 身份验证插件以用于 GSSAPI/Kerberos 中所述,MySQL 服务器已经使用适当的配置设置启动了服务器端 SASL LDAP 插件。然后,MySQL DBA 创建了一个对应于 Kerberos 主体名称的 MySQL 帐户,包括域名。

Note

SASL LDAP 插件使用恒定的用户 DN 进行 Kerberos 身份验证,并忽略了从 MySQL 配置的用户 DN。这有一些隐含的影响:

  • 对于任何使用 GSSAPI/Kerberos 身份验证的 MySQL 帐户,CREATE USERALTER USER 语句中的身份验证字符串不应包含用户 DN,因为它没有效果。

  • 因为身份验证字符串不包含用户 DN,因此它应该包含组映射信息,以便用户可以作为代理用户被映射到所需的代理用户。有关 LDAP 身份验证插件的代理信息,请参阅 LDAP 身份验证与代理

以下语句创建了一个名为 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'@'%'

Note

当创建使用 authentication_ldap_sasl SASL LDAP 身份验证插件的 GSSAPI/Kerberos 身份验证方法的帐户时,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 节,“无登录可插拔身份验证”。) 有关保护代理帐户免受直接使用的替代方法,请参阅 防止代理帐户的直接登录

Use the MySQL Account to Connect to the MySQL Server

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

  • 在调用 MySQL 客户端程序之前,客户端用户可以独立于 MySQL 获取 TGT 从 KDC。例如,客户端用户可以使用 kinit 通过提供 Kerberos 主体名称和主体密码来对 Kerberos 进行身份验证:

    $> kinit bredon@MYSQL.LOCAL
    Password for bredon@MYSQL.LOCAL: (enter password here)

    结果TGT被缓存并可供其他Kerberos-aware应用程序使用,例如使用客户端SASL LDAP身份验证插件的程序。在这种情况下,MySQL客户端程序使用TGT对MySQL服务器进行身份验证,因此可以在不指定用户名或密码的情况下调用客户端:

    mysql --default-auth=authentication_ldap_sasl_client

    正如刚才描述的那样,当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 来检查。

身份验证按照以下方式进行:

  1. 客户端使用TGT进行Kerberos身份验证。

  2. 服务器找到LDAP条目中的主体,并使用它来身份验证连接到 bredon@MYSQL.LOCAL MySQL代理帐户。

  3. 代理帐户身份验证字符串中的组映射信息('#krb_grp=proxied_krb_user')指示已身份验证的代理用户应为 proxied_krb_user

  4. 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,客户端插件都使用它来获取服务票据并与服务器端插件通信。

Note

当客户端插件本身获取TGT时,客户端用户可能不想重用TGT。如 Client Configuration Parameters for LDAP Authentication 所述,local /etc/krb5.conf 文件可以用于使客户端插件在完成后销毁TGT。

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

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

Client Configuration Parameters for LDAP Authentication

authentication_ldap_sasl_client 客户端SASL LDAP插件读取local /etc/krb5.conf 文件。如果该文件不存在或不可访问,将发生错误。假设该文件可访问,可以在 mysql 部分的可选 [appdefaults] 部分中提供信息供插件使用。例如:

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

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

  • ldap_server_host 值指定LDAP服务器主机,可以在LDAP服务器主机与KDC服务器主机不同时使用。默认情况下,插件使用KDC服务器主机作为LDAP服务器主机。

  • ldap_destroy_tgt 值指示客户端插件是否在获取和使用 TGT 后销毁它。默认情况下,ldap_destroy_tgtfalse,但可以设置为 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 重定向的一个问题是,搜索可能会因 LDAP 操作错误而失败,当搜索基 DN 是根 DN 时,并且重定向对象未设置。MySQL DBA 可能希望避免这些重定向错误,以便 LDAP 身份验证插件,即使 LDAP 重定向在 ldap.conf 配置文件中全局设置。要在插件特定基础上配置 LDAP 服务器是否在与每个插件通信时使用 LDAP 重定向,设置 authentication_ldap_simple_referralauthentication_ldap_sasl_referral 系统变量。将任一变量设置为 ONOFF 将导致相应的 LDAP 身份验证插件告诉 LDAP 服务器在 MySQL 身份验证期间是否使用重定向。每个变量都具有插件特定的效果,不会影响其他与 LDAP 服务器通信的应用程序。两个变量默认情况下都是 OFF