MySQL8 中文参考(二十六)(1)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
运维安全中心(堡垒机),免费版 6个月
简介: MySQL8 中文参考(二十六)


原文:docs.oracle.com/javase/tutorial/reallybigindex.html

原文:dev.mysql.com/doc/refman/8.0/en/sha256-pluggable-authentication.html

8.4.1.3 SHA-256 可插拔认证

MySQL 提供了两个认证插件,用于实现 SHA-256 哈希算法对用户账户密码进行加密:

  • sha256_password:实现基本的 SHA-256 认证。
  • caching_sha2_password:实现 SHA-256 认证(类似于sha256_password),但在服务器端使用缓存以提高性能,并具有更广泛适用性的附加功能。

本节描述了原始的非缓存 SHA-2 认证插件。有关缓存插件的信息,请参见第 8.4.1.2 节,“缓存 SHA-2 可插拔认证”。

重要提示

在 MySQL 8.0 中,默认认证插件为caching_sha2_password而不是mysql_native_password。有关此更改对服务器操作以及服务器与客户端和连接器的兼容性的影响的信息,请参见 caching_sha2_password 作为首选认证插件。

由于caching_sha2_password是 MySQL 8.0 中的默认认证插件,并提供了sha256_password认证插件的全部功能,因此sha256_password已被弃用;预计在未来的 MySQL 版本中将其移除。使用sha256_password进行认证的 MySQL 账户应迁移到使用caching_sha2_password

重要提示

要使用使用sha256_password插件进行认证连接到服务器,您必须使用支持密码交换的 TLS 连接或 RSA 密钥对的非加密连接,如本节后面描述的那样。无论哪种方式,sha256_password插件都使用 MySQL 的加密功能。参见第 8.3 节,“使用加密连接”。

注意

sha256_password中,“sha256”指的是插件用于加密的 256 位摘要长度。在caching_sha2_password中,“sha2”更普遍地指 SHA-2 类加密算法,256 位加密是其中的一个实例。后者的名称选择为未来扩展可能的摘要长度留出了空间,而不更改插件名称。

以下表格显示了服务器端和客户端端的插件名称。

表 8.18 SHA-256 认证的插件和库名称

插件或文件 插件或文件名
服务器端插件 sha256_password
客户端端插件 sha256_password
库文件 无(插件已内置)

以下各节提供了特定于 SHA-256 可插拔认证的安装和使用信息:

  • 安装 SHA-256 可插拔认证
  • 使用 SHA-256 可插拔认证

有关 MySQL 中可插拔认证的一般信息,请参见第 8.2.17 节,“可插拔认证”。

安装 SHA-256 可插拔认证

sha256_password插件以服务器和客户端形式存在:

  • 服务器端插件内置于服务器中,无需显式加载,并且无法通过卸载来禁用。
  • 客户端端插件内置于libmysqlclient客户端库中,并可供链接到libmysqlclient的任何程序使用。
使用 SHA-256 可插拔认证

要设置使用sha256_password插件进行 SHA-256 密码哈希的帐户,请使用以下语句,其中*password*是所需的帐户密码:

CREATE USER 'sha256user'@'localhost'
IDENTIFIED WITH sha256_password BY '*password*';

服务器将sha256_password插件分配给帐户,并使用它使用 SHA-256 加密密码,将这些值存储在mysql.user系统表的pluginauthentication_string列中。

上述说明不假设sha256_password是默认认证插件。如果sha256_password是默认认证插件,则可以使用更简单的CREATE USER语法。

要将服务器的默认认证插件设置为sha256_password启动服务器,请在服务器选项文件中添加以下行:

[mysqld]
default_authentication_plugin=sha256_password

这将导致默认情况下新帐户使用sha256_password插件。因此,可以创建帐户并设置其密码而无需明确命名插件:

CREATE USER 'sha256user'@'localhost' IDENTIFIED BY '*password*';

