• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • PAM可插入身份验证

    注意

    PAM可插入身份验证是商业产品MySQL Enterprise Edition中包含的扩展。要了解有关商业产品的更多信息,请参见https://www.mysql.com/products/。

    MySQL Enterprise Edition支持一种身份验证方法,该方法使MySQL Server可以使用PAM(可插入身份验证模块)对MySQL用户进行身份验证。PAM使系统能够使用标准接口来访问各种身份验证方法,例如传统的Unix密码或LDAP目录。

    PAM可插入身份验证提供以下功能:

    • 外部身份验证:PAM身份验证使MySQL Server可以接受来自MySQL授予表之外定义的用户的连接,并使用PAM支持的方法进行身份验证。
    • 代理用户支持:基于外部用户所属的PAM组和提供的身份验证字符串,PAM身份验证可以将与客户端程序传递的外部用户名不同的用户名返回给MySQL。这意味着该插件可以返回MySQL用户,该用户定义了经过外部PAM身份验证的用户应具有的特权。例如,一个名为的操作系统用户joe可以连接并具有名为的MySQL用户的特权developer

    PAM可插入身份验证已在Linux和macOS上进行了测试。

    下表显示了插件和库文件名。文件名后缀在您的系统上可能有所不同。该文件必须位于plugin_dir系统变量命名的目录中。有关安装信息,请参阅《安装PAM可插入身份验证》。

    表6.16用于PAM身份验证的插件和库名称

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

    mysql_clear_password与服务器端PAM插件进行通信的客户端明文插件内置于libmysqlclient客户端库中,并包含在所有发行版中,包括社区发行版。在所有MySQL发行版中都包含客户端明文插件,使来自任何发行版的客户端都可以连接到已加载了服务器端PAM插件的服务器。

    以下各节提供特定于PAM可插入身份验证的安装和使用信息:

    • MySQL用户的PAM身份验证如何工作
    • 安装PAM可插入身份验证
    • 卸载PAM可插入身份验证
    • 使用PAM可插入身份验证
    • 没有代理用户的PAM Unix密码认证
    • 没有代理用户的PAM LDAP认证
    • 使用代理用户和组映射的PAM Unix密码身份验证
    • 对Unix密码存储的PAM身份验证访问
    • PAM身份验证调试

    有关MySQL中的可插入身份验证的一般信息,有关mysql_clear_password插件的信息,请参见“客户端明文可插入身份验证”。有关代理用户的信息,请参见“代理用户”。

    MySQL用户的PAM身份验证如何工作

    本节概述了MySQL和PAM如何协同工作以认证MySQL用户。有关显示如何设置MySQL帐户以使用特定PAM服务的示例,请参见使用PAM可插入身份验证。

    1. 客户端程序和服务器进行通信,客户端将服务器的用户名(默认为操作系统用户名)和密码发送给服务器:

      • 客户端用户名是外部用户名。
      • 对于使用PAM服务器端身份验证插件的帐户,相应的客户端插件为mysql_clear_password。该客户端插件不执行密码哈希处理,结果是客户端将密码以明文形式发送到服务器。
    2. 服务器根据外部用户名和客户端连接的主机找到匹配的MySQL帐户。PAM插件使用MySQL Server传递给它的信息(例如用户名,主机名,密码和身份验证字符串)。定义使用PAM进行身份验证的MySQL帐户时,身份验证字符串包含:

      • PAM服务名称,这是系统管理员可以用来引用特定应用程序的身份验证方法的名称。单个数据库服务器实例可以有多个应用程序,因此服务名称的选择留给SQL应用程序开发人员进行。
      • (可选)如果要使用代理,则是从PAM组到MySQL用户名的映射。
    3. 插件使用身份验证字符串中命名的PAM服务检查用户凭据,然后返回或。该密码必须适合PAM服务使用的密码存储。例子:'Authentication succeeded, Username is user_name''Authentication failed'

      • 对于传统的Unix密码,该服务将查找/etc/shadow文件中存储的密码。
      • 对于LDAP,该服务将查找存储在LDAP目录中的密码。

      如果凭据检查失败,则服务器拒绝连接。

    4. 否则,认证字符串指示是否发生代理。如果该字符串不包含PAM组映射,则不会发生代理。在这种情况下,MySQL用户名与外部用户名相同。
    5. 否则,将基于PAM组映射指示代理,并根据映射列表中的第一个匹配组确定MySQL用户名。“ PAM组”的含义取决于PAM服务。例子:

      • 对于传统的Unix密码,组是/etc/group文件中定义的Unix组,可能在文件中添加了PAM信息(例如)/etc/security/group.conf
      • 对于LDAP,组是在LDAP目录中定义的LDAP组。

      如果代理用户(外部用户)具有PROXY代理MySQL用户名的特权,则将发生代理,代理用户将承担代理用户的特权。

    安装PAM可插入身份验证

    本节介绍如何安装PAM身份验证插件。有关安装插件的一般信息,请参见“MySQL服务器插件”。

    要由服务器使用,插件库文件必须位于MySQL插件目录(由plugin_dir系统变量命名的目录)中。如有必要,通过设置plugin_dir服务器启动时的值来配置插件目录位置。

    插件库文件的基本名称为 uthentication_pam。每个平台的文件名后缀都不同(例如,.so对于Unix和类似Unix的系统,.dll对于Windows)。

    要在服务器启动时加载插件,请使用--plugin-load-add选项来命名包含该插件的库文件。使用这种插件加载方法,每次服务器启动时都必须给出该选项。例如,将以下行放在服务器my.cnf文件中(.so根据需要调整平台的后缀):

    [mysqld]
    plugin-load-add= uthentication_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语句(请参见“获取服务器插件信息”)。例如:

    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身份验证插件将MySQL客户端程序连接到服务器。以下各节提供了以特定方式使用PAM身份验证的说明。如安装PAM可插拔身份验证中所述,假定服务器正在启用服务器端PAM插件的情况下运行。

    要在语句的IDENTIFIED WITH子句中引用PAM身份验证插件CREATE USER,请使用name uthentication_pam。例如:

    CREATE USER user
    IDENTIFIED WITH authentication_pam
    AS ' uth_string';
    

    认证字符串指定以下类型的信息:

    • PAM服务名称(请参阅 MySQL用户的PAM身份验证如何工作)。以下讨论中的示例使用服务名称进行服务,mysql-unix以使用传统的Unix密码mysql-ldap进行身份验证,并使用LDAP进行身份验证。
    • 为了获得代理支持,PAM为PAM模块提供了一种将MySQL用户名返回给服务器的方法,该客户端用户名不是客户端程序在连接到服务器时传递的外部用户名。使用身份验证字符串来控制从外部用户名到MySQL用户名的映射。如果要利用代理用户功能,则身份验证字符串必须包括这种映射。

    例如,如果一个帐户使用mysql-unixPAM服务名称,并且应该将rootusers组中的操作系统用户分别映射到developerdata_entry用户,则使用如下语句:

    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_namepam_group_namemysql_user_name值可包含除等号,逗号或空间什么。
    • 如果一个pam_service_namepam_group_namemysql_user_name价值与双引号引用,引号之间的一切就是价值的一部分。例如,如果该值包含空格字符,则这是必需的。除双引号和反斜杠(\)外,所有字符均合法。要包含两个字符,请使用反斜杠将其转义。

    如果插件成功地验证了外部用户名(客户端传递的名称),它将在身份验证字符串中查找PAM组映射列表,如果存在,则使用该插件将基于以下内容的另一个MySQL用户名返回给MySQL服务器:外部用户属于哪个PAM组:

    • 如果身份验证字符串不包含PAM组映射列表,则插件将返回外部名称。
    • 如果验证字符串确实包含PAM组映射列表,插件检查每个列表中对由左到右,并试图找到一个匹配的分配给经过身份验证的用户和收益组的非MySQL目录值的找到的第一个匹配项。如果插件未找到任何PAM组的匹配项,则返回外部名称。如果该插件无法在目录中查找组,则它将忽略PAM组映射列表并返回外部名称。pam_group_name=mysql_user_namepam_group_namemysql_user_name

    以下各节描述如何设置使用PAM身份验证插件的几种身份验证方案:

    • 没有代理用户。这仅使用PAM来检查登录名和密码。每个允许连接到MySQL Server的外部用户都应具有一个定义为使用PAM身份验证的匹配MySQL帐户。(要与外部用户匹配的MySQL帐户,必须是外部用户名,并且必须与客户端连接的主机匹配。)可以通过各种PAM支持的方法来执行身份验证。稍后的讨论显示了如何使用传统的Unix密码和LDAP中的密码来认证客户端凭证。'user_name'@'host_name'user_namehost_name

      如果不通过代理用户或PAM组进行PAM身份验证,则要求MySQL用户名与操作系统用户名相同。MySQL用户名限制为32个字符(请参见“授权表”),这将PAM非代理身份验证限制为名称最多为32个字符的Unix帐户。

    • 仅代理用户,具有PAM组映射。对于这种情况,创建一个或多个定义不同权限集的MySQL帐户。(理想情况下,没有人应该直接使用这些帐户进行连接。)然后定义一个通过PAM进行身份验证的默认用户,该身份验证使用某种映射方案(通常基于用户所属的外部PAM组)将所有外部用户名映射到少数MySQL拥有特权集的帐户。任何连接并指定外部用户名作为客户端用户名的客户端都将映射到一个MySQL帐户并使用其特权。讨论内容显示了如何使用传统的Unix密码进行设置,

    这些方案可能会有所不同:

    • 您可以允许某些用户直接登录(不使用代理),但要求其他用户通过代理帐户连接。
    • 通过在经过PAM身份验证的帐户中使用不同的PAM服务名称,可以为某些用户使用一种PAM身份验证方法,而对其他用户使用另一种方法。例如,您可以mysql-unix为某些用户和mysql-ldap其他用户使用PAM服务。

    这些示例进行以下假设。如果您的系统设置不同,则可能需要进行一些调整。

    • 登录名和密码分别为 ntonio ntonio_password。更改它们以与您要认证的用户相对应。
    • PAM配置目录为/etc/pam.d
    • PAM服务名称对应于身份验证方法(mysql-unixmysql-ldap在本讨论中)。要使用给定的PAM服务,必须在PAM配置目录中设置一个具有相同名称的PAM文件(如果文件不存在,则创建该文件)。此外,您必须在CREATE USER使用该PAM服务进行身份验证的任何帐户的语句的身份验证字符串中命名 PAM服务。

    PAM身份验证插件在初始化时检查AUTHENTICATION_PAM_LOG服务器启动环境中是否设置了环境值。如果是这样,则插件可以将诊断消息记录到标准输出中。该消息可能会显示在控制台上或错误日志中,具体取决于服务器的启动方式。这些消息有助于调试插件执行身份验证时发生的与PAM相关的问题。有关更多信息,请参见 PAM身份验证调试。

    没有代理用户的PAM Unix密码认证

    此身份验证方案使用PAM来检查根据操作系统用户名和Unix密码定义的外部用户,而无需代理。每个允许连接到MySQL Server的此类外部用户都应具有一个匹配的MySQL帐户,该帐户定义为通过传统的Unix密码存储区使用PAM身份验证。

    注意

    使用该/etc/shadow文件检查传统的Unix密码。有关与此文件有关的可能问题的信息,请参阅《对Unix密码存储的PAM身份验证访问》。

    1. 验证Unix身份验证是否允许使用用户名 ntonio和密码登录到操作系统 ntonio_password
    2. 通过创建mysql-unix名为的PAM服务文件,设置PAM以使用传统的Unix密码对MySQL连接进行身份验证/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
      
    3. 使用与操作系统用户名相同的用户名创建一个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密码。

    4. 使用mysql命令行客户端以方式连接到MySQL服务器 ntonio。例如:

      shell>mysql --user= ntonio --password --enable-cleartext-plugin
      Enter password: ntonio_password
      

      服务器应允许连接,并且以下查询返回输出,如下所示:

      mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
      +-------------------	+-------------------	+--------------	+
      | USER()             | CURRENT_USER()     | @@proxy_user  |
      +-------------------	+-------------------	+--------------	+
      | antonio@localhost  | antonio@localhost  | NULL          |
      +-------------------	+-------------------	+--------------	+
      

      这表明 ntonio操作系统用户已通过身份验证,具有授予 ntonioMySQL用户的特权,并且未发生代理。

    注意

    客户端mysql_clear_password身份验证插件使密码保持不变,因此客户端程序将其以明文形式发送到MySQL服务器。这样可以将密码原样传递给PAM。明文密码对于使用服务器端PAM库是必需的,但在某些配置中可能是安全问题。这些措施可最大程度地降低风险:

    • 为了减少偶然使用该mysql_clear_password插件的可能性,MySQL客户端必须显式启用它(例如,使用--enable-cleartext-plugin选项)。请参见“客户端明文可插入身份验证”。
    • 为了避免在mysql_clear_password启用插件的情况下暴露密码,MySQL客户端应使用加密连接连接到MySQL服务器。请参见“配置MySQL以使用加密连接”。
    没有代理用户的PAM LDAP认证

    此身份验证方案使用PAM来检查根据操作系统用户名和LDAP密码定义的外部用户,而无需代理。每个允许连接到MySQL Server的此类外部用户都应具有一个匹配的MySQL帐户,该帐户被定义为通过LDAP使用PAM身份验证。

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

    • LDAP服务器必须可用于PAM LDAP服务进行通信。
    • 要由MySQL认证的LDAP用户必须存在于LDAP服务器管理的目录中。
    注意

    使用LDAP进行MySQL用户身份验证的另一种方法是使用特定于LDAP的身份验证插件。请参见“ LDAP可插拔身份验证”。

    配置MySQL以进行PAM LDAP身份验证,如下所示:

    1. 验证Unix身份验证是否允许使用用户名 ntonio和密码登录到操作系统 ntonio_password
    2. 通过创建mysql-ldap名为的PAM服务文件,设置PAM以使用LDAP验证MySQL连接/etc/pam.d/mysql-ldap。文件内容取决于系统,因此请检查目录中现有的与登录相关的文件,/etc/pam.d以参见其外观。在Linux上,mysql-ldap文件可能如下所示:

      #%PAM-1.0
      auth        required    pam_ldap.so
      account     required    pam_ldap.so
      

      如果PAM对象文件的后缀不同于.so系统上的后缀,请替换正确的后缀。

      在某些系统上,PAM文件格式可能有所不同。

    3. 使用与操作系统用户名相同的用户名创建一个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进行身份验证。

    4. 连接到服务器与“没有代理用户的PAM Unix密码身份验证”中描述的相同。
    使用代理用户和组映射的PAM Unix密码身份验证

    此处描述的身份验证方案使用代理和PAM组映射将使用PAM进行身份验证的MySQL用户连接到定义了不同权限集的其他MySQL帐户。用户不会直接通过定义特权的帐户进行连接。相反,它们通过使用PAM进行身份验证的默认代理帐户进行连接,这样所有外部用户都将映射到拥有特权的MySQL帐户。使用代理帐户进行连接的任何用户都将映射到这些MySQL帐户之一,这些帐户的特权确定了允许外部用户执行的数据库操作。

    此处显示的过程使用Unix密码身份验证。要改为使用LDAP,请参阅“没有代理用户的PAM LDAP身份验证”的早期步骤。

    注意

    使用该/etc/shadow文件检查传统的Unix密码。有关与此文件有关的可能问题的信息,请参阅《对Unix密码存储的PAM身份验证访问》。

    1. 验证Unix身份验证是否允许使用用户名 ntonio和密码登录到操作系统 ntonio_password
    2. 验证该用户 ntoniorootusersPAM组的成员。
    3. mysql-unix通过创建名为的文件,将PAM 设置为通过操作系统用户对PAM服务进行身份验证/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
      
    4. 创建一个默认代理用户(''@''),将外部PAM用户映射到代理帐户:

      CREATE USER ''@''
      IDENTIFIED WITH authentication_pam
      AS 'mysql-unix, root=developer, users=data_entry';
      

      此处,认证字符串包含PAM服务名称mysql-unix,用于认证Unix密码。身份验证字符串还将,rootusersPAM组中的外部用户分别映射到developerdata_entry用户名。

      设置代理用户时,需要PAM服务名称后面的PAM组映射列表。否则,该插件将无法告诉您如何执行从外部用户名到正确的代理MySQL用户名的映射。

      注意

      如果您的MySQL安装中有匿名用户,则它们可能与默认代理用户冲突。有关此问题及其处理方式的更多信息,请参见默认代理用户和匿名用户冲突。

    5. 创建代理帐户并向其授予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进行身份验证的用户将基于其PAM组使用developerdata_entry代理帐户。(这假定已安装了插件。有关说明,请参见“无登录可插入身份验证”。)有关防止代理帐户直接使用的替代方法,请参见防止直接登录代理帐户。

    6. 向代理帐户PROXY授予每个代理帐户的特权:

      GRANT PROXY
      ON 'developer'@'localhost'
      TO ''@'';
      GRANT PROXY
      ON 'data_entry'@'localhost'
      TO ''@'';
      
    7. 使用mysql命令行客户端以方式连接到MySQL服务器 ntonio

      shell>mysql --user= ntonio --password --enable-cleartext-plugin
      Enter password: ntonio_password
      

      服务器使用默认''@''代理帐户对连接进行身份验证。所产生的特权 ntonio取决于哪个PAM组 ntonio是成员。如果 ntoniorootPAM组的成员,则PAM插件将映射rootdeveloperMySQL用户名,并将该名称返回给服务器。服务器验证''@''具有PROXY特权developer并允许连接。以下查询返回输出,如下所示:

      mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
      +-------------------	+---------------------	+--------------	+
      | USER()             | CURRENT_USER()       | @@proxy_user  |
      +-------------------	+---------------------	+--------------	+
      | antonio@localhost  | developer@localhost  | ''@''         |
      +-------------------	+---------------------	+--------------	+
      

      这表明 ntonio操作系统用户已通过身份验证,具有授予developer MySQL用户的特权,并且通过默认的代理帐户进行了代理。

      如果 ntonio不是rootPAM组的成员users,而是userPAM组的成员,则会发生类似的过程,但是插件将PAM组成员关系映射到data_entry MySQL用户名,并将该名称返回给服务器:

      mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
      +-------------------	+----------------------	+--------------	+
      | USER()             | CURRENT_USER()        | @@proxy_user  |
      +-------------------	+----------------------	+--------------	+
      | antonio@localhost  | data_entry@localhost  | ''@''         |
      +-------------------	+----------------------	+--------------	+
      

      这表明已对 ntonio操作系统用户进行了身份验证以具有data_entryMySQL用户的特权,并且通过默认的代理帐户进行了代理。

    注意

    客户端mysql_clear_password身份验证插件使密码保持不变,因此客户端程序将其以明文形式发送到MySQL服务器。这样可以将密码原样传递给PAM。明文密码对于使用服务器端PAM库是必需的,但在某些配置中可能是安全问题。这些措施可最大程度地降低风险:

    • 为了减少偶然使用该mysql_clear_password插件的可能性,MySQL客户端必须显式启用它(例如,使用--enable-cleartext-plugin选项)。请参见“客户端明文可插入身份验证”。
    • 为了避免在mysql_clear_password启用插件的情况下暴露密码,MySQL客户端应使用加密连接连接到MySQL服务器。请参见“配置MySQL以使用加密连接”。
    对Unix密码存储的PAM身份验证访问

    在某些系统上,Unix身份验证使用密码存储(例如)/etc/shadow,该文件通常具有受限的访问权限。这可能导致基于MySQL PAM的身份验证失败。不幸的是,PAM实施不允许将“密码无法匹配”(例如,由于无法读取/etc/shadow)与“密码不匹配”区分开。”如果您使用Unix密码存储进行PAM身份验证,则可以使用以下方法之一从MySQL启用对它的访问:

    • 假设MySQL服务器是通过mysql操作系统帐户运行的,则将该帐户放入shadow具有/etc/shadow访问权限的组中:

      1. 在中创建shadow/etc/group
      2. mysql操作系统用户添加到中的shadow/etc/group
      3. 分配/etc/groupshadow组并启用组读取权限:

        chgrp shadow /etc/shadow
        chmod g	+r /etc/shadow
        
      4. 重新启动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身份验证调试

    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-passwordPAM服务:

    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-passwordPAM服务文件以禁用任何密码访问。