Pluggable Authentication(PAM,即可插拔式认证模块)是一种高效且灵活的用户级别的认证方式,广泛应用于现代操作系统,特别是Linux服务器中。它允许数据库管理员(DBAs)为MySQL用户帐户选择和更改不同的认证方法。
1 身份验证插件客户端/服务器兼容性
可插拔身份验证使MySQL帐户在选择身份验证方法时具有灵活性,但在某些情况下,由于客户端和服务器之间的身份验证插件不兼容,无法建立客户端连接。
客户端成功连接到给定服务器上的给定帐户的一般兼容性原则是,客户端和服务器都必须支持帐户所需的身份验证方法。由于身份验证方法是由身份验证插件实现的,因此客户端和服务器都必须支持帐户所需的身份验证插件。
身份验证插件不兼容可能以各种方式出现。示例:
- 使用5.7.22或更低版本的MySQL 5.7客户端连接到使用caching_sha2_password进行身份验证的MySQL 8.0服务器帐户。这失败了,因为5.7客户端无法识别MySQL 8.0中引入的插件。(这个问题在5.7.23版本的MySQL 5.7中得到了解决,当时MySQL客户端库和客户端程序中添加了caching_sha2_password客户端支持。)
- 使用MySQL 5.7客户端连接到5.7之前的服务器帐户,该帐户使用MySQL_old_password进行身份验证。失败的原因有很多。首先,这样的连接需要--secure-auth=0,这不再是受支持的选项。即使支持该插件,5.7客户端也无法识别该插件,因为它已在MySQL 5.7中删除。
- 使用社区分发版的MySQL 5.7客户端连接到MySQL 5.7 Enterprise服务器帐户,该帐户使用仅限Enterprise的LDAP身份验证插件之一进行身份验证。此操作失败,因为社区客户端没有访问企业插件的权限。
一般来说,当在来自同一MySQL分发版的客户端和服务器之间进行连接时,不会出现这些兼容性问题。当在不同MySQL系列的客户端和服务器之间建立连接时,可能会出现问题。当MySQL引入新的验证插件或删除旧的验证插件时,这些问题是开发过程中固有的。为了最大限度地减少不兼容的可能性,请定期及时升级服务器、客户端和连接器。
2 身份验证插件连接器编写注意事项
MySQL客户端/服务器协议存在各种实现。libmysqlclientC API客户端库就是一个实现。一些MySQL连接器(通常不是用C编写的)提供了自己的实现。然而,并不是所有的协议实现都以相同的方式处理插件身份验证。本节描述了协议实现者应该考虑的身份验证问题。
在客户端/服务器协议中,服务器告诉连接客户端它认为默认的身份验证插件。如果客户端使用的协议实现尝试加载默认插件,而该插件在客户端不存在,则加载操作失败。如果默认插件不是客户端尝试连接的帐户实际需要的插件,则这是不必要的失败。
如果客户端/服务器协议实现没有自己的默认身份验证插件概念,并且总是试图加载服务器指定的默认插件,则如果该插件不可用,则会失败并出现错误。
为了避免这个问题,客户端使用的协议实现应该有自己的默认插件,并应将其作为第一选择(或者,在无法加载服务器指定的默认插件的情况下,返回到该默认插件)。例如:
- 在MySQL 5.7中,libmysqlclient使用MySQL_native_password或通过MySQL_options()的MySQL_default_AUTH选项指定的插件作为默认选项。
- 当5.7客户端尝试连接到8.0服务器时,服务器会指定caching_sha2_password作为其默认身份验证插件,但客户端仍会根据mysql_native_password或通过mysql_default_AUTH指定的任何内容发送凭据详细信息。
- 客户端加载服务器指定的插件的唯一时间是针对更改插件请求,但在这种情况下,它可以是任何插件,具体取决于用户帐户。在这种情况下,客户端必须尝试加载插件,如果该插件不可用,则错误不是可选的。
3 对可插拔身份验证的限制
“本机身份验证”是指根据存储在mysql.user系统表中的密码进行身份验证。在实现可插拔身份验证之前,这与旧的MySQL服务器提供的身份验证方法相同。“Windows本机身份验证”是指使用已登录Windows的用户的凭据进行身份验证,由Windows本机验证插件(简称“Windows插件”)实现。
3.1 常规可插拔身份验证限制
- 连接器/C++:使用此连接器的客户端只能通过使用本机身份验证的帐户连接到服务器。
异常:如果连接器是为了动态(而不是静态)链接到libmysqlclient而构建的,并且如果安装了当前版本的libmysqlclient,或者连接器是从源代码重新编译以链接到当前libmysqlclient的,则连接器支持可插式身份验证。
- 连接器/NET:使用连接器/NET的客户端可以通过使用本地身份验证或Windows本地身份验证的帐户连接到服务器。
- 连接器/PHP:使用此连接器的客户端只能通过使用本机身份验证的帐户连接到服务器,当使用MySQL PHP本机驱动程序(mysqlnd)进行编译时。
- Windows本机身份验证:通过使用Windows插件的帐户进行连接需要安装Windows域。如果没有它,将使用NTLM身份验证,然后只能进行本地连接;也就是说,客户端和服务器必须在同一台计算机上运行。
- 代理用户:代理用户支持的范围是,客户端可以通过使用实现代理用户功能的插件(即,可以返回与连接用户不同的用户名的插件)验证的帐户进行连接。例如,PAM和Windows插件支持代理用户。mysql_native_password和sha256_password身份验证插件默认不支持代理用户,但可以配置为支持代理用户;请参阅服务器对代理用户映射的支持。
- 复制:复制副本不仅可以使用使用本机身份验证的复制用户帐户,而且如果所需的客户端插件可用,还可以通过使用非本机身份证明的复制用户账户进行连接。如果插件内置在libmysqlclient中,则默认情况下它是可用的。否则,插件必须安装在复制副本一侧的由复制副本的plugin_dir系统变量命名的目录中。
- FEDERATED表:FEDERATED表只能通过使用本机身份验证的远程服务器上的帐户访问远程表。
3.2 可插拔身份验证和第三方连接器
第三方连接器开发人员可以使用以下指南来确定连接器是否准备好利用可插拔身份验证功能,以及采取哪些步骤使其更符合要求:
- 未对其进行更改的现有连接器使用本机身份验证,使用该连接器的客户端只能通过使用本机验证的帐户连接到服务器。但是,您应该针对最新版本的服务器测试连接器,以验证此类连接是否仍然正常工作。
异常:如果连接器动态(而不是静态)链接到libmysqlclient,并且如果安装了当前版本的libmysqlclient则加载该版本,则连接器可能在不进行任何更改的情况下使用可插入身份验证。
- 为了利用可插入的身份验证功能,应该根据当前版本的libmysqlclient重新链接基于libmysqlclient的连接器。这使连接器能够支持通过需要客户端插件的帐户进行连接,这些插件现在内置在libmysqlclient中(例如PAM身份验证所需的明文插件和Windows本机身份验证所需要的Windows插件)。与当前的libmysqlclient链接还使连接器能够访问安装在默认MySQL插件目录中的客户端插件(通常是由本地服务器的plugin_dir系统变量的默认值命名的目录)。
如果连接器动态链接到libmysqlclient,则必须确保在客户端主机上安装了较新版本的libmysqlclient并且连接器在运行时加载它。
- 连接器支持给定身份验证方法的另一种方式是直接在客户端/服务器协议中实现它。Connector/NET使用此方法为Windows本机身份验证提供支持。
- 如果连接器应该能够从不同于默认插件目录的目录加载客户端插件,那么它必须为客户端用户实现一些指定目录的方法。这方面的可能性包括命令行选项或环境变量,连接器可以从中获取目录名。标准MySQL客户端程序(如MySQL和mysqladmin)实现了一个--plugin-dir选项。
- 连接器对代理用户的支持取决于其支持的身份验证方法是否允许代理用户。