default_authentication_plugin设置为sha256_password的另一个后果是,要使用其他插件进行帐户创建,必须明确指定该插件。例如,要使用mysql_native_password插件,请使用以下语句:

CREATE USER 'nativeuser'@'localhost'
IDENTIFIED WITH mysql_native_password BY '*password*';

sha256_password支持通过安全传输进行连接。如果 MySQL 使用 OpenSSL 编译,并且要连接的 MySQL 服务器配置为支持 RSA(使用本节后面给出的 RSA 配置过程),sha256_password还支持在未加密连接上使用 RSA 进行加密密码交换。

RSA 支持具有以下特征:

  • 在服务器端,两个系统变量命名 RSA 私钥和公钥对文件:sha256_password_private_key_pathsha256_password_public_key_path。如果要使用与系统变量默认值不同的名称的密钥文件,数据库管理员必须在服务器启动时设置这些变量。
  • 服务器使用sha256_password_auto_generate_rsa_keys系统变量来确定是否自动生成 RSA 密钥对文件。请参阅第 8.3.3 节,“创建 SSL 和 RSA 证书和密钥”。
  • Rsa_public_key状态变量显示sha256_password认证插件使用的 RSA 公钥值。
  • 拥有 RSA 公钥的客户端可以在连接过程中与服务器执行基于 RSA 密钥对的密码交换,如后文所述。
  • 对于使用sha256_password和 RSA 密钥对进行密码交换进行身份验证的帐户的连接,服务器根据需要向客户端发送 RSA 公钥。但是,如果客户端主机上有公钥的副本,则客户端可以使用它来节省客户端/服务器协议中的往返:
  • 对于这些命令行客户端,请使用--server-public-key-path选项来指定 RSA 公钥文件:mysql, mysqladmin, mysqlbinlog, mysqlcheck, mysqldump, mysqlimport, mysqlpump, mysqlshow, mysqlslap, mysqltest, mysql_upgrade.
  • 对于使用 C API 的程序,请调用mysql_options()来通过传递MYSQL_SERVER_PUBLIC_KEY选项和文件名指定 RSA 公钥文件。
  • 对于副本,使用CHANGE REPLICATION SOURCE TO语句(从 MySQL 8.0.23 开始)或CHANGE MASTER TO语句(在 MySQL 8.0.23 之前)与SOURCE_PUBLIC_KEY_PATH | MASTER_PUBLIC_KEY_PATH选项来指定 RSA 公钥文件。对于组复制,group_replication_recovery_get_public_key系统变量具有相同的作用。

对于使用sha256_password插件的客户端,在连接到服务器时,密码永远不会以明文形式暴露。密码传输的方式取决于是否使用安全连接或 RSA 加密:

  • 如果连接是安全的,则不需要使用 RSA 密钥对,也不会使用。这适用于使用 TLS 加密的连接。密码以明文形式发送,但无法被窃听,因为连接是安全的。
    注意
    caching_sha2_password不同,sha256_password插件不将共享内存连接视为安全,即使共享内存传输默认安全。
  • 如果连接不安全,并且存在 RSA 密钥对,则连接保持未加密。这适用于未使用 TLS 加密的连接。RSA 仅用于客户端和服务器之间的密码交换,以防止密码窃听。当服务器接收到加密密码时,它会对其进行解密。在加密中使用了一种混淆以防止重复攻击。
  • 如果未使用安全连接且不可用 RSA 加密,则连接尝试将失败,因为密码无法在未以明文形式暴露的情况下发送。

注意

要使用sha256_password进行 RSA 密码加密,客户端和服务器都必须使用 OpenSSL 进行编译,而不仅仅是其中一个。

