文档首页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


MySQL 8.4 参考手册  /  ...  /  LDAP 可插拔身份验证

8.4.1.7 LDAP 可插拔身份验证

注意

LDAP 可插拔身份验证是 MySQL 企业版(一种商业产品)中包含的扩展。要详细了解商业产品,请参阅 https://www.mysqlserver.cn/products/

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

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

  • 外部身份验证:LDAP 身份验证使 MySQL 服务器能够接受来自 LDAP 目录中 MySQL 授权表外部定义的用户的连接。

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

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

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

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

表 8.21 用于简单 LDAP 身份验证的插件和库名

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

表 8.22 用于基于 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 可插拔身份验证的安装和使用信息。

有关 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 可插拔身份验证的先决条件

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

  • 必须有一个 LDAP 服务器可供 LDAP 身份验证插件与其通信。

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

  • 在使用服务器端 authentication_ldap_saslauthentication_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_simpleauthentication_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。请参阅第 15.7.6.1 节“SET 语法用于变量赋值”

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

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 中的以下参数:

有关 ldap.conf 的更多信息,请参阅 ldap.conf(5) 联机帮助页。

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

为了使 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 身份验证的默认超时。

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


LDAP 身份验证的超时值可以在服务器启动时和运行时进行调整。如果使用其中一个变量将超时设置为零,则实际上将禁用它,并且 MySQL 服务器将恢复为使用主机系统的默认超时。

注意

在以下条件组合下,authentication_ldap_sasl_connect_timeout 设置的实际等待时间会翻倍,因为(在内部)服务器必须调用 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 消息在 LDAP 协议中安全传输凭据,以避免在 MySQL 客户端和服务器之间发送明文密码。

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

  • 对于要进行身份验证的每个用户,都必须有一个 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 用户 betsyboris 分别对 betsy_ldapboris_ldap 的 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
  • 创建 MySQL 帐户的 CREATE USER 语句在 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_clear_password 插件来连接到 MySQL 服务器:

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

客户端 mysql_clear_password 身份验证插件会保留密码不变,因此客户端程序会将其作为明文发送到 MySQL 服务器。这使得密码可以按原样传递到 LDAP 服务器。要在没有 SASL 的情况下使用服务器端 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 服务器找到了 betsy_ldap 的 LDAP 条目,并且密码匹配,因此 LDAP 身份验证成功。

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

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

如果 CREATE USER 语句不包含指定 betsy_ldap LDAP 可分辨名称的 BY 子句,则身份验证尝试将使用客户端提供的用户名(在本例中为 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 条目使用 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 帐户。

注意

如果您的 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 命令行客户端以 basha 的身份连接到 MySQL 服务器。

$> 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,则即使 grp2 也匹配,插件也会使用 grp1grp1 的优先级高于 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 值。在构造的 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 组。

Linux 上的 MySQL 服务器和客户端支持 GSSAPI/Kerberos 作为 LDAP 身份验证方法。这在应用程序可以通过 Microsoft Active Directory(默认情况下启用了 Kerberos)访问 LDAP 的 Linux 环境中很有用。

以下讨论提供了有关使用 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 的可用性

以下示例显示如何测试 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 帐户相关联。)

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

  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 [email protected]
      Password for [email protected]: (enter password here)

      该命令为名为 [email protected] 的 Kerberos 主体进行身份验证。当命令提示输入主体密码时,请输入该密码。KDC 返回一个 TGT,该 TGT 缓存在客户端,供其他支持 Kerberos 的应用程序使用。

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

    ldapsearch -h 198.51.100.10 -Y GSSAPI -b "dc=MYSQL,dc=LOCAL"
为 GSSAPI/Kerberos 配置服务器端 SASL LDAP 身份验证插件

假设可以通过 Kerberos 访问 LDAP 服务器,如上所述,请将服务器端 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 插件:

创建一个使用 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 USERALTER 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 语句将领域作为用户名的一部分。这与创建使用 authentication_kerberos Kerberos 插件的帐户不同。对于此类帐户,CREATE USER 语句不包括作为用户名一部分的领域。相反,在 BY 子句中将领域指定为身份验证字符串。请参阅 创建一个使用 Kerberos 身份验证的 MySQL 帐户

被代理帐户使用 mysql_no_login 身份验证插件来防止客户端使用该帐户直接登录到 MySQL 服务器。相反,预计使用 LDAP 进行身份验证的用户将使用 [email protected] 代理帐户。(这假定已安装 mysql_no_login 插件。有关说明,请参阅 第 8.4.1.9 节“无登录可插拔身份验证”。)有关防止被代理帐户被直接使用的替代方法,请参阅 防止直接登录到被代理帐户

使用 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 进行检查。

身份验证过程如下

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

  2. 服务器找到该主体的 LDAP 条目,并使用它对 [email protected] MySQL 代理帐户的连接进行身份验证。

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

  4. [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 本身或用于获取 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 后是否销毁它。默认情况下,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 引用时的一个问题是,当搜索基础 DN 为根 DN 并且未设置引用对象时,搜索可能会失败并出现 LDAP 操作错误。MySQL DBA 可能希望避免 LDAP 身份验证插件出现此类引用错误,即使 LDAP 引用可能已在 ldap.conf 配置文件中全局设置。要针对每个插件配置 LDAP 服务器在与每个插件通信时是否应使用 LDAP 引用,请设置 authentication_ldap_simple_referralauthentication_ldap_sasl_referral 系统变量。将任一变量设置为 ONOFF 会导致相应的 LDAP 身份验证插件告诉 LDAP 服务器在 MySQL 身份验证期间是否使用引用。每个变量都有特定于插件的效果,不会影响与 LDAP 服务器通信的其他应用程序。默认情况下,这两个变量都为 OFF