PAM 可插拔身份验证是 MySQL Enterprise Edition 的一部分,一个商业产品。要了解更多关于商业产品的信息,请参阅 https://www.mysql.com/products/。
MySQL Enterprise Edition 支持一种身份验证方法,允许 MySQL Server 使用 PAM(可插拔身份验证模块)来身份验证 MySQL 用户。PAM 启用系统使用标准接口访问各种身份验证方法,如传统 Unix 密码或 LDAP 目录。
PAM 可插拔身份验证提供以下功能:
-
外部身份验证:PAM 身份验证使 MySQL Server 能够接受来自外部定义的用户的连接,这些用户使用 PAM 支持的方法进行身份验证。
-
代理用户支持:PAM 身份验证可以根据外部用户所属的 PAM 组和提供的身份验证字符串,返回到 MySQL 的用户名不同于客户端程序传递的外部用户名。这意味着插件可以返回 MySQL 用户,该用户定义了外部 PAM 身份验证用户应有的权限。例如,操作系统用户
joe可以连接并拥有 MySQL 用户developer的权限。
PAM 可插拔身份验证已经在 Linux 和 macOS 上进行了测试;注意 Windows 不支持 PAM。
以下表格显示了插件和库文件名。文件名后缀可能在您的系统上不同。文件必须位于由 plugin_dir 系统变量命名的目录中。有关安装信息,请参阅 安装 PAM 可插拔身份验证。
表 8.20 PAM 身份验证插件和库文件名
| Plugin or File | Plugin or File Name |
|---|---|
| 服务器端插件 | authentication_pam |
| 客户端插件 | mysql_clear_password |
| 库文件 | authentication_pam.so |
客户端 mysql_clear_password 明文插件与服务器端 PAM 插件通信,已经构建到 libmysqlclient 客户端库中,并包含在所有发行版中,包括社区发行版。这使得来自任何发行版的客户端都可以连接到加载了服务器端 PAM 插件的服务器。
以下部分提供了 PAM 可插拔身份验证的安装和使用信息:
关于 MySQL 中的可插拔身份验证的常规信息,请参阅 第 8.2.17 节,“可插拔身份验证”。关于 mysql_clear_password 插件的信息,请参阅 第 8.4.1.4 节,“客户端明文可插拔身份验证”。关于代理用户信息,请参阅 第 8.2.19 节,“代理用户”。
本节概述了 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 密码,组是 Unix 组,定义在
/etc/group文件中,可能补充了附加的 PAM 信息在文件中,例如/etc/security/group.conf。 -
对于 LDAP,组是 LDAP 组,定义在 LDAP 目录中。
如果代理用户(外部用户)拥有
PROXY权限的代理 MySQL 用户名,则发生代理,代理用户将获得代理用户的权限。 -
本节描述了如何安装服务器端 PAM 身份验证插件。有关安装插件的一般信息,请参阅 第 7.6.1 节,“安装和卸载插件”。
要使插件可供服务器使用,插件库文件必须位于 MySQL 插件目录中(由 plugin_dir 系统变量命名的目录)。如果必要,请在服务器启动时设置 plugin_dir 的值。
插件库文件的基本名称是 authentication_pam,通常以 .so 后缀编译。
要在服务器启动时加载插件,请使用 --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 选项。
要验证插件安装,请检查 Information Schema PLUGINS 表或使用 SHOW PLUGINS 语句(见 第 7.6.2 节,“获取服务器插件信息”)。例如:
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE '%pam%';
+--------------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+--------------------+---------------+
| authentication_pam | ACTIVE |
+--------------------+---------------+
如果插件无法初始化,请检查服务器错误日志以获取诊断信息。
要将 MySQL 帐户与 PAM 插件关联,请参阅 使用 PAM 可插拔身份验证。
卸载 PAM 身份验证插件的方法取决于您安装它的方式:
-
如果您使用
--plugin-load-add选项在服务器启动时安装插件,只需重新启动服务器而不使用该选项。 -
如果您使用
INSTALL PLUGIN语句在运行时安装插件,它将在服务器重新启动时保持安装。要卸载它,请使用UNINSTALL PLUGIN:UNINSTALL PLUGIN authentication_pam;
本节描述了如何使用 PAM 身份验证插件从 MySQL 客户端程序连接到服务器。以下部分提供了使用 PAM 身份验证的特定指令。假设服务器正在运行启用了服务器端 PAM 插件,如 安装 PAM 可插拔身份验证 中所述。
要在 IDENTIFIED WITH 子句中引用 PAM 身份验证插件,请使用名称 authentication_pam。例如:
CREATE USER user
IDENTIFIED WITH authentication_pam
AS 'auth_string';
身份验证字符串指定以下类型的信息:
-
PAM 服务名称(见 PAM 身份验证 MySQL 用户的工作方式)。以下讨论中的示例使用服务名称
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 组名称和 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 组映射列表,插件将从左到右检查每个
对,并尝试在非 MySQL 目录中查找外部用户所属的组,返回第一个匹配的pam_group_name=mysql_user_namemysql_user_name。如果插件找不到任何 PAM 组的匹配项,将返回外部名称。如果插件无法在目录中查找组,将忽略 PAM 组映射列表并返回外部名称。
以下部分描述了使用 PAM 身份验证插件设置多个身份验证场景:
-
不使用代理用户。这使用 PAM 仅检查登录名和密码。每个外部用户都需要有一个匹配的 MySQL 帐户,该帐户定义为使用 PAM 身份验证。(对于 MySQL 帐户
'来匹配外部用户,user_name'@'host_name'user_name必须是外部用户名,host_name必须与客户端连接的主机匹配。)身份验证可以通过各种 PAM 支持的方法进行。后续讨论将展示如何使用传统 Unix 密码和 LDAP 密码进行客户端身份验证。PAM 身份验证(不通过代理用户或 PAM 组)需要 MySQL 用户名与操作系统用户名相同。MySQL 用户名最多 32 个字符(见 第 8.2.3 节,“Grant Tables”),这限制了 PAM 非代理身份验证只能用于 Unix 帐户名称最多 32 个字符。
-
仅使用代理用户,带有 PAM 组映射。对于这种场景,创建一个或多个 MySQL 帐户,定义不同的权限集。(理想情况下,没人应该直接连接这些帐户。)然后,定义一个默认用户通过 PAM 身份验证,使用某种映射方案(通常基于外部用户所属的 PAM 组)将所有外部用户名映射到少数 MySQL 帐户中。任何客户端连接并指定外部用户名作为客户端用户名,将被映射到一个 MySQL 帐户并使用其权限。讨论将展示如何使用传统 Unix 密码设置这种场景,但其他 PAM 方法如 LDAP 也可以使用。
这些场景的变体是可能的:
-
您可以允许一些用户直接登录(不使用代理)但要求其他用户连接到代理帐户。
-
您可以使用不同的 PAM 身份验证方法 для不同的用户,通过使用不同的 PAM 服务名称在 PAM-authenticated 帐户中。例如,您可以使用
mysql-unixPAM 服务 для一些用户,而使用mysql-ldapдля其他用户。
示例假设了以下内容。您可能需要根据您的系统设置进行调整。
-
登录名和密码分别是
antonio和antonio_password。请将其更改为您要身份验证的用户。 -
PAM 配置目录是
/etc/pam.d。 -
PAM 服务名称对应于身份验证方法(
mysql-unix或mysql-ldap在本讨论中)。要使用给定的 PAM 服务,您必须在 PAM 配置目录中设置一个同名的 PAM 文件(如果不存在则创建文件)。此外,您必须在CREATE USER语句的身份验证字符串中命名 PAM 服务,以便任何使用该 PAM 服务进行身份验证的帐户。
PAM 身份验证插件在初始化时检查服务器启动环境中的 AUTHENTICATION_PAM_LOG 环境值是否设置。如果是这样,插件将启用标准输出的诊断消息记录。根据服务器的启动方式,消息可能出现在控制台或错误日志中。这些消息可以帮助调试 PAM 相关问题,当插件执行身份验证时出现问题。有关更多信息,请参阅 PAM 身份验证调试。
这种身份验证场景使用 PAM 来检查外部用户,定义为操作系统用户名和 Unix 密码,无代理。每个外部用户都需要连接到 MySQL 服务器,应该有一个匹配的 MySQL 帐户,定义为使用 PAM 身份验证通过传统 Unix 密码存储。
传统 Unix 密码使用 /etc/shadow 文件进行检查。有关该文件可能出现的问题,请参阅 PAM 身份验证访问 Unix 密码存储。
-
验证 Unix 身份验证是否允许使用用户名
antonio和密码antonio_password登录操作系统。 -
设置 PAM 以使用传统 Unix 密码来身份验证 MySQL 连接,创建一个名为
/etc/pam.d/mysql-unix的mysql-unixPAM 服务文件。该文件的内容取决于系统,因此请检查/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-unixPAM 服务进行身份验证:CREATE USER 'antonio'@'localhost' IDENTIFIED WITH authentication_pam AS 'mysql-unix'; GRANT ALL PRIVILEGES ON mydb.* TO 'antonio'@'localhost';这里,身份验证字符串仅包含 PAM 服务名称
mysql-unix,它身份验证 Unix 密码。 -
使用 mysql 命令行客户端连接到 MySQL 服务器作为
antonio。例如:$> 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被身份验证为拥有antonioMySQL 用户的权限,并且没有发生代理。
客户端 mysql_clear_password 身份验证插件将密码保持不变,因此客户端程序将其作为明文发送到 MySQL 服务器。这使得密码可以被 PAM 库作为明文传递。但是,这可能在某些配置中引发安全问题。这些措施可以减少风险:
-
为了使
mysql_clear_password插件的意外使用可能性降低,MySQL 客户端必须明确启用它(例如,使用--enable-cleartext-plugin选项)。请参阅 第 8.4.1.4 节,“客户端明文插件身份验证”。 -
为了避免使用
mysql_clear_password插件时的密码暴露,MySQL 客户端应该使用加密连接连接到 MySQL 服务器。请参阅 第 8.3.1 节,“配置 MySQL 使用加密连接”。
此身份验证方案使用 PAM 检查外部用户,定义为操作系统用户名和 LDAP 密码,无需代理。每个外部用户都需要有一个匹配的 MySQL 帐户,该帐户定义为使用 PAM 身份验证通过 LDAP。
要使用 PAM LDAP 可插拔身份验证 для MySQL,必须满足以下条件:
-
LDAP 服务器必须可用,以便 PAM LDAP 服务可以与其通信。
-
每个 LDAP 用户都必须在 LDAP 服务器管理的目录中存在,以便 MySQL 进行身份验证。
另一种使用 LDAP 进行 MySQL 用户身份验证的方法是使用 LDAP 特定的身份验证插件。见 第 8.4.1.7 节,“LDAP 可插拔身份验证”。
按照以下步骤配置 MySQL 以使用 PAM LDAP 身份验证:
-
验证 Unix 身份验证是否允许使用用户名
antonio和密码antonio_password登录操作系统。 -
通过创建名为
/etc/pam.d/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-ldapPAM 服务进行身份验证: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 组映射将连接到 MySQL 的外部用户映射到其他 MySQL 帐户,这些帐户定义了不同的权限集。用户不直接通过定义权限的帐户连接,而是通过一个默认的代理帐户连接,该帐户使用 PAM 进行身份验证,以便所有外部用户都映射到定义权限的 MySQL 帐户中。
这里的过程使用 Unix 密码身份验证。要使用 LDAP,请参阅 PAM LDAP 身份验证无代理用户 的早期步骤。
传统的 Unix 密码使用 /etc/shadow 文件进行检查。有关该文件相关问题的信息,请参阅 PAM 身份验证访问 Unix 密码存储。
-
验证 Unix 身份验证是否允许使用用户名
antonio和密码antonio_password登录操作系统。 -
验证
antonio是否是root或usersPAM 组的成员。 -
设置 PAM 以便使用操作系统用户身份验证
mysql-unixPAM 服务,通过创建名为/etc/pam.d/mysql-unix的文件。该文件的内容取决于系统,因此请检查/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和usersPAM 组中映射到developer和data_entryMySQL 用户名中,分别。按照PAM服务名称设置代理用户时,需要PAM组映射列表。否则,插件无法确定如何将外部用户名映射到正确的代理MySQL用户名。
Note如果您的MySQL安装有匿名用户,它们可能与默认代理用户冲突。有关此问题的更多信息,以及解决方法,请参阅默认代理用户和匿名用户冲突。
-
创建代理账户并授予每个账户相应的权限:
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身份验证的用户预计使用developer或data_entry账户通过代理,基于其PAM组。(假设插件已安装。有关说明,请参阅第8.4.1.9节,“无登录可插拔身份验证”。)有关保护代理账户免受直接使用的替代方法,请参阅防止代理账户直接登录。 -
授予代理账户
PROXY权限,以便每个代理账户:GRANT PROXY ON 'developer'@'localhost' TO ''@''; GRANT PROXY ON 'data_entry'@'localhost' TO ''@''; -
使用mysql命令行客户端连接到MySQL服务器作为
antonio。$> mysql --user=antonio --password --enable-cleartext-plugin Enter password: antonio_password服务器使用默认的
''@''代理账户进行身份验证。结果权限取决于antonio所属的PAM组。如果antonio是rootPAM组的成员,则PAM插件将root映射到developerMySQL用户名,并将该名称返回给服务器。服务器验证''@''是否具有PROXY权限的developer,并允许连接。以下查询返回输出,如下所示:mysql> SELECT USER(), CURRENT_USER(), @@proxy_user; +-------------------+---------------------+--------------+ | USER() | CURRENT_USER() | @@proxy_user | +-------------------+---------------------+--------------+ | antonio@localhost | developer@localhost | ''@'' | +-------------------+---------------------+--------------+这表明
antonio操作系统用户被身份验证为拥有developerMySQL用户的权限,并且代理发生通过默认代理账户。如果
antonio不是rootPAM组的成员,但是usersPAM组的成员,则类似的过程将发生,但插件将userPAM组成员映射到data_entryMySQL用户名,并将该名称返回给服务器:mysql> SELECT USER(), CURRENT_USER(), @@proxy_user; +-------------------+----------------------+--------------+ | USER() | CURRENT_USER() | @@proxy_user | +-------------------+----------------------+--------------+ | antonio@localhost | data_entry@localhost | ''@'' | +-------------------+----------------------+--------------+这表明
antonio操作系统用户被身份验证为拥有data_entryMySQL用户的权限,并且代理发生通过默认代理账户。
客户端mysql_clear_password身份验证插件将密码保持不变,因此客户端程序将其发送到MySQL服务器作为明文。这使得密码可以被PAM库使用,但可能在某些配置中引发安全问题。这些措施可以减少风险:
-
为了使
mysql_clear_password插件的意外使用可能性降低,MySQL客户端必须明确启用它(例如,使用--enable-cleartext-plugin选项)。请参阅第8.4.1.4节,“客户端明文可插拔身份验证”。 -
为了避免使用
mysql_clear_password插件时的密码暴露,MySQL客户端应该使用加密连接连接到MySQL服务器。请参阅第8.3.1节,“配置MySQL使用加密连接”。
在某些系统中,Unix 认证使用密码存储,如 /etc/shadow,该文件通常具有受限的访问权限。这可能会导致 MySQL 基于 PAM 的认证失败。不幸的是,PAM 实现不允许区分 “密码无法检查”(例如,无法读取 /etc/shadow)和 “密码不匹配。” 如果您使用 Unix 密码存储进行 PAM 认证,可能可以使用以下方法之一启用对其的访问:
-
假设 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 认证插件在初始化时检查环境值 AUTHENTICATION_PAM_LOG 是否设置。如果设置了该值,插件将启用标准输出的诊断消息记录。这些消息可能有助于调试 PAM 相关问题,该问题发生在插件执行认证时。
设置 AUTHENTICATION_PAM_LOG=1(或其他任意值)不会包含任何密码。如果您想在这些消息中包含密码,请设置 AUTHENTICATION_PAM_LOG=PAM_LOG_WITH_SECRET_INFO。
一些消息包括对 PAM 插件源文件和行号的引用,这使插件操作能够更紧密地与代码中的位置相关。
另一种调试连接失败和确定连接尝试期间发生的情况的技术是配置 PAM 认证以允许所有连接,然后检查系统日志文件。这种技术应该仅在临时 basis 上使用,而不是在生产服务器上。
配置一个名为 /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 服务文件以禁用任何密码访问。