假设 MySQL 已使用 OpenSSL 编译,请使用以下过程在客户端连接过程中启用 RSA 密钥对用于密码交换:

  1. 使用 Section 8.3.3, “Creating SSL and RSA Certificates and Keys”中的说明创建 RSA 私钥和公钥对文件。
  2. 如果私钥和公钥文件位于数据目录中,并且命名为private_key.pempublic_key.pemsha256_password_private_key_pathsha256_password_public_key_path系统变量的默认值),服务器将在启动时自动使用它们。
    否则,要显式命名关键文件,请在服务器选项文件中设置系统变量为关键文件名。如果文件位于服务器数据目录中,则无需指定其完整路径名:
[mysqld]
sha256_password_private_key_path=myprivkey.pem
sha256_password_public_key_path=mypubkey.pem
  1. 如果密钥文件不位于数据目录中,或者要在系统变量值中明确它们的位置,请使用完整路径名:
[mysqld]
sha256_password_private_key_path=/usr/local/mysql/myprivkey.pem
sha256_password_public_key_path=/usr/local/mysql/mypubkey.pem
  1. 重新启动服务器,然后连接到服务器并检查Rsa_public_key状态变量值。实际显示的值与此处显示的值不同,但应为非空:
mysql> SHOW STATUS LIKE 'Rsa_public_key'\G
*************************** 1\. row ***************************
Variable_name: Rsa_public_key
        Value: -----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO9nRUDd+KvSZgY7cNBZMNpwX6
MvE1PbJFXO7u18nJ9lwc99Du/E7lw6CVXw7VKrXPeHbVQUzGyUNkf45Nz/ckaaJa
aLgJOBCIDmNVnyU54OT/1lcs2xiyfaDMe8fCJ64ZwTnKbY2gkt1IMjUAB5Ogd5kJ
g8aV7EtKwyhHb0c30QIDAQAB
-----END PUBLIC KEY-----
  1. 如果值为空,则服务器发现密钥文件存在问题。请检查错误日志以获取诊断信息。

在服务器配置了 RSA 密钥文件之后,使用sha256_password插件进行身份验证的帐户可以选择使用这些密钥文件连接到服务器。如前所述,这些帐户可以使用安全连接(在这种情况下不使用 RSA)或使用 RSA 执行密码交换的未加密连接。假设使用未加密连接。例如:

$> mysql --ssl-mode=DISABLED -u sha256user -p
Enter password: *password*

对于sha256user的此连接尝试,服务器确定sha256_password是适当的身份验证插件并调用它(因为在CREATE USER时指定了该插件)。插件发现连接未加密,因此需要使用 RSA 加密传输密码。在这种情况下,插件将 RSA 公钥发送给客户端,客户端使用它加密密码并将结果返回给服务器。插件在服务器端使用 RSA 私钥解密密码,并根据密码是否正确接受或拒绝连接。

服务器根据需要向客户端发送 RSA 公钥。但是,如果客户端有包含服务器所需的 RSA 公钥的本地副本的文件,可以使用--server-public-key-path选项指定该文件:

$> mysql --ssl-mode=DISABLED -u sha256user -p --server-public-key-path=*file_name*
Enter password: *password*

--server-public-key-path选项指定的文件中的公钥值应与由sha256_password_public_key_path系统变量指定的服务器端文件中的密钥值相同。如果密钥文件包含有效的公钥值但值不正确,则会发生访问被拒绝的错误。如果密钥文件不包含有效的公钥,则客户端程序无法使用它。在这种情况下,sha256_password插件将向客户端发送公钥,就好像没有指定--server-public-key-path选项一样。

客户端用户可以通过两种方式获取 RSA 公钥:

  • 数据库管理员可以提供公钥文件的副本。
  • 客户端用户可以通过其他方式连接到服务器,使用SHOW STATUS LIKE 'Rsa_public_key'语句并将返回的密钥值保存在文件中。

原文:dev.mysql.com/doc/refman/8.0/en/cleartext-pluggable-authentication.html

8.4.1.4 客户端端明文可插拔身份验证

有一个客户端身份验证插件可用,使客户端可以将密码以明文形式发送到服务器,而无需进行哈希或加密。此插件内置于 MySQL 客户端库中。

