PAM 可插拔身份验证是 MySQL 企业版(商业产品)中包含的扩展。要了解有关商业产品的更多信息,请参见 https://www.mysqlserver.cn/products/.
MySQL 企业版支持一种身份验证方法,该方法使 MySQL 服务器能够使用 PAM(可插拔身份验证模块)来验证 MySQL 用户。PAM 使系统能够使用标准接口来访问各种身份验证方法,例如传统的 Unix 密码或 LDAP 目录。
PAM 可插拔身份验证提供以下功能
外部身份验证:PAM 身份验证使 MySQL 服务器能够接受来自在 MySQL 授权表之外定义的用户连接,这些用户使用 PAM 支持的方法进行身份验证。
代理用户支持:PAM 身份验证可以根据外部用户所属的 PAM 组以及提供的身份验证字符串,将与客户端程序传递的外部用户名不同的用户名返回给 MySQL。这意味着插件可以返回定义外部 PAM 身份验证用户应拥有的特权的 MySQL 用户。例如,操作系统用户名为
joe
可以连接并拥有名为developer
的 MySQL 用户的特权。
PAM 可插拔身份验证已在 Linux 和 macOS 上进行测试;请注意,Windows 不支持 PAM。
下表显示了插件和库文件名。文件名后缀可能在您的系统上有所不同。该文件必须位于由 plugin_dir
系统变量命名的目录中。有关安装信息,请参见 安装 PAM 可插拔身份验证。
表 8.18 PAM 身份验证的插件和库名称
插件或文件 | 插件或文件名 |
---|---|
服务器端插件 | authentication_pam |
客户端插件 | mysql_clear_password |
库文件 | authentication_pam.so |
与服务器端 PAM 插件通信的客户端 mysql_clear_password
明文插件内置于 libmysqlclient
客户端库中,并包含在所有发行版中,包括社区发行版。客户端明文插件包含在所有 MySQL 发行版中,使来自任何发行版的客户端能够连接到已加载服务器端 PAM 插件的服务器。
以下部分提供了特定于 PAM 可插拔身份验证的安装和使用信息
有关 MySQL 中可插拔身份验证的一般信息,请参见 第 8.2.17 节,“可插拔身份验证”。有关 mysql_clear_password
插件的信息,请参见 第 8.4.1.3 节,“客户端明文可插拔身份验证”。有关代理用户的信息,请参见 第 8.2.19 节,“代理用户”。
本节概述了 MySQL 和 PAM 如何协同工作以验证 MySQL 用户。有关设置使用特定 PAM 服务的 MySQL 帐户的示例,请参见 使用 PAM 可插拔身份验证。
客户端程序与服务器进行通信,客户端向服务器发送客户端用户名(默认情况下为操作系统用户名)和密码。
客户端用户名是外部用户名。
对于使用 PAM 服务器端身份验证插件的帐户,相应的客户端插件是
mysql_clear_password
。此客户端插件不执行任何密码哈希,因此客户端将密码以明文形式发送到服务器。
服务器根据外部用户名和客户端连接的主机查找匹配的 MySQL 帐户。PAM 插件使用 MySQL 服务器传递给它的信息(例如用户名、主机名、密码和身份验证字符串)。当您定义使用 PAM 身份验证的 MySQL 帐户时,身份验证字符串包含
PAM 服务名称,它是系统管理员可以用来引用特定应用程序的身份验证方法的名称。单个数据库服务器实例可以关联多个应用程序,因此服务名称的选择留给 SQL 应用程序开发人员。
可选地,如果要使用代理,则将 PAM 组映射到 MySQL 用户名。
该插件使用身份验证字符串中命名的 PAM 服务来检查用户凭据,并返回
'Authentication succeeded, Username is
或user_name
''Authentication failed'
。密码必须适合 PAM 服务使用的密码存储。示例对于传统的 Unix 密码,该服务会查找存储在
/etc/shadow
文件中的密码。对于 LDAP,该服务会查找存储在 LDAP 目录中的密码。
如果凭据检查失败,服务器将拒绝连接。
否则,身份验证字符串指示是否发生代理。如果字符串不包含 PAM 组映射,则不会发生代理。在这种情况下,MySQL 用户名与外部用户名相同。
否则,代理将根据 PAM 组映射进行指示,MySQL 用户名将根据映射列表中第一个匹配的组进行确定。“PAM 组” 的含义取决于 PAM 服务。示例
对于传统的 Unix 密码,组是在
/etc/group
文件中定义的 Unix 组,可能还会在/etc/security/group.conf
等文件中添加额外的 PAM 信息。对于 LDAP,组是在 LDAP 目录中定义的 LDAP 组。
如果代理用户(外部用户)对代理的 MySQL 用户名具有
PROXY
权限,则会发生代理,代理用户将承担代理用户的权限。
本节介绍如何安装服务器端 PAM 身份验证插件。有关安装插件的一般信息,请参阅 第 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 服务名称(请参阅 MySQL 用户如何进行 PAM 身份验证)。以下讨论中的示例使用服务名称
mysql-unix
来表示使用传统 Unix 密码进行身份验证,并使用mysql-ldap
来表示使用 LDAP 进行身份验证。对于代理支持,PAM 提供了一种方法,使 PAM 模块能够将 MySQL 用户名返回到服务器,而不是在客户端程序连接到服务器时传递的外部用户名。使用身份验证字符串来控制外部用户名到 MySQL 用户名的映射。如果您想利用代理用户的功能,则身份验证字符串必须包含这种映射。
例如,如果一个帐户使用 mysql-unix
PAM 服务名称,并且应该将 root
和 users
PAM 组中的操作系统用户分别映射到 developer
和 data_entry
MySQL 用户,请使用以下语句
CREATE USER user
IDENTIFIED WITH authentication_pam
AS 'mysql-unix, root=developer, users=data_entry';
PAM 身份验证插件的身份验证字符串语法遵循以下规则
该字符串由 PAM 服务名称组成,后跟可选的 PAM 组映射列表,该列表包含一个或多个关键字/值对,每个对指定一个 PAM 组名和一个 MySQL 用户名
pam_service_name[,pam_group_name=mysql_user_name]...
该插件会为使用该帐户的每次连接尝试解析身份验证字符串。为最大程度地减少开销,请尽可能缩短字符串。
每个
对前面必须有一个逗号。pam_group_name
=mysql_user_name
双引号之外的开头和结尾空格将被忽略。
未引用的
pam_service_name
、pam_group_name
和mysql_user_name
值可以包含除等号、逗号或空格之外的任何内容。如果
pam_service_name
、pam_group_name
或mysql_user_name
值用双引号引起来,引号之间的所有内容都是该值的一部分。例如,如果该值包含空格字符,则需要这样做。除双引号和反斜杠 (\
) 之外,所有字符都是合法的。要包含这两个字符中的任何一个,请使用反斜杠对其进行转义。
如果该插件成功验证了外部用户名(客户端传递的名称),它会在身份验证字符串中查找 PAM 组映射列表,如果存在,则使用它根据已验证的用户所属的 PAM 组,将不同的 MySQL 用户名返回到 MySQL 服务器
如果身份验证字符串不包含 PAM 组映射列表,该插件将返回外部名称。
如果身份验证字符串确实包含 PAM 组映射列表,该插件将从左到右检查列表中的每个
对,并尝试在非 MySQL 目录中查找与已验证用户的pam_group_name
=mysql_user_name
pam_group_name
值匹配的项,并为第一个找到的匹配项返回mysql_user_name
。如果该插件未找到任何 PAM 组的匹配项,它将返回外部名称。如果该插件无法在目录中查找组,它将忽略 PAM 组映射列表,并返回外部名称。
以下部分介绍如何设置使用 PAM 身份验证插件的几种身份验证场景
没有代理用户。这仅使用 PAM 来检查登录名和密码。每个允许连接到 MySQL 服务器的外部用户都应该具有一个匹配的 MySQL 帐户,该帐户被定义为使用 PAM 身份验证。(对于 MySQL 帐户
'
来匹配外部用户,user_name
'@'host_name
'user_name
必须是外部用户名,host_name
必须与客户端连接的主机匹配。)身份验证可以通过各种 PAM 支持的方法执行。后面的讨论将展示如何使用传统的 Unix 密码和 LDAP 中的密码来验证客户端凭据。PAM 身份验证在不通过代理用户或 PAM 组进行的情况下,要求 MySQL 用户名与操作系统用户名相同。MySQL 用户名限制为 32 个字符(请参阅 第 8.2.3 节,“Grant 表”),这将 PAM 非代理身份验证限制为名称不超过 32 个字符的 Unix 帐户。
仅代理用户,使用 PAM 组映射。对于这种场景,请创建一个或多个定义不同权限集的 MySQL 帐户。(理想情况下,任何人都应该直接使用这些帐户进行连接。)然后,定义一个通过 PAM 进行身份验证的默认用户,该用户使用一些映射方案(通常基于用户所属的外部 PAM 组)将所有外部用户名映射到持有权限集的少数几个 MySQL 帐户。任何连接并指定外部用户名作为客户端用户名的客户端都会被映射到其中一个 MySQL 帐户,并使用其权限。讨论将展示如何使用传统的 Unix 密码来设置它,但也可以使用其他 PAM 方法(如 LDAP)。
这些场景可能有各种变体
您可以允许某些用户直接登录(不使用代理),但要求其他用户通过代理帐户进行连接。
您可以为某些用户使用一种 PAM 身份验证方法,而为其他用户使用另一种方法,方法是在您的 PAM 身份验证帐户中使用不同的 PAM 服务名称。例如,您可以对某些用户使用
mysql-unix
PAM 服务,而对其他用户使用mysql-ldap
。
以下示例基于以下假设。如果您的系统设置不同,您可能需要进行一些调整。
登录名和密码分别是
antonio
和antonio_password
。将这些更改为与您要验证的用户相对应。PAM 配置目录为
/etc/pam.d
。PAM 服务名称对应于身份验证方法(在本讨论中为
mysql-unix
或mysql-ldap
)。要使用给定的 PAM 服务,您必须在 PAM 配置目录中设置一个同名 PAM 文件(如果文件不存在则创建)。此外,您必须在任何使用该 PAM 服务进行身份验证的帐户的CREATE USER
语句的身份验证字符串中命名 PAM 服务。
PAM 身份验证插件在初始化时会检查服务器启动环境中是否设置了 AUTHENTICATION_PAM_LOG
环境值。如果设置,则插件会启用将诊断消息记录到标准输出。根据服务器的启动方式,消息可能会出现在控制台中或错误日志中。这些消息可能有助于调试在插件执行身份验证时发生的与 PAM 相关的错误。有关更多信息,请参见 PAM 身份验证调试。
此身份验证方案使用 PAM 检查以操作系统用户名和 Unix 密码形式定义的外部用户,不进行代理。每个被允许连接到 MySQL 服务器的此类外部用户都应该有一个匹配的 MySQL 帐户,该帐户被定义为通过传统的 Unix 密码存储使用 PAM 身份验证。
传统的 Unix 密码使用 /etc/shadow
文件进行检查。有关与该文件相关的可能问题的详细信息,请参见 PAM 身份验证访问 Unix 密码存储。
验证 Unix 身份验证是否允许使用用户名
antonio
和密码antonio_password
登录到操作系统。通过创建名为
/etc/pam.d/mysql-unix
的mysql-unix
PAM 服务文件,设置 PAM 以使用传统的 Unix 密码对 MySQL 连接进行身份验证。文件内容依赖于系统,因此请检查/etc/pam.d
目录中现有的与登录相关的文件,看看它们是什么样的。在 Linux 上,mysql-unix
文件可能如下所示#%PAM-1.0 auth include password-auth account include password-auth
对于 macOS,使用
login
而不是password-auth
。PAM 文件格式在某些系统上可能有所不同。例如,在 Ubuntu 和其他基于 Debian 的系统上,请改用以下文件内容
@include common-auth @include common-account @include common-session-noninteractive
创建一个与操作系统用户名相同的用户名的 MySQL 帐户,并将其定义为使用 PAM 插件和
mysql-unix
PAM 服务进行身份验证CREATE USER 'antonio'@'localhost' IDENTIFIED WITH authentication_pam AS 'mysql-unix'; GRANT ALL PRIVILEGES ON mydb.* TO 'antonio'@'localhost';
此处,身份验证字符串仅包含 PAM 服务名称
mysql-unix
,它用于验证 Unix 密码。使用 mysql 命令行客户端以
antonio
用户身份连接到 MySQL 服务器。例如$> mysql --user=antonio --password --enable-cleartext-plugin Enter password: antonio_password
服务器应该允许连接,并且以下查询将返回如下所示的输出
mysql> SELECT USER(), CURRENT_USER(), @@proxy_user; +-------------------+-------------------+--------------+ | USER() | CURRENT_USER() | @@proxy_user | +-------------------+-------------------+--------------+ | antonio@localhost | antonio@localhost | NULL | +-------------------+-------------------+--------------+
这表明
antonio
操作系统用户被验证为拥有授予antonio
MySQL 用户的权限,并且没有发生代理。
客户端 mysql_clear_password
身份验证插件不会修改密码,因此客户端程序会将密码以明文形式发送到 MySQL 服务器。这使得密码可以原样传递给 PAM。使用服务器端 PAM 库需要明文密码,但在某些配置中可能存在安全问题。这些措施将风险降至最低
为了降低意外使用
mysql_clear_password
插件的可能性,MySQL 客户端必须显式启用它(例如,使用--enable-cleartext-plugin
选项)。请参见 第 8.4.1.3 节,“客户端明文可插拔身份验证”。为了避免在启用
mysql_clear_password
插件的情况下暴露密码,MySQL 客户端应该使用加密连接连接到 MySQL 服务器。请参见 第 8.3.1 节,“配置 MySQL 以使用加密连接”。
此身份验证方案使用 PAM 检查以操作系统用户名和 LDAP 密码形式定义的外部用户,不进行代理。每个被允许连接到 MySQL 服务器的此类外部用户都应该有一个匹配的 MySQL 帐户,该帐户被定义为通过 LDAP 使用 PAM 身份验证。
要对 MySQL 使用 PAM LDAP 可插拔身份验证,必须满足以下先决条件
PAM LDAP 服务必须能够与之通信的 LDAP 服务器必须可用。
每个要由 MySQL 验证的 LDAP 用户都必须存在于 LDAP 服务器管理的目录中。
使用 LDAP 对 MySQL 用户进行身份验证的另一种方法是使用特定于 LDAP 的身份验证插件。请参见 第 8.4.1.6 节,“LDAP 可插拔身份验证”。
按如下方式配置 MySQL 以使用 PAM LDAP 身份验证
验证 Unix 身份验证是否允许使用用户名
antonio
和密码antonio_password
登录到操作系统。通过创建名为
/etc/pam.d/mysql-ldap
的mysql-ldap
PAM 服务文件,设置 PAM 以使用 LDAP 对 MySQL 连接进行身份验证。文件内容依赖于系统,因此请检查/etc/pam.d
目录中现有的与登录相关的文件,看看它们是什么样的。在 Linux 上,mysql-ldap
文件可能如下所示#%PAM-1.0 auth required pam_ldap.so account required pam_ldap.so
如果 PAM 对象文件的后缀与您系统上的
.so
不同,请替换正确的后缀。PAM 文件格式在某些系统上可能有所不同。
创建一个与操作系统用户名相同的用户名的 MySQL 帐户,并将其定义为使用 PAM 插件和
mysql-ldap
PAM 服务进行身份验证CREATE USER 'antonio'@'localhost' IDENTIFIED WITH authentication_pam AS 'mysql-ldap'; GRANT ALL PRIVILEGES ON mydb.* TO 'antonio'@'localhost';
此处,身份验证字符串仅包含 PAM 服务名称
mysql-ldap
,它用于使用 LDAP 进行身份验证。连接到服务器与 无代理用户的 PAM Unix 密码身份验证 中描述的相同。
此处描述的身份验证方案使用代理和 PAM 组映射,将使用 PAM 进行身份验证的连接 MySQL 用户映射到定义不同权限集的其他 MySQL 帐户。用户不会直接通过定义权限的帐户进行连接。相反,他们通过使用 PAM 进行身份验证的默认代理帐户进行连接,以便所有外部用户都映射到拥有权限的 MySQL 帐户。任何使用代理帐户进行连接的用户都将映射到其中一个 MySQL 帐户,其权限决定了允许外部用户执行的数据库操作。
此处显示的过程使用 Unix 密码身份验证。要改用 LDAP,请参见 无代理用户的 PAM LDAP 身份验证 的早期步骤。
传统的 Unix 密码使用 /etc/shadow
文件进行检查。有关与该文件相关的可能问题的详细信息,请参见 PAM 身份验证访问 Unix 密码存储。
验证 Unix 身份验证是否允许使用用户名
antonio
和密码antonio_password
登录到操作系统。验证
antonio
是否是root
或users
PAM 组的成员。通过创建名为
/etc/pam.d/mysql-unix
的文件,设置 PAM 以通过操作系统用户对mysql-unix
PAM 服务进行身份验证。文件内容依赖于系统,因此请检查/etc/pam.d
目录中现有的与登录相关的文件,看看它们是什么样的。在 Linux 上,mysql-unix
文件可能如下所示#%PAM-1.0 auth include password-auth account include password-auth
对于 macOS,使用
login
而不是password-auth
。PAM 文件格式在某些系统上可能有所不同。例如,在 Ubuntu 和其他基于 Debian 的系统上,请改用以下文件内容
@include common-auth @include common-account @include common-session-noninteractive
创建一个默认代理用户 (
''@''
),将外部 PAM 用户映射到代理帐户CREATE USER ''@'' IDENTIFIED WITH authentication_pam AS 'mysql-unix, root=developer, users=data_entry';
此处,身份验证字符串包含 PAM 服务名称
mysql-unix
,它用于验证 Unix 密码。身份验证字符串还将root
和users
PAM 组中的外部用户分别映射到developer
和data_entry
MySQL 用户名。在设置代理用户时,需要 PAM 服务名称后面的 PAM 组映射列表。否则,插件无法知道如何从外部用户名映射到正确的代理 MySQL 用户名。
注意如果您的 MySQL 安装有匿名用户,他们可能会与默认代理用户冲突。有关此问题的更多信息以及解决方法,请参见 默认代理用户和匿名用户冲突。
创建代理帐户,并为每个帐户授予它应该拥有的权限
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.8 节,“无登录可插拔身份验证”。)有关保护代理帐户免受直接使用的方法,请参见 阻止直接登录代理帐户。为代理帐户授予每个代理帐户的
PROXY
权限GRANT PROXY ON 'developer'@'localhost' TO ''@''; GRANT PROXY ON 'data_entry'@'localhost' TO ''@'';
使用 mysql 命令行客户端以
antonio
用户身份连接到 MySQL 服务器。$> mysql --user=antonio --password --enable-cleartext-plugin Enter password: antonio_password
服务器使用默认的
''@''
代理帐户验证连接。antonio
的结果权限取决于antonio
是哪个 PAM 组的成员。如果antonio
是root
PAM 组的成员,则 PAM 插件会将root
映射到developer
MySQL 用户名,并将该用户名返回给服务器。服务器会验证''@''
是否对developer
拥有PROXY
权限,并允许连接。以下查询将返回如下所示的输出mysql> SELECT USER(), CURRENT_USER(), @@proxy_user; +-------------------+---------------------+--------------+ | USER() | CURRENT_USER() | @@proxy_user | +-------------------+---------------------+--------------+ | antonio@localhost | developer@localhost | ''@'' | +-------------------+---------------------+--------------+
这表明
antonio
操作系统用户被验证为拥有授予developer
MySQL 用户的权限,并且代理通过默认代理帐户进行。如果
antonio
不是root
PAM 组的成员,而是users
PAM 组的成员,则会发生类似的过程,但插件会将user
PAM 组成员资格映射到data_entry
MySQL 用户名,并将该用户名返回给服务器mysql> SELECT USER(), CURRENT_USER(), @@proxy_user; +-------------------+----------------------+--------------+ | USER() | CURRENT_USER() | @@proxy_user | +-------------------+----------------------+--------------+ | antonio@localhost | data_entry@localhost | ''@'' | +-------------------+----------------------+--------------+
这表明
antonio
操作系统用户被验证为拥有授予data_entry
MySQL 用户的权限,并且代理通过默认代理帐户进行。
客户端 mysql_clear_password
身份验证插件不会修改密码,因此客户端程序会将密码以明文形式发送到 MySQL 服务器。这使得密码可以原样传递给 PAM。使用服务器端 PAM 库需要明文密码,但在某些配置中可能存在安全问题。这些措施将风险降至最低
为了降低意外使用
mysql_clear_password
插件的可能性,MySQL 客户端必须显式启用它(例如,使用--enable-cleartext-plugin
选项)。请参见 第 8.4.1.3 节,“客户端明文可插拔身份验证”。为了避免在启用
mysql_clear_password
插件的情况下暴露密码,MySQL 客户端应该使用加密连接连接到 MySQL 服务器。请参见 第 8.3.1 节,“配置 MySQL 以使用加密连接”。
在某些系统上,Unix 身份验证使用密码存储,例如 /etc/shadow
,这是一个通常具有受限访问权限的文件。这会导致 MySQL 基于 PAM 的身份验证失败。不幸的是,PAM 实现不允许区分 “无法检查密码”(例如,由于无法读取 /etc/shadow
)和 “密码不匹配。”如果您对 PAM 身份验证使用 Unix 密码存储,则可以使用以下方法之一启用 MySQL 从中访问密码存储
假设 MySQL 服务器从
mysql
操作系统帐户运行,将该帐户放入具有/etc/shadow
访问权限的shadow
组。在
/etc/group
中创建一个shadow
组。在
/etc/group
中将mysql
操作系统用户添加到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 身份验证配置为允许所有连接,然后检查系统日志文件。此技术应仅在临时基础上使用,不应在生产服务器上使用。
使用以下内容配置一个名为 /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 服务文件以禁用任何密码访问。