原文:
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
系统表的plugin
和authentication_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_path
和sha256_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 密钥对用于密码交换:
- 使用 Section 8.3.3, “Creating SSL and RSA Certificates and Keys”中的说明创建 RSA 私钥和公钥对文件。
- 如果私钥和公钥文件位于数据目录中,并且命名为
private_key.pem
和public_key.pem
(sha256_password_private_key_path
和sha256_password_public_key_path
系统变量的默认值),服务器将在启动时自动使用它们。
否则,要显式命名关键文件,请在服务器选项文件中设置系统变量为关键文件名。如果文件位于服务器数据目录中,则无需指定其完整路径名:
[mysqld] sha256_password_private_key_path=myprivkey.pem sha256_password_public_key_path=mypubkey.pem
- 如果密钥文件不位于数据目录中,或者要在系统变量值中明确它们的位置,请使用完整路径名:
[mysqld] sha256_password_private_key_path=/usr/local/mysql/myprivkey.pem sha256_password_public_key_path=/usr/local/mysql/mypubkey.pem
- 重新启动服务器,然后连接到服务器并检查
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-----
- 如果值为空,则服务器发现密钥文件存在问题。请检查错误日志以获取诊断信息。
在服务器配置了 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
环境变量设置为以1
、Y
或y
开头的值。这将为所有客户端连接启用该插件。 - 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 可插拔认证。
- 客户端程序和服务器进行通信,客户端向服务器发送客户端用户名(默认为操作系统用户名)和密码:
- 客户端用户名为外部用户名。
- 对于使用 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 可插拔认证
本节描述了如何安装服务器端 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 服务名称,并且应该将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 组映射列表,则插件会从左到右检查列表中的每个
*
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-unix
或mysql-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 密码存储。
- 验证 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
选项)。参见 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/1566139