以下表格显示了插件名称。

Table 8.19 Plugin and Library Names for Cleartext Authentication

插件或文件 插件或文件名
服务器端插件 无,请参见讨论
客户端插件 mysql_clear_password
库文件 无(插件内置)

许多客户端身份验证插件在客户端将密码发送到服务器之前对密码进行哈希或加密。这使客户端可以避免以明文形式发送密码。

对于需要服务器接收客户端输入的密码的身份验证方案,无法进行哈希或加密。在这种情况下,将使用客户端端的mysql_clear_password插件,该插件使客户端可以将密码以明文形式发送到服务器。没有相应的服务器端插件。相反,mysql_clear_password可以与需要明文密码的任何服务器端插件一起在客户端端使用(例如  PAM 和简单的 LDAP 身份验证插件;请参见 Section 8.4.1.5, “PAM Pluggable  Authentication”,以及 Section 8.4.1.7, “LDAP Pluggable Authentication”)。

下面的讨论提供了特定于明文插件身份验证的使用信息。有关 MySQL 中可插拔身份验证的一般信息,请参见 Section 8.2.17, “Pluggable Authentication”。

注意

在某些配置中,以明文形式发送密码可能会带来安全问题。为避免问题,如果存在密码可能被拦截的可能性,客户端应该使用一种保护密码的方法连接到  MySQL 服务器。可能的方法包括 SSL(请参见 Section 8.3, “Using Encrypted  Connections”)、IPsec 或私有网络。

为了减少意外使用mysql_clear_password插件的可能性,MySQL 客户端必须显式启用它。可以通过几种方式实现:

  • LIBMYSQL_ENABLE_CLEARTEXT_PLUGIN环境变量设置为以1Yy开头的值。这将为所有客户端连接启用该插件。
  • mysql, mysqladmin, mysqlcheck, mysqldump, mysqlshow, 以及 mysqlslap 客户端程序支持 --enable-cleartext-plugin 选项,可以在每次调用时启用该插件。
  • mysql_options() C API 函数支持 MYSQL_ENABLE_CLEARTEXT_PLUGIN 选项,可以在每个连接上启用该插件。此外,任何使用 libmysqlclient 并读取选项文件的程序都可以通过在客户端库读取的选项组中包含 enable-cleartext-plugin 选项来启用该插件。

原文:dev.mysql.com/doc/refman/8.0/en/pam-pluggable-authentication.html

8.4.1.5 PAM 可插入认证

注意

PAM 可插入认证是 MySQL 企业版中包含的扩展,是一款商业产品。要了解更多关于商业产品的信息,请参阅www.mysql.com/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.20 PAM 认证的插件和库名称

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

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

以下部分提供了特定于 PAM 可插入认证的安装和使用信息:

  • MySQL 用户 PAM 认证工作原理
  • 安装 PAM 可插拔认证
  • 卸载 PAM 可插拔认证
  • 使用 PAM 可插拔认证
  • 无代理用户的 PAM Unix 密码认证
  • 无代理用户的 PAM LDAP 认证
  • 带有代理用户和组映射的 PAM Unix 密码认证
  • 访问 Unix 密码存储的 PAM 认证
  • PAM 认证调试

关于 MySQL 中可插拔认证的一般信息,请参见第 8.2.17 节,“可插拔认证”。关于mysql_clear_password插件的信息,请参见第 8.4.1.4 节,“客户端明文可插拔认证”。有关代理用户信息,请参见第 8.2.19 节,“代理用户”。

