#### 6.4.1.5 PAM 可插拔身份验证

[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)

笔记

PAM 可插拔身份验证是商业产品 MySQL 企业版中包含的扩展。要了解有关商业产品的更多信息，请参阅<https://www.mysql.com/products/>.

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

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

-   外部身份验证：PAM 身份验证使 MySQL 服务器能够接受来自 MySQL 授权表之外定义的用户的连接，并使用 PAM 支持的方法进行身份验证。

-   代理用户支持：PAM 身份验证可以根据外部用户所属的 PAM 组和提供的身份验证字符串，向 MySQL 返回一个不同于客户端程序传递的外部用户名的用户名。这意味着插件可以返回定义外部 PAM 身份验证用户应具有的权限的 MySQL 用户。例如，一个操作系统用户名为`乔`可以连接并拥有名为的 MySQL 用户的权限`开发商`.

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

    下表显示了插件和库文件名。您的系统上的文件名后缀可能不同。该文件必须位于由[`插件目录`](server-system-variables.html#sysvar_plugin_dir)系统变量。有关安装信息，请参阅[安装 PAM 可插入身份验证](pam-pluggable-authentication.html#pam-pluggable-authentication-installation).

[](<>)

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

| 插件或文件 | 插件或文件名 |
| ----- | ------ |
| 服务器端插件 | `身份验证_pam` |
| 客户端插件 | `mysql_clear_password` |
| 库文件 | `authentication_pam.so` |

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

以下部分提供特定于 PAM 可插入身份验证的安装和使用信息：

-   [MySQL 用户的 PAM 身份验证如何工作](pam-pluggable-authentication.html#pam-pluggable-authentication-process)

-   [安装 PAM 可插入身份验证](pam-pluggable-authentication.html#pam-pluggable-authentication-installation)

-   [卸载 PAM 可插入身份验证](pam-pluggable-authentication.html#pam-pluggable-authentication-uninstallation)

-   [使用 PAM 可插拔身份验证](pam-pluggable-authentication.html#pam-pluggable-authentication-usage)

-   [没有代理用户的 PAM Unix 密码验证](pam-pluggable-authentication.html#pam-authentication-unix-without-proxy)

-   [没有代理用户的 PAM LDAP 身份验证](pam-pluggable-authentication.html#pam-authentication-ldap-without-proxy)

-   [使用代理用户和组映射的 PAM Unix 密码验证](pam-pluggable-authentication.html#pam-authentication-unix-with-proxy)

-   [对 Unix 密码存储的 PAM 身份验证访问](pam-pluggable-authentication.html#pam-authentication-unix-password-store)

-   [PAM 身份验证调试](pam-pluggable-authentication.html#pam-pluggable-authentication-debugging)

    有关 MySQL 中可插入身份验证的一般信息，请参阅[第 6.2.17 节，“可插拔身份验证”](pluggable-authentication.html).有关信息`mysql_clear_password`插件，见[第 6.4.1.4 节，“客户端明文可插入身份验证”](cleartext-pluggable-authentication.html).有关代理用户信息，请参阅[第 6.2.19 节，“代理用户”](proxy-users.html).

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

本节概述 MySQL 和 PAM 如何协同工作以验证 MySQL 用户。有关显示如何设置 MySQL 帐户以使用特定 PAM 服务的示例，请参阅[使用 PAM 可插拔身份验证](pam-pluggable-authentication.html#pam-pluggable-authentication-usage).

1.  客户端程序与服务器通信，客户端向服务器发送客户端用户名（默认为操作系统用户名）和密码：

    -   客户端用户名是外部用户名。

    -   对于使用 PAM 服务器端身份验证插件的帐户，对应的客户端插件是`mysql_clear_password`.此客户端插件不执行密码散列，结果客户端将密码以明文形式发送到服务器。

2.  服务器根据外部用户名和客户端连接的主机找到匹配的 MySQL 帐户。PAM 插件使用 MySQL Server 传递给它的信息（例如用户名、主机名、密码和身份验证字符串）。当您定义使用 PAM 进行身份验证的 MySQL 帐户时，身份验证字符串包含：

    -   PAM 服务名称，系统管理员可以使用该名称来指代特定应用程序的身份验证方法。可以有多个应用程序与单个数据库服务器实例相关联，因此服务名称的选择留给 SQL 应用程序开发人员。

    -   可选地，如果要使用代理，则从 PAM 组到 MySQL 用户名的映射。

3.  该插件使用身份验证字符串中命名的 PAM 服务来检查用户凭据并返回`'认证成功，用户名*`用户名`*'`要么`'身份验证失败'`.密码必须适合 PAM 服务使用的密码存储。例子：

    -   对于传统的 Unix 密码，该服务会查找存储在`/etc/影子`文件。

    -   对于 LDAP，该服务会查找存储在 LDAP 目录中的密码。

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

4.  否则，验证字符串指示是否发生代理。如果字符串不包含 PAM 组映射，则不会发生代理。在这种情况下，MySQL 用户名与外部用户名相同。

5.  否则，基于 PAM 组映射指示代理，MySQL 用户名基于映射列表中的第一个匹配组确定。“PAM 组”的含义取决于 PAM 服务。例子：

    -   对于传统的 Unix 密码，组是定义在`/etc/组`文件，可能在文件中补充了其他 PAM 信息，例如`/etc/security/group.conf`.

    -   对于 LDAP，组是在 LDAP 目录中定义的 LDAP 组。

        如果代理用户（外部用户）拥有[`代理`](privileges-provided.html#priv_proxy)代理 MySQL 用户名的特权，代理发生，代理用户承担代理用户的特权。

##### 安装 PAM 可插入身份验证

本节介绍如何安装服务器端 PAM 身份验证插件。有关安装插件的一般信息，请参阅[第 5.6.1 节，“安装和卸载插件”](plugin-loading.html).

要被服务器使用，插件库文件必须位于 MySQL 插件目录（由[`插件目录`](server-system-variables.html#sysvar_plugin_dir)系统变量）。如有必要，通过设置值来配置插件目录位置[`插件目录`](server-system-variables.html#sysvar_plugin_dir)在服务器启动时。

插件库文件的基本名称是`身份验证_pam`.文件名后缀因平台而异（例如，`。所以`对于 Unix 和类 Unix 系统，`.dll`对于 Windows）。

要在服务器启动时加载插件，请使用[`--plugin-load-add`](server-options.html#option_mysqld_plugin-load-add)选项来命名包含它的库文件。使用这种插件加载方法，每次服务器启动时都必须给出该选项。例如，将这些行放在服务器中`我的.cnf`文件，调整`。所以`根据需要为您的平台添加后缀：

```
[mysqld]
plugin-load-add=authentication_pam.so
```

修改后`我的.cnf`, 重启服务器使新设置生效。

或者，要在运行时加载插件，请使用此语句，调整`。所以`根据需要为您的平台添加后缀：

```
INSTALL PLUGIN authentication_pam SONAME 'authentication_pam.so';
```

[`安装插件`](install-plugin.html)立即加载插件，并将其注册到`mysql.plugins`系统表，以使服务器在每次后续正常启动时加载它，而无需[`--plugin-load-add`](server-options.html#option_mysqld_plugin-load-add).

要验证插件安装，请检查[`INFORMATION_SCHEMA.PLUGINS`](information-schema-plugins-table.html)表或使用[`显示插件`](show-plugins.html)声明（见[第 5.6.2 节，“获取服务器插件信息”](obtaining-plugin-information.html)）。例如：

```
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-pluggable-authentication.html#pam-pluggable-authentication-usage).

##### 卸载 PAM 可插入身份验证

用于卸载 PAM 身份验证插件的方法取决于您的安装方式：

-   如果您在服务器启动时使用[`--plugin-load-add`](server-options.html#option_mysqld_plugin-load-add)选项，在没有选项的情况下重新启动服务器。

-   如果您在运行时使用[`安装插件`](install-plugin.html)声明，它仍然在服务器重新启动时安装。要卸载它，请使用[`卸载插件`](uninstall-plugin.html)：

    ```
    UNINSTALL PLUGIN authentication_pam;
    ```

##### 使用 PAM 可插拔身份验证

本节概括介绍如何使用 PAM 身份验证插件从 MySQL 客户端程序连接到服务器。以下部分提供了有关以特定方式使用 PAM 身份验证的说明。假设服务器在启用服务器端 PAM 插件的情况下运行，如中所述[安装 PAM 可插入身份验证](pam-pluggable-authentication.html#pam-pluggable-authentication-installation).

要参考 PAM 身份验证插件`标识为`a的从句[`创建用户`](create-user.html)声明，使用名称`身份验证_pam`.例如：

```
CREATE USER user
  IDENTIFIED WITH authentication_pam
  AS 'auth_string';
```

身份验证字符串指定以下类型的信息：

-   PAM 服务名称（请参阅[MySQL 用户的 PAM 身份验证如何工作](pam-pluggable-authentication.html#pam-pluggable-authentication-process)）。以下讨论中的示例使用服务名称`mysql-unix`使用传统的 Unix 密码进行身份验证，以及`mysql-ldap`使用 LDAP 进行身份验证。

-   对于代理支持，PAM 提供了一种方法让 PAM 模块向服务器返回 MySQL 用户名，而不是客户端程序在连接到服务器时传递的外部用户名。使用身份验证字符串来控制从外部用户名到 MySQL 用户名的映射。如果您想利用代理用户功能，身份验证字符串必须包含这种映射。

    例如，如果一个帐户使用`mysql-unix`PAM 服务名称，并应映射操作系统用户`根`和`用户`PAM 组到`开发商`和`数据输入`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\_用户名`*`配对前必须加逗号。

-   不在双引号内的前导空格和尾随空格将被忽略。

-   无报价*`pam_服务_名称`*,*`pam_组_名称`*和*`mysql_用户名`*值可以包含除等号、逗号或空格以外的任何内容。

-   如果*`pam_服务_名称`*,*`pam_组_名称`*或*`mysql_用户名`*值用双引号引用，引号之间的所有内容都是值的一部分。例如，如果值包含空格字符，这是必需的。除双引号和反斜杠外，所有字符均合法(`\`).若要包含任一字符，请使用反斜杠将其转义。

    如果插件成功验证了外部用户名（客户端传递的名称），它会在验证字符串中查找PAM组映射列表，如果存在，则使用该列表将不同的MySQL用户名返回到MySQL服务器，外部用户基于该服务器的PAM组成员：

-   如果认证字符串不包含PAM组映射列表，插件将返回外部名称。

-   如果身份验证字符串确实包含PAM组映射列表，则插件会检查每个列表`*`pam\_组\_名称`*=*`mysql\_用户名`*`在列表中从左到右配对，并尝试为*`pam_组_名称`*非MySQL目录中分配给经过身份验证的用户的组的值，并返回*`mysql_用户名`*它找到的第一个匹配项。如果插件找不到任何PAM组的匹配项，它将返回外部名称。如果插件无法在目录中查找组，它将忽略PAM组映射列表并返回外部名称。

    以下部分描述了如何设置使用PAM身份验证插件的多个身份验证场景：

-   没有代理用户。这只使用PAM检查登录名和密码。每个被允许连接到MySQL服务器的外部用户都应该有一个匹配的MySQL帐户，该帐户被定义为使用PAM身份验证。（对于MySQL帐户）`'*`用户名`*'@'*`主机名`*'`为了匹配外部用户，*`用户名`*必须是外部用户名和*`主机名`*必须与客户端连接的主机匹配。）身份验证可以通过各种PAM支持的方法执行。后面的讨论将展示如何使用传统的Unix密码和LDAP中的密码验证客户端凭据。

    当不通过代理用户或PAM组进行PAM身份验证时，要求MySQL用户名与操作系统用户名相同。MySQL用户名限制为32个字符（请参阅[第6.2.3节“拨款表”](grant-tables.html))，它将PAM非代理身份验证限制为名称最多32个字符的Unix帐户。

-   仅限代理用户，使用PAM组映射。对于这种情况，创建一个或多个定义不同权限集的MySQL帐户。（理想情况下，任何人都不应该直接使用这些帐户进行连接。）然后定义一个通过PAM进行身份验证的默认用户，该用户使用某种映射方案（通常基于用户所属的外部PAM组）将所有外部用户名映射到持有特权集的几个MySQL帐户。任何连接并指定外部用户名作为客户端用户名的客户端都会映射到一个MySQL帐户并使用其权限。讨论展示了如何使用传统的Unix密码进行设置，但也可以使用LDAP等其他PAM方法。

    这些场景可能会发生变化：

-   您可以允许一些用户直接登录（无需代理），但需要其他用户通过代理帐户进行连接。

-   通过在经过PAM身份验证的帐户中使用不同的PAM服务名称，可以对某些用户使用一种PAM身份验证方法，对其他用户使用另一种方法。例如，您可以使用`mysql unix`一些用户的PAM服务，以及`mysql ldap`对其他人来说。

    这些例子做出了以下假设。如果系统设置不同，可能需要进行一些调整。

-   登录名和密码是`安东尼奥`和*`antonio_密码`*分别地将其更改为与要验证的用户相对应。

-   PAM配置目录是`/etc/pam。D`.

-   PAM服务名称对应于身份验证方法(`mysql unix`或`mysql ldap`在本讨论中）。要使用给定的PAM服务，必须在PAM配置目录中设置一个同名的PAM文件（如果该文件不存在，则创建该文件）。此外，必须在[`创建用户`](create-user.html)任何使用PAM服务进行身份验证的帐户的声明。

    PAM身份验证插件在初始化时检查`身份验证\u PAM\u日志`环境值在服务器的启动环境中设置。如果是这样，该插件可以将诊断消息记录到标准输出中。根据服务器的启动方式，消息可能会出现在控制台或错误日志中。这些消息有助于调试插件执行身份验证时发生的与PAM相关的问题。有关更多信息，请参阅[PAM身份验证调试](pam-pluggable-authentication.html#pam-pluggable-authentication-debugging).

##### 不使用代理用户的PAM Unix密码身份验证

此身份验证场景使用PAM检查根据操作系统用户名和Unix密码定义的外部用户，无需代理。每个被允许连接到MySQL服务器的外部用户都应该有一个匹配的MySQL帐户，该帐户被定义为通过传统的Unix密码存储使用PAM身份验证。

笔记

使用`/等/影子`文件有关与此文件相关的可能问题的信息，请参阅[对Unix密码存储的PAM身份验证访问](pam-pluggable-authentication.html#pam-authentication-unix-password-store).

1.  验证Unix身份验证是否允许使用用户名登录操作系统`安东尼奥`密码*`antonio_密码`*.

2.  通过创建`mysql unix`PAM服务文件名为`/etc/pam。d/mysql unix`。文件内容取决于系统，因此请检查中现有的登录相关文件`/etc/pam。D`查看它们的外观。在Linux上`mysql unix`文件可能如下所示：

    ```
    #%PAM-1.0
    auth            include         password-auth
    account         include         password-auth
    ```

    对于macOS，使用`登录`而不是`密码验证`.

    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.html)命令行客户端连接到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         |
    +-------------------+-------------------+--------------+
    ```

    这表明`安东尼奥`操作系统用户经过身份验证，具有授予`安东尼奥`MySQL用户，并且没有发生代理。

笔记

客户端`mysql\u清除\u密码`身份验证插件保持密码不变，因此客户端程序将其以明文形式发送到MySQL服务器。这样就可以将密码按原样传递给PAM。使用服务器端PAM库需要明文密码，但在某些配置中可能存在安全问题。这些措施将风险降至最低：

-   无意中使用`mysql\u清除\u密码`插件不太可能，MySQL客户端必须显式启用它（例如，使用`--启用明文插件`选项）。看见[第6.4.1.4节，“客户端明文可插入身份验证”](cleartext-pluggable-authentication.html).

-   以避免使用`mysql\u清除\u密码`启用插件后，MySQL客户端应使用加密连接连接到MySQL服务器。看见[第6.3.1节，“配置MySQL以使用加密连接”](using-encrypted-connections.html).

##### 无代理用户的PAM LDAP身份验证

此身份验证场景使用PAM检查根据操作系统用户名和LDAP密码定义的外部用户，无需代理。每个被允许连接到MySQL服务器的外部用户都应该有一个匹配的MySQL帐户，该帐户被定义为通过LDAP使用PAM身份验证。

要对MySQL使用PAM LDAP可插拔身份验证，必须满足以下先决条件：

-   必须有LDAP服务器，PAM LDAP服务才能与之通信。

-   要通过MySQL进行身份验证的每个LDAP用户必须位于LDAP服务器管理的目录中。

笔记

使用LDAP进行MySQL用户身份验证的另一种方法是使用特定于LDAP的身份验证插件。看见[第6.4.1.7节，“LDAP可插拔身份验证”](ldap-pluggable-authentication.html).

将MySQL配置为PAM LDAP身份验证，如下所示：

1.  验证Unix身份验证是否允许使用用户名登录操作系统`安东尼奥`密码*`antonio_密码`*.

2.  通过创建`mysql ldap`PAM服务文件名为`/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对象文件的后缀不同于`所以`在您的系统上，替换正确的后缀。

    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-pluggable-authentication.html#pam-authentication-unix-without-proxy).

##### 使用代理用户和组映射的PAM Unix密码身份验证

[](<>)

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

此处显示的过程使用Unix密码身份验证。要改用LDAP，请参阅[无代理用户的PAM LDAP身份验证](pam-pluggable-authentication.html#pam-authentication-ldap-without-proxy).

笔记

使用`/等/影子`文件有关与此文件相关的可能问题的信息，请参阅[对Unix密码存储的PAM身份验证访问](pam-pluggable-authentication.html#pam-authentication-unix-password-store).

1.  验证Unix身份验证是否允许使用用户名登录操作系统`安东尼奥`密码*`antonio_密码`*.

2.  核实一下`安东尼奥`是该组织的成员`根`或`用户`帕姆集团。

3.  设置PAM以验证`mysql unix`PAM服务通过操作系统用户创建一个名为`/etc/pam。d/mysql unix`。文件内容取决于系统，因此请检查中现有的登录相关文件`/etc/pam。D`查看它们的外观。在Linux上`mysql unix`文件可能如下所示：

    ```
    #%PAM-1.0
    auth            include         password-auth
    account         include         password-auth
    ```

    对于macOS，使用`登录`而不是`密码验证`.

    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密码。身份验证字符串还映射`根`和`用户`帕姆把两组人带到`开发商`和`数据输入`分别是MySQL用户名。

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

    笔记

    如果你的MySQL安装有匿名用户，他们可能会与默认的代理用户冲突。有关此问题及其处理方法的更多信息，请参阅[默认代理用户和匿名用户冲突](proxy-users.html#proxy-users-conflicts).

5.  创建代理帐户并向每个帐户授予其应有的特权：

    ```
    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\u无\u登录`身份验证插件，防止客户端使用帐户直接登录MySQL服务器。相反，使用PAM进行身份验证的用户应该使用`开发商`或`数据输入`基于PAM组的代理帐户。（假设插件已安装。有关说明，请参阅[第6.4.1.9节，“无登录可插拔身份验证”](no-login-pluggable-authentication.html)）有关保护代理帐户不被直接使用的替代方法，请参阅[阻止直接登录代理帐户](proxy-users.html#preventing-proxied-account-direct-login).

6.  向代理帐户授予[`代理`](privileges-provided.html#priv_proxy)每个代理帐户的权限：

    ```
    GRANT PROXY
      ON 'developer'@'localhost'
      TO ''@'';
    GRANT PROXY
      ON 'data_entry'@'localhost'
      TO ''@'';
    ```

7.  使用[**mysql**](mysql.html)命令行客户端连接到MySQL服务器`安东尼奥`.

    ```
    $> mysql --user=antonio --password --enable-cleartext-plugin
    Enter password: antonio_password
    ```

    服务器使用默认值对连接进行身份验证`''@''`代理账户。由此产生的特权`安东尼奥`取决于PAM组`安东尼奥`是…的一员。如果`安东尼奥`是该组织的成员`根`PAM组，PAM插件映射`根`到`开发商`MySQL用户名并将该名称返回给服务器。服务器会验证这一点`''@''`有[`代理`](privileges-provided.html#priv_proxy)特权`开发商`并允许连接。以下查询返回输出，如下所示：

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

    这表明`安东尼奥`操作系统用户经过身份验证以具有授予`开发商`MySQL 用户，并且该代理通过默认代理帐户进行。

    如果`安东尼奥`不是`根`PAM 组，但属于`用户`PAM 组，发生类似的过程，但插件映射`用户`PAM 组成员资格`数据输入`MySQL 用户名并将该名称返回给服务器：

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

    这表明`安东尼奥`操作系统用户经过身份验证具有以下权限`数据输入`MySQL 用户，并且该代理通过默认代理帐户进行。

笔记

客户端`mysql_clear_password`身份验证插件保持密码不变，因此客户端程序将其以明文形式发送到 MySQL 服务器。这使密码能够按原样传递给 PAM。使用服务器端 PAM 库需要明文密码，但在某些配置中可能存在安全问题。这些措施将风险降至最低：

-   无意中使用`mysql\u清除\u密码`插件不太可能，MySQL客户端必须显式启用它（例如，使用`--启用明文插件`选项）。看见[第6.4.1.4节，“客户端明文可插入身份验证”](cleartext-pluggable-authentication.html).

-   以避免使用`mysql\u清除\u密码`启用插件后，MySQL客户端应使用加密连接连接到MySQL服务器。看见[第6.3.1节，“配置MySQL以使用加密连接”](using-encrypted-connections.html).

##### 对Unix密码存储的PAM身份验证访问

在某些系统上，Unix身份验证使用密码存储，例如`/等/影子`，一个通常具有受限访问权限的文件。这可能会导致基于MySQL PAM的身份验证失败。不幸的是，PAM实现不允许区分“无法检查密码”（例如，由于无法读取密码）`/等/影子`)来自“密码不匹配”如果您使用Unix密码存储进行PAM身份验证，则可以使用以下方法之一从MySQL访问它：

-   假设MySQL服务器是从`mysql`操作系统帐户，将该帐户放入`阴影`拥有`/等/影子`访问：

    1.  创建一个`阴影`加入`/等/组`.

    2.  添加`mysql`操作系统用户`阴影`分组`/etc/组`.

    3.  分配`/etc/组`到`阴影`组并启用组读取权限：

        ```
        chgrp shadow /etc/shadow
        chmod g+r /etc/shadow
        ```

    4.  重新启动 MySQL 服务器。

-   如果您正在使用`pam_unix`模块和**unix\_密码**实用程序，启用密码存储访问，如下所示：

    ```
    chmod u-s /usr/sbin/unix_chkpwd
    setcap cap_dac_read_search+ep /usr/sbin/unix_chkpwd
    ```

    调整路径为**unix\_密码**根据您的平台的需要。

##### PAM 身份验证调试

[](<>)[](<>)

PAM 身份验证插件在初始化时检查是否`AUTHENTICATION_PAM_LOG`设置环境值（值无关紧要）。如果是这样，该插件允许将诊断消息记录到标准输出。这些消息可能有助于调试插件执行身份验证时发生的与 PAM 相关的问题。

一些消息包括对 PAM 插件源文件和行号的引用，这使插件操作能够更紧密地与代码中它们发生的位置相关联。

调试连接失败和确定连接尝试期间发生的情况的另一种技术是将 PAM 身份验证配置为允许所有连接，然后检查系统日志文件。这种技术应该只用于*暂时的*基础，而不是在生产服务器上。

配置一个名为的 PAM 服务文件`/etc/pam.d/mysql-any-password`包含这些内容（某些系统上的格式可能不同）：

```
#%PAM-1.0
auth        required    pam_permit.so
account     required    pam_permit.so
```

创建一个使用 PAM 插件的帐户并命名`mysql-任何密码`PAM 服务：

```
CREATE USER 'testuser'@'localhost'
  IDENTIFIED WITH authentication_pam
  AS 'mysql-any-password';
```

这`mysql-任何密码`service 文件会导致任何身份验证尝试返回 true，即使密码不正确也是如此。如果身份验证尝试失败，则说明配置问题出在 MySQL 端。否则，问题出在操作系统/PAM 方面。要查看可能发生的情况，请检查系统日志文件，例如`/var/log/安全`,`/var/log/audit.log`,`/var/log/系统日志`， 要么`/var/log/消息`.

确定问题所在后，删除`mysql-任何密码`PAM 服务文件以禁用任何密码访问。
