6.4.1.7 PAM 可插入身份验证
Note
PAM 可插入身份验证是商业产品 MySQL Enterprise Edition 中包含的扩展。要了解有关商品的更多信息,请参阅https://www.mysql.com/products/。
MySQL Enterprise Edition 支持一种身份验证方法,该方法使 MySQL Server 能够使用 PAM(可插入身份验证模块)来对 MySQL 用户进行身份验证。 PAM 使系统能够使用标准接口来访问各种身份验证方法,例如传统的 Unix 密码或 LDAP 目录。
PAM 可插入身份验证提供以下功能:
-
外部身份验证:PAM 身份验证使 MySQL Server 可以接受来自 MySQL 授予 table 之外定义的用户的连接,并使用 PAM 支持的方法进行身份验证。
-
代理用户支持:基于外部用户所属的 PAM 组和提供的身份验证字符串,PAM 身份验证可以将与 Client 端程序传递的外部用户名不同的用户名返回给 MySQL。这意味着该插件可以返回 MySQL 用户,该用户定义了经过外部 PAM 身份验证的用户应具有的特权。例如,一个名为
joe
的 os 用户可以连接并具有一个名为developer
的 MySQL 用户的特权。
PAM 可插入身份验证已在 Linux 和 macOS 上进行了测试。
下 table 显示了插件和库文件名。文件名后缀可能在您的系统上有所不同。该文件必须位于plugin_dir系统变量命名的目录中。有关安装信息,请参见安装 PAM 可插入身份验证。
table6.13 用于 PAM 身份验证的插件和库名称
插件或文件 | 插件或文件名 |
---|---|
Server-side plugin | authentication_pam |
Client-side plugin | mysql_clear_password |
Library file | authentication_pam.so |
与服务器端 PAM 插件进行通信的 Client 端mysql_clear_password
cleartext 插件内置在libmysqlclient
Client 端库中,并包含在所有发行版中,包括社区发行版。在所有 MySQL 发行版中都包含 Client 端明文插件,使来自任何发行版的 Client 端都可以连接到已加载了服务器端 PAM 插件的服务器。
以下各节提供特定于 PAM 可插入身份验证的安装和使用信息:
有关 MySQL 中可插拔身份验证的一般信息,请参见第 6.2.13 节“可插入身份验证”。有关mysql_clear_password
插件的信息,请参见第 6.4.1.6 节“Client 端明文可插入身份验证”。有关代理用户的信息,请参见第 6.2.14 节“代理用户”。
MySQL 用户的 PAM 身份验证如何工作
本节概述了 MySQL 和 PAM 如何协同工作以认证 MySQL 用户。有关显示如何设置 MySQL 帐户以使用特定 PAM 服务的示例,请参见使用 PAM 可插入身份验证。
-
Client 端程序和服务器进行通信,Client 端将服务器的用户名(默认为 os 用户名)和密码发送给服务器:
-
Client 端用户名是外部用户名。
-
对于使用 PAM 服务器端身份验证插件的帐户,相应的 Client 端插件为
mysql_clear_password
。该 Client 端插件不执行密码哈希处理,结果是 Client 端将密码以明文形式发送到服务器。 -
服务器根据外部用户名和 Client 端连接的主机找到匹配的 MySQL 帐户。 PAM 插件使用 MySQL Server 传递给它的信息(例如用户名,主机名,密码和身份验证字符串)。定义使用 PAM 进行身份验证的 MySQL 帐户时,身份验证字符串包含:
-
PAM 服务名称,这是系统 Management 员可以用来引用特定应用程序的身份验证方法的名称。单个数据库服务器实例可以有多个应用程序,因此服务名称的选择留给 SQL 应用程序开发人员进行。
-
(可选)如果要使用代理,则是从 PAM 组到 MySQL 用户名的 Map。
-
该插件使用身份验证字符串中命名的 PAM 服务来检查用户凭据,并返回
'Authentication succeeded, Username is user_name'
或'Authentication failed'
。该密码必须适合 PAM 服务使用的密码存储。例子: -
对于传统的 Unix 密码,该服务将查找存储在
/etc/shadow
文件中的密码。 -
对于 LDAP,该服务将查找存储在 LDAP 目录中的密码。
如果凭据检查失败,则服务器拒绝连接。
-
否则,认证字符串指示是否发生代理。如果该字符串不包含 PAM 组 Map,则不会发生代理。在这种情况下,MySQL 用户名与外部用户名相同。
-
否则,将基于 PAM 组 Map 指示代理,并根据 Map 列 table 中的第一个匹配组确定 MySQL 用户名。 “ PAM 组”的含义取决于 PAM 服务。例子:
-
对于传统的 Unix 密码,组是在
/etc/group
文件中定义的 Unix 组,可能在文件/etc/security/group.conf
中添加了附加的 PAM 信息。 -
对于 LDAP,组是在 LDAP 目录中定义的 LDAP 组。
如果代理用户(外部用户)对代理的 MySQL 用户名具有PROXY特权,则将进行代理,代理用户将承担代理用户的特权。
安装 PAM 可插入身份验证
本节介绍如何安装 PAM 身份验证插件。有关安装插件的一般信息,请参见第 5.5.1 节“安装和卸载插件”。
要由服务器使用,插件库文件必须位于 MySQL 插件目录(由plugin_dir系统变量命名的目录)中。如有必要,通过在服务器启动时设置plugin_dir的值来配置插件目录位置。
插件库文件的基本名称为authentication_pam
。每个平台的文件名后缀都不同(例如,对于 Unix 和类 Unix 系统,为.so
,对于 Windows 为.dll
)。
要在服务器启动时加载插件,请使用--plugin-load-add选项命名包含该插件的库文件。使用这种插件加载方法,每次服务器启动时都必须给出该选项。例如,将这些行放在服务器my.cnf
文件中,并根据需要调整平台的.so
后缀:
[mysqld]
plugin-load-add=authentication_pam.so
修改my.cnf
后,重新启动服务器以使新设置生效。
或者,要在运行时加载插件,请使用以下语句,并根据需要调整平台的.so
后缀:
INSTALL PLUGIN authentication_pam SONAME 'authentication_pam.so';
INSTALL PLUGIN立即加载该插件,并将其注册在mysql.plugins
系统 table 中,以使服务器为每次后续的正常启动加载该插件,而无需--plugin-load-add。
要验证插件安装,请检查INFORMATION_SCHEMA.PLUGINStable 或使用SHOW PLUGINS语句(请参见第 5.5.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 可插入身份验证
卸载 PAM 身份验证插件的方法取决于安装方式:
-
如果您在服务器启动时使用--plugin-load-add选项安装了插件,请在不使用该选项的情况下重新启动服务器。
-
如果您在运行时使用INSTALL PLUGIN语句安装了插件,则在服务器重新启动后仍会安装该插件。要卸载它,请使用UNINSTALL PLUGIN:
UNINSTALL PLUGIN authentication_pam;
使用 PAM 可插入身份验证
本节以一般术语描述如何使用 PAM 身份验证插件将 MySQLClient 端程序连接到服务器。以下各节提供了以特定方式使用 PAM 身份验证的说明。如安装 PAM 可插入身份验证所述,假定服务器正在启用服务器端 PAM 插件的情况下运行。
要在CREATE USER语句的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 用户名返回给服务器的方法,该 Client 端用户名不是 Client 端程序在连接到服务器时传递的外部用户名。使用身份验证字符串来控制从外部用户名到 MySQL 用户名的 Map。如果要利用代理用户功能,则身份验证字符串必须包括这种 Map。
例如,如果一个帐户使用mysql-unix
PAM 服务名称,并且应将root
和users
PAM 组中的 os 用户分别 Map 到developer
和data_entry
MySQL 用户,则使用如下语句:
CREATE USER user
IDENTIFIED WITH authentication_pam
AS 'mysql-unix, root=developer, users=data_entry';
PAM 身份验证插件的身份验证字符串语法遵循以下规则:
- 该字符串由一个 PAM 服务名称组成,可选地后面是一个 PAM 组 Map 列 table,该列 table 由一个或多个关键字/值对组成,每个关键字/值对指定一个 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
*值用双引号引起来,则引号之间的所有内容都是该值的一部分。例如,如果该值包含空格字符,则这是必需的。除双引号和反斜杠(\
)外,所有字符均合法。要包含两个字符,请用反斜杠将其转义。
如果插件成功验证了外部用户名(Client 端传递的名称),它将在身份验证字符串中查找 PAM 组 Map 列 table,如果存在,则使用该插件将基于以下内容的另一个 MySQL 用户名返回给 MySQL 服务器:外部用户属于哪个 PAM 组:
-
如果身份验证字符串不包含 PAM 组 Map 列 table,则插件将返回外部名称。
-
如果身份验证字符串确实包含 PAM 组 Map 列 table,则插件从左到右检查列 table 中的每个
pam_group_name=mysql_user_name
对,并尝试在分配给已认证的组的非 MySQL 目录中找到*pam_group_name
值的匹配项用户并为找到的第一个匹配项返回mysql_user_name
*。如果插件未找到任何 PAM 组的匹配项,则它将返回外部名称。如果该插件无法在目录中查找组,则它将忽略 PAM 组 Map 列 table 并返回外部名称。
以下各节描述如何设置使用 PAM 身份验证插件的几种身份验证方案:
- 没有代理用户。这仅使用 PAM 来检查登录名和密码。每个允许连接到 MySQL Server 的外部用户都应具有一个定义为使用 PAM 身份验证的匹配 MySQL 帐户。 (要使
'user_name'@'host_name'
的 MySQL 帐户与外部用户匹配,*user_name
必须是外部用户名,host_name
*必须与 Client 端连接的主机匹配.)可以通过各种 PAM 支持的方法来执行身份验证。稍后的讨论显示了如何使用传统的 Unix 密码和 LDAP 中的密码来认证 Client 端凭证。
如果不通过代理用户或 PAM 组进行 PAM 身份验证,则需要 MySQL 用户名与 os 用户名相同。 MySQL 用户名限制为 32 个字符(请参阅第 6.2.3 节“授权 table”),这将 PAM 非代理身份验证限制为名称最多为 32 个字符的 Unix 帐户。
- 仅代理用户,具有 PAM 组 Map。对于这种情况,创建一个或多个定义不同权限集的 MySQL 帐户。 (理想情况下,没有人应该直接使用这些帐户进行连接.)然后定义一个通过 PAM 进行身份验证的默认用户,该身份验证使用某种 Map 方案(通常基于用户所属的外部 PAM 组)将所有外部用户名 Map 到少数 MySQL 拥有特权集的帐户。任何连接并指定外部用户名作为 Client 端用户名的 Client 端都将 Map 到一个 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 密码认证
此身份验证方案使用 PAM 来检查根据 os 用户名和 Unix 密码定义的外部用户,而无需代理。每个允许连接到 MySQL Server 的此类外部用户都应具有一个匹配的 MySQL 帐户,该帐户定义为通过传统的 Unix 密码存储区使用 PAM 身份验证。
Note
使用/etc/shadow
文件检查传统的 Unix 密码。有关与此文件有关的可能问题的信息,请参见对 Unix 密码存储的 PAM 身份验证访问。
-
验证 Unix 身份验证是否允许使用用户名
antonio
和密码*antonio_password
*登录到 os。 -
通过创建名为
/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
- 使用与 os 用户名相同的用户名创建一个 MySQL 帐户,并使用 PAM 插件和
mysql-unix
PAM 服务对其进行定义以进行身份验证:
CREATE USER 'antonio'@'localhost'
IDENTIFIED WITH authentication_pam
AS 'mysql-unix';
GRANT ALL PRIVILEGES
ON mydb.*
TO 'antonio'@'localhost';
此处,认证字符串仅包含用于认证 Unix 密码的 PAM 服务名称mysql-unix
。
- 使用mysql命令行 Client 端以
antonio
连接到 MySQL 服务器。例如:
shell> 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 |
+-------------------+-------------------+--------------+
这 table 明对antonio
os 用户进行了身份验证以具有授予antonio
MySQL 用户的特权,并且没有发生代理。
Note
Client 端mysql_clear_password
身份验证插件不会更改密码,因此 Client 端程序会将其以明文形式发送到 MySQL 服务器。这样可以将密码原样传递给 PAM。明文密码对于使用服务器端 PAM 库是必需的,但在某些配置中可能是安全问题。这些措施可最大程度地降低风险:
-
为了减少偶然使用
mysql_clear_password
插件的可能性,MySQLClient 端必须显式启用它(例如,使用--enable-cleartext-plugin
选项)。参见第 6.4.1.6 节“Client 端明文可插入身份验证”。 -
为了避免在启用
mysql_clear_password
插件的情况下暴露密码,MySQLClient 端应使用加密连接连接到 MySQL 服务器。参见第 6.3.1 节“配置 MySQL 以使用加密连接”。
没有代理用户的 PAM LDAP 认证
此身份验证方案使用 PAM 来检查根据 os 用户名和 LDAP 密码定义的外部用户,而无需代理。每个允许连接到 MySQL Server 的此类外部用户应具有一个匹配的 MySQL 帐户,该帐户定义为通过 LDAP 使用 PAM 身份验证。
要将 PAM LDAP 可插拔身份验证用于 MySQL,必须满足以下先决条件:
-
LDAP 服务器必须可用于 PAM LDAP 服务进行通信。
-
要由 MySQL 认证的 LDAP 用户必须存在于 LDAP 服务器 Management 的目录中。
Note
使用 LDAP 进行 MySQL 用户身份验证的另一种方法是使用 LDAP 特定的身份验证插件。参见第 6.4.1.9 节“ LDAP 可插拔身份验证”。
配置 MySQL 以进行 PAM LDAP 身份验证,如下所示:
-
验证 Unix 身份验证是否允许使用用户名
antonio
和密码*antonio_password
*登录到 os。 -
通过创建名为
/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 文件格式可能有所不同。
- 使用与 os 用户名相同的用户名创建一个 MySQL 帐户,并使用 PAM 插件和
mysql-ldap
PAM 服务对其进行定义以进行身份验证:
CREATE USER 'antonio'@'localhost'
IDENTIFIED WITH authentication_pam
AS 'mysql-ldap';
GRANT ALL PRIVILEGES
ON mydb.*
TO 'antonio'@'localhost';
此处,身份验证字符串仅包含使用 LDAP 进行身份验证的 PAM 服务名称mysql-ldap
。
- 连接到服务器与没有代理用户的 PAM Unix 密码认证中描述的相同。
使用代理用户和组 Map 的 PAM Unix 密码认证
此处描述的身份验证方案使用代理和 PAM 组 Map 将使用 PAM 进行身份验证的 MySQL 用户连接到定义了不同权限集的其他 MySQL 帐户。用户不会直接通过定义特权的帐户进行连接。相反,它们通过使用 PAM 进行身份验证的默认代理帐户连接,这样所有外部用户都将 Map 到拥有特权的 MySQL 帐户。使用代理帐户进行连接的任何用户都将 Map 到这些 MySQL 帐户之一,这些帐户的特权确定了允许外部用户执行的数据库操作。
此处显示的过程使用 Unix 密码身份验证。要改用 LDAP,请参阅没有代理用户的 PAM LDAP 认证的早期步骤。
Note
使用/etc/shadow
文件检查传统的 Unix 密码。有关与此文件有关的可能问题的信息,请参见对 Unix 密码存储的 PAM 身份验证访问。
-
验证 Unix 身份验证是否允许使用用户名
antonio
和密码*antonio_password
*登录到 os。 -
验证
antonio
是root
或users
PAM 组的成员。 -
通过创建名为
/etc/pam.d/mysql-unix
的文件,设置 PAM 以通过 os 用户对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 用户 Map 到代理帐户的默认代理用户(
''@''
):
CREATE USER ''@''
IDENTIFIED WITH authentication_pam
AS 'mysql-unix, root=developer, users=data_entry';
这里,认证字符串包含用于认证 Unix 密码的 PAM 服务名称mysql-unix
。身份验证字符串还将root
和users
PAM 组中的外部用户分别 Map 到developer
和data_entry
MySQL 用户名。
设置代理用户时,需要 PAM 服务名称后面的 PAM 组 Map 列 table。否则,插件将无法告诉您如何执行从外部用户名到正确的代理 MySQL 用户名的 Map。
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
身份验证插件来防止 Client 端使用帐户直接登录到 MySQL 服务器。相反,预期使用 PAM 进行身份验证的用户将根据其 PAM 组通过代理使用developer
或data_entry
帐户。 (这假定已安装插件.有关说明,请参阅第 6.4.1.10 节“无登录可插入身份验证”。)有关防止代理帐户直接使用的替代方法,请参阅防止直接登录到代理帐户。
- 为代理帐户授予每个代理帐户的PROXY特权:
GRANT PROXY
ON 'developer'@'localhost'
TO ''@'';
GRANT PROXY
ON 'data_entry'@'localhost'
TO ''@'';
- 使用mysql命令行 Client 端以
antonio
连接到 MySQL 服务器。
shell> mysql --user=antonio --password --enable-cleartext-plugin
Enter password: antonio_password
服务器使用默认的''@''
代理帐户对连接进行身份验证。 antonio
的最终特权取决于antonio
是哪个 PAM 组的成员。如果antonio
是root
PAM 组的成员,则 PAM 插件将root
Map 到developer
MySQL 用户名并将该名称返回到服务器。服务器验证''@''
拥有developer
的PROXY特权并允许连接。以下查询返回输出,如下所示:
mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
+-------------------+---------------------+--------------+
| USER() | CURRENT_USER() | @@proxy_user |
+-------------------+---------------------+--------------+
| antonio@localhost | developer@localhost | ''@'' |
+-------------------+---------------------+--------------+
这 table 明对antonio
os 用户进行了身份验证以具有授予developer
MySQL 用户的特权,并且通过默认代理帐户进行了代理。
如果antonio
不是root
PAM 组的成员,而是users
PAM 组的成员,则会发生类似的过程,但是该插件将user
PAM 组成员资格 Map 到data_entry
MySQL 用户名,并将该名称返回给服务器:
mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
+-------------------+----------------------+--------------+
| USER() | CURRENT_USER() | @@proxy_user |
+-------------------+----------------------+--------------+
| antonio@localhost | data_entry@localhost | ''@'' |
+-------------------+----------------------+--------------+
这 table 明antonio
os 用户已通过身份验证,具有data_entry
MySQL 用户的特权,并且通过默认代理帐户进行了代理。
Note
Client 端mysql_clear_password
身份验证插件不会更改密码,因此 Client 端程序会将其以明文形式发送到 MySQL 服务器。这样可以将密码原样传递给 PAM。明文密码对于使用服务器端 PAM 库是必需的,但在某些配置中可能是安全问题。这些措施可最大程度地降低风险:
-
为了减少偶然使用
mysql_clear_password
插件的可能性,MySQLClient 端必须显式启用它(例如,使用--enable-cleartext-plugin
选项)。参见第 6.4.1.6 节“Client 端明文可插入身份验证”。 -
为了避免在启用
mysql_clear_password
插件的情况下暴露密码,MySQLClient 端应使用加密连接连接到 MySQL 服务器。参见第 6.3.1 节“配置 MySQL 以使用加密连接”。
对 Unix 密码存储库的 PAM 身份验证访问
在某些系统上,Unix 身份验证使用诸如/etc/shadow
之类的密码存储,该文件通常具有受限的访问权限。这可能导致基于 MySQL PAM 的身份验证失败。不幸的是,PAM 实施不允许将“无法检查密码”(例如,由于无法读取/etc/shadow
)与“密码不匹配”区分开。如果您使用 Unix 密码存储进行 PAM 身份验证,则可以使用以下方法之一启用从 MySQL 对其的访问:
-
假设 MySQL 服务器是通过
mysql
os 帐户运行的,请将该帐户放入具有/etc/shadow
访问权限的shadow
组中: -
在
/etc/group
中创建一个shadow
组。 -
将
mysql
os 用户添加到/etc/group
的shadow
组中。 -
将
/etc/group
分配给shadow
组并启用组读取权限:
chgrp shadow /etc/shadow
chmod g+r /etc/shadow
-
重新启动 MySQL 服务器。
-
如果您使用的是
pam_unix
模块和 unix_chkpwd Util,请按以下方式启用密码存储访问:
chmod u-s /usr/sbin/unix_chkpwd
setcap cap_dac_read_search+ep /usr/sbin/unix_chkpwd
根据您的平台的需要,将路径调整为 unix_chkpwd **。
PAM 身份验证调试
PAM 身份验证插件在初始化时检查是否设置了AUTHENTICATION_PAM_LOG
环境值(该值无关紧要)。如果是这样,则插件可以将诊断消息记录到标准输出中。这些消息可能有助于调试插件执行身份验证时发生的与 PAM 相关的问题。
一些消息包括对 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,即使密码错误也是如此。如果身份验证尝试失败,则 table 明配置问题在 MySQL 方面。否则,问题出在 os/ PAM 端。要查看可能发生的情况,请检查/var/log/secure
,/var/log/audit.log
,/var/log/syslog
或/var/log/messages
之类的系统日志文件。
确定问题出在哪里之后,请删除mysql-any-password
PAM 服务文件以禁用任何密码访问。