MySQL 用户的 PAM 认证工作原理

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

  1. 客户端程序和服务器进行通信,客户端向服务器发送客户端用户名(默认为操作系统用户名)和密码:
  • 客户端用户名为外部用户名。
  • 对于使用 PAM 服务器端认证插件的帐户,相应的客户端插件是mysql_clear_password。这个客户端插件不执行密码哈希处理,结果客户端将密码以明文形式发送到服务器。
  1. 服务器根据客户端连接的外部用户名和主机找到匹配的 MySQL 帐户。PAM 插件使用 MySQL 服务器传递给它的信息(如用户名、主机名、密码和认证字符串)。当您定义一个使用 PAM 进行身份验证的 MySQL 帐户时,认证字符串包含:
  • PAM 服务名称,这是系统管理员可以用来引用特定应用程序的身份验证方法的名称。可以将多个应用程序关联到单个数据库服务器实例,因此服务名称的选择留给 SQL 应用程序开发人员。
  • 可选地,如果要使用代理,可以从 PAM 组到 MySQL 用户名的映射。
  1. 该插件使用认证字符串中命名的 PAM 服务来检查用户凭据,并返回'Authentication succeeded, Username is *user_name*''Authentication failed'。密码必须适用于 PAM 服务使用的密码存储。示例:
  • 对于传统的 Unix 密码,服务查找存储在/etc/shadow文件中的密码。
  • 对于 LDAP,服务查找存储在 LDAP 目录中的密码。
  1. 如果凭据检查失败,服务器将拒绝连接。
  2. 否则,认证字符串指示是否进行代理。如果字符串不包含 PAM 组映射,则不会进行代理。在这种情况下,MySQL 用户名与外部用户名相同。
  3. 否则,根据 PAM 组映射指示代理,MySQL 用户名根据映射列表中的第一个匹配组确定。“PAM 组”的含义取决于 PAM 服务。示例:
  • 对于传统的 Unix 密码,组是在/etc/group文件中定义的 Unix 组,可能在诸如/etc/security/group.conf之类的文件中补充了其他 PAM 信息。
  • 对于 LDAP,组是在 LDAP 目录中定义的 LDAP 组。
  1. 如果代理用户(外部用户)对被代理的 MySQL 用户名具有PROXY权限,则进行代理,代理用户承担被代理用户的权限。
安装 PAM 可插拔认证

本节描述了如何安装服务器端 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

要验证插件安装,请检查信息模式PLUGINS表或使用SHOW PLUGINS语句(参见 Section 7.6.2, “Obtaining Server Plugin Information”)。例如:

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 可插拔认证中所述。

要在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 用户名。使用认证字符串来控制从外部用户名到 MySQL 用户名的映射。如果要利用代理用户功能,认证字符串必须包含这种映射。

例如,如果一个账户使用mysql-unix PAM 服务名称,并且应该将rootusers PAM 组中的操作系统用户映射到developerdata_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_namepam_group_namemysql_user_name*值可以包含除等号、逗号或空格之外的任何内容。
  • 如果*pam_service_namepam_group_namemysql_user_name*值用双引号引起来,引号之间的所有内容都是值的一部分。例如,如果值包含空格字符,则这是必要的。所有字符都是合法的,除了双引号和反斜杠(\)。要包含这两个字符,用反斜杠进行转义。

如果插件成功验证外部用户名(客户端传递的名称),它会查找认证字符串中的 PAM 组映射列表,并且如果存在,则根据外部用户所属的 PAM 组返回不同的 MySQL 用户名给 MySQL 服务器:

  • 如果认证字符串不包含 PAM 组映射列表,则插件返回外部名称。
  • 如果认证字符串包含 PAM 组映射列表,则插件会从左到右检查列表中的每个*pam_group_name*=*mysql_user_name*对,并尝试在已认证用户分配的非 MySQL 目录中找到*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 节,“授权表”),这限制了 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-unixmysql-ldap)。要使用给定的 PAM 服务,您必须在 PAM 配置目录中设置一个同名的 PAM 文件(如果不存在则创建该文件)。此外,您必须在使用该 PAM 服务进行认证的任何账户的CREATE USER语句的认证字符串中命名 PAM 服务。

PAM 认证插件在初始化时检查服务器启动环境中是否设置了AUTHENTICATION_PAM_LOG环境值。如果是,则插件会启用将诊断消息记录到标准输出的功能。根据服务器的启动方式,消息可能会显示在控制台上或错误日志中。这些消息对于调试描相关问题很有帮助。有关更多信息,请参阅 PAM 认证调试。

无代理用户的 PAM Unix 密码认证

这种认证场景使用 PAM 来检查以操作系统用户名和 Unix 密码定义的外部用户,而无需代理。每个被允许连接到 MySQL 服务器的外部用户都应该有一个匹配的 MySQL 账户,该账户被定义为通过传统的 Unix 密码存储使用 PAM 认证。

注意

传统的 Unix 密码是使用/etc/shadow文件进行检查的。有关与该文件相关的可能问题的信息,请参阅 PAM 认证访问 Unix 密码存储。

  1. 验证 Unix 认证是否允许使用用户名antonio和密码*antonio_password*登录到操作系统。
  2. 通过创建名为/etc/pam.d/mysql-unixmysql-unix PAM 服务文件来设置 PAM 以使用传统的 Unix 密码对 MySQL 连接进行认证。文件内容取决于系统,因此请检查/etc/pam.d目录中现有的与登录相关的文件以查看其外观。在 Linux 上,mysql-unix文件可能如下所示:
#%PAM-1.0
auth            include         password-auth
account         include         password-auth
  1. 对于 macOS,请使用login而不是password-auth
    在某些系统上,PAM 文件格式可能有所不同。例如,在 Ubuntu 和其他基于 Debian 的系统上,使用以下文件内容:
@include common-auth
@include common-account
@include common-session-noninteractive
  1. 创建一个与操作系统用户名相同的 MySQL 账户,并定义其使用 PAM 插件和mysql-unix PAM 服务进行认证:
CREATE USER 'antonio'@'localhost'
  IDENTIFIED WITH authentication_pam
  AS 'mysql-unix';
GRANT ALL PRIVILEGES
  ON mydb.*
  TO 'antonio'@'localhost';
  1. 在这里,认证字符串仅包含 PAM 服务名称,mysql-unix,用于验证 Unix 密码。
  2. 使用mysql命令行客户端作为antonio连接到 MySQL 服务器。例如:
$> mysql --user=antonio --password --enable-cleartext-plugin
Enter password: *antonio_password*
  1. 服务器应允许连接,并且以下查询返回如下输出:
mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
+-------------------+-------------------+--------------+
| USER()            | CURRENT_USER()    | @@proxy_user |
+-------------------+-------------------+--------------+
| antonio@localhost | antonio@localhost | NULL         |
+-------------------+-------------------+--------------+
  1. 这表明antonio操作系统用户经过认证具有授予antonio MySQL 用户的权限,并且没有发生代理。

注意

客户端端的mysql_clear_password认证插件不会更改密码,因此客户端程序会将其以明文形式发送到 MySQL 服务器。这使得密码可以原样传递给 PAM。在某些配置中,明文密码是使用服务器端 PAM 库所必需的,但可能会存在安全问题。以下措施可最小化风险:

  • 为了减少意外使用mysql_clear_password插件的可能性,MySQL 客户端必须显式启用它(例如,使用--enable-cleartext-plugin选项)。参见 Section 8.4.1.4, “Client-Side Cleartext Pluggable Authentication”。
  • 为了避免启用mysql_clear_password插件时密码暴露,MySQL 客户端应该使用加密连接连接到 MySQL 服务器。参见 Section 8.3.1, “Configuring MySQL to Use Encrypted Connections”。
无代理用户的 PAM LDAP 认证

这种认证场景使用 PAM 来检查以操作系统用户名和 LDAP 密码定义的外部用户,而无需代理。每个被允许连接到 MySQL 服务器的外部用户都应该有一个匹配的 MySQL 账户,该账户被定义为通过 LDAP 进行 PAM 认证。

要使用 PAM LDAP 可插拔认证为 MySQL,必须满足以下先决条件:

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

注意

另一种使用 LDAP 进行 MySQL 用户认证的方法是使用特定于 LDAP 的认证插件。参见 Section 8.4.1.7, “LDAP Pluggable Authentication”。

配置 MySQL 以进行 PAM LDAP 认证如下:

  1. 验证 Unix 认证是否允许使用用户名antonio和密码*antonio_password*登录到操作系统。
  2. 通过创建一个名为/etc/pam.d/mysql-ldapmysql-ldap PAM 服务文件来设置 PAM 以使用 LDAP 认证 MySQL 连接。文件内容取决于系统,因此请检查/etc/pam.d目录中现有的与登录相关的文件以查看其内容。在 Linux 上,mysql-ldap文件可能如下所示:
#%PAM-1.0
auth        required    pam_ldap.so
account     required    pam_ldap.so
  1. 如果在您的系统上,PAM 对象文件的后缀与.so不同,请替换正确的后缀。
    PAM 文件格式可能在某些系统上有所不同。
  2. 创建一个与操作系统用户名相同的 MySQL 账户,并定义其使用 PAM 插件和mysql-ldap PAM 服务进行验证:
CREATE USER 'antonio'@'localhost'
  IDENTIFIED WITH authentication_pam
  AS 'mysql-ldap';
GRANT ALL PRIVILEGES
  ON mydb.*
  TO 'antonio'@'localhost';
  1. 这里,认证字符串仅包含 PAM 服务名称mysql-ldap,用 LDAP 进行验证。
  2. 连接到服务器的方式与 PAM Unix 密码认证无代理用户中描述的相同。
使用代理用户和组映射的 PAM Unix 密码认证

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

此处所示的过程使用 Unix 密码认证。要改用 LDAP,请参阅 PAM LDAP 认证无代理用户的早期步骤。

注意

传统的 Unix 密码使用/etc/shadow文件进行检查。有关与该文件相关的可能问题的信息,请参阅 PAM 认证访问 Unix 密码存储。

  1. 验证 Unix 认证是否允许使用用户名antonio和密码*antonio_password*登录操作系统。
  2. 验证antonio是否是rootusers PAM 组的成员。
  3. 通过创建名为/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
  1. 对于 macOS,请使用login而不是password-auth
    在某些系统上,PAM 文件格式可能有所不同。例如,在 Ubuntu 和其他基于 Debian 的系统上,使用以下文件内容:
@include common-auth
@include common-account
@include common-session-noninteractive
  1. 创建一个默认的代理用户(''@''),将外部 PAM 用户映射到代理账户:
CREATE USER ''@''
  IDENTIFIED WITH authentication_pam
  AS 'mysql-unix, root=developer, users=data_entry';
  1. 这里,认证字符串包含了 PAM 服务名称mysql-unix,用于验证 Unix 密码。认证字符串还将rootusers PAM 组中的外部用户映射到developerdata_entry MySQL 用户名。
    在设置代理用户时,必须在 PAM 服务名称后面提供 PAM 组映射列表。否则,插件无法确定如何将外部用户名映射到正确的被代理 MySQL 用户名。
    注意
    如果您的 MySQL 安装中存在匿名用户,则可能会与默认代理用户发生冲突。有关此问题的更多信息以及处理方法,请参见 Default Proxy User and Anonymous User Conflicts。
  2. 创建被代理账户并为每个账户授予应具有的权限:
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';
  1. 代理账户使用mysql_no_login认证插件,以防止客户端直接使用这些账户登录到 MySQL 服务器。相反,使用 PAM 进行身份验证的用户应该通过代理使用基于他们的 PAM 组的developerdata_entry账户。(假设插件已安装。有关说明,请参见  Section 8.4.1.9, “No-Login Pluggable  Authentication”。)有关保护代理账户免受直接使用的替代方法,请参见 Preventing Direct Login to  Proxied Accounts。
  2. 为每个被代理账户授予PROXY权限:
GRANT PROXY
  ON 'developer'@'localhost'
  TO ''@'';
GRANT PROXY
  ON 'data_entry'@'localhost'
  TO ''@'';
  1. 使用mysql命令行客户端作为安东尼奥连接到 MySQL 服务器。
$> mysql --user=antonio --password --enable-cleartext-plugin
Enter password: *antonio_password*
  1. 服务器使用默认的''@''代理账户对连接进行身份验证。安东尼奥的权限取决于他是哪些 PAM 组的成员。如果安东尼奥root PAM 组的成员,PAM 插件将root映射到developer MySQL 用户名并将该名称返回给服务器。服务器验证''@''是否具有developerPROXY权限,并允许连接。以下查询返回如下输出:
mysql> SELECT USER(), CURRENT_USER(), @@proxy_user;
+-------------------+---------------------+--------------+
| USER()            | CURRENT_USER()      | @@proxy_user |
+-------------------+---------------------+--------------+
| antonio@localhost | developer@localhost | ''@''        |
+-------------------+---------------------+--------------+
  1. 这表明安东尼奥操作系统用户被验证具有授予developer MySQL 用户的权限,并且通过默认代理账户进行代理。
    如果安东尼奥不是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 | ''@''        |
+-------------------+----------------------+--------------+
  1. 这表明安东尼奥操作系统用户被验证具有data_entry MySQL 用户的权限,并且通过默认代理账户进行代理。

注意

客户端端的mysql_clear_password认证插件保持密码不变,因此客户端程序将其以明文形式发送到 MySQL 服务器。这使得密码可以原样传递给 PAM。在某些配置中,明文密码是使用服务器端 PAM 库所必需的,但可能在某些配置中存在安全问题。以下措施可最小化风险:

  • 为了减少意外使用mysql_clear_password插件的可能性,MySQL 客户端必须显式启用它(例如,使用--enable-cleartext-plugin选项)。参见 Section 8.4.1.4, “Client-Side Cleartext Pluggable Authentication”。
  • 启用mysql_clear_password插件以避免密码暴露,MySQL 客户端应该使用加密连接连接到 MySQL 服务器。参见 Section 8.3.1, “Configuring MySQL to Use Encrypted Connections”。

MySQL8 中文参考(二十六)(2)https://developer.aliyun.com/article/1566128

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
4月前
|
关系型数据库 MySQL Unix
MySQL8 中文参考(二十三)(3)
MySQL8 中文参考(二十三)
48 4
|
4月前
|
存储 缓存 关系型数据库
MySQL8 中文参考(二十一)(5)
MySQL8 中文参考(二十一)
74 3
|
4月前
|
存储 监控 Java
MySQL8 中文参考(二十一)(4)
MySQL8 中文参考(二十一)
112 3
|
4月前
|
存储 安全 关系型数据库
MySQL8 中文参考(二十一)(1)
MySQL8 中文参考(二十一)
46 3
|
4月前
|
存储 关系型数据库 MySQL
MySQL8 中文参考(二十一)(3)
MySQL8 中文参考(二十一)
65 2
|
4月前
|
关系型数据库 MySQL Unix
MySQL8 中文参考(二十一)(2)
MySQL8 中文参考(二十一)
56 2
|
4月前
|
关系型数据库 MySQL 数据安全/隐私保护
MySQL8 中文参考(二十五)(5)
MySQL8 中文参考(二十五)
38 2
|
4月前
|
存储 关系型数据库 MySQL
MySQL8 中文参考(二十四)(1)
MySQL8 中文参考(二十四)
43 2
|
4月前
|
NoSQL 关系型数据库 MySQL
MySQL8 中文参考(二十三)(2)
MySQL8 中文参考(二十三)
52 2
|
4月前
|
存储 关系型数据库 MySQL
MySQL8 中文参考(二十三)(1)
MySQL8 中文参考(二十三)
31 2