MySQL8 中文参考(二十七)(1)https://developer.aliyun.com/article/1566138
无代理用户的 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 认证如下:
- 验证 Unix 认证是否允许使用用户名
antonio
和密码*antonio_password
*登录到操作系统。 - 通过创建一个名为
/etc/pam.d/mysql-ldap
的mysql-ldap
PAM 服务文件来设置 PAM 以使用 LDAP 认证 MySQL 连接。文件内容取决于系统,因此请检查/etc/pam.d
目录中现有的与登录相关的文件以查看其内容。在 Linux 上,mysql-ldap
文件可能如下所示:
#%PAM-1.0 auth required pam_ldap.so account required pam_ldap.so
- 如果在您的系统上,PAM 对象文件的后缀与
.so
不同,请替换正确的后缀。
PAM 文件格式可能在某些系统上有所不同。 - 创建一个与操作系统用户名相同的 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 进行验证。 - 连接到服务器的方式与 PAM Unix 密码认证无代理用户中描述的相同。
使用代理用户和组映射的 PAM Unix 密码认证
此处描述的认证方案使用代理和 PAM 组映射,将使用 PAM 进行验证的连接 MySQL 用户映射到定义了不同权限集的其他 MySQL 账户上。用户不直接通过定义权限的账户连接。相反,他们通过使用 PAM 进行身份验证的默认代理账户连接,以便将所有外部用户映射到具有权限的 MySQL 账户。使用代理账户连接的任何用户都将映射到这些 MySQL 账户之一,其权限确定了允许外部用户执行的数据库操作。
此处所示的过程使用 Unix 密码认证。要改用 LDAP,请参阅 PAM LDAP 认证无代理用户的早期步骤。
注意
传统的 Unix 密码使用/etc/shadow
文件进行检查。有关与该文件相关的可能问题的信息,请参阅 PAM 认证访问 Unix 密码存储。
- 验证 Unix 认证是否允许使用用户名
antonio
和密码*antonio_password
*登录操作系统。 - 验证
antonio
是否是root
或users
PAM 组的成员。 - 通过创建名为
/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
- 对于 macOS,请使用
login
而不是password-auth
。
在某些系统上,PAM 文件格式可能有所不同。例如,在 Ubuntu 和其他基于 Debian 的系统上,使用以下文件内容:
@include common-auth @include common-account @include common-session-noninteractive
- 创建一个默认的代理用户(
''@''
),将外部 PAM 用户映射到代理账户:
CREATE USER ''@'' IDENTIFIED WITH authentication_pam AS 'mysql-unix, root=developer, users=data_entry';
- 这里,认证字符串包含了 PAM 服务名称
mysql-unix
,用于验证 Unix 密码。认证字符串还将root
和users
PAM 组中的外部用户映射到developer
和data_entry
MySQL 用户名。
在设置代理用户时,必须在 PAM 服务名称后面提供 PAM 组映射列表。否则,插件无法确定如何将外部用户名映射到正确的被代理 MySQL 用户名。
注意
如果您的 MySQL 安装中存在匿名用户,则可能会与默认代理用户发生冲突。有关此问题的更多信息以及处理方法,请参见 Default Proxy User and Anonymous User Conflicts。 - 创建被代理账户并为每个账户授予应具有的权限:
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 组的developer
或data_entry
账户。(假设插件已安装。有关说明,请参见 Section 8.4.1.9, “No-Login Pluggable Authentication”。)有关保护代理账户免受直接使用的替代方法,请参见 Preventing Direct Login to Proxied Accounts。 - 为每个被代理账户授予
PROXY
权限:
GRANT PROXY ON 'developer'@'localhost' TO ''@''; GRANT PROXY ON 'data_entry'@'localhost' TO ''@'';
- 使用mysql命令行客户端作为
安东尼奥
连接到 MySQL 服务器。
$> mysql --user=antonio --password --enable-cleartext-plugin Enter password: *antonio_password*
- 服务器使用默认的
''@''
代理账户对连接进行身份验证。安东尼奥
的权限取决于他是哪些 PAM 组的成员。如果安东尼奥
是root
PAM 组的成员,PAM 插件将root
映射到developer
MySQL 用户名并将该名称返回给服务器。服务器验证''@''
是否具有developer
的PROXY
权限,并允许连接。以下查询返回如下输出:
mysql> SELECT USER(), CURRENT_USER(), @@proxy_user; +-------------------+---------------------+--------------+ | USER() | CURRENT_USER() | @@proxy_user | +-------------------+---------------------+--------------+ | antonio@localhost | developer@localhost | ''@'' | +-------------------+---------------------+--------------+
- 这表明
安东尼奥
操作系统用户被验证具有授予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 | ''@'' | +-------------------+----------------------+--------------+
- 这表明
安东尼奥
操作系统用户被验证具有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”。
PAM 身份验证访问 Unix 密码存储
在某些系统上,Unix 身份验证使用密码存储,例如/etc/shadow
,这是一个通常具有受限访问权限的文件。这可能导致 MySQL 基于 PAM 的身份验证失败。不幸的是,PAM 实现不允许区分“密码无法检查”(例如,由于无法读取/etc/shadow
)和“密码不匹配”。如果您正在使用 Unix 密码存储进行 PAM 身份验证,您可以通过以下方法之一启用 MySQL 对其的访问:
- 假设 MySQL 服务器是从
mysql
操作系统帐户运行的,请将该帐户放入具有/etc/shadow
访问权限的shadow
组中:
- 在
/etc/group
中创建���个shadow
组。 - 将
mysql
操作系统用户添加到/etc/group
中的shadow
组。 - 将
/etc/group
分配给shadow
组并启用组读权限:
chgrp shadow /etc/shadow chmod g+r /etc/shadow
- 重新启动 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
环境值是否已设置。在 MySQL 8.0.35 及更早版本中,该值无关紧要。如果是,则插件将启用将诊断消息记录到标准输出的功能。这些消息可能有助于调试插件执行身份验证时出现的与 PAM 相关的问题。您应该知道,在这些版本中,这些消息中包含密码。
从 MySQL 8.0.36 开始,设置AUTHENTICATION_PAM_LOG=1
(或其他任意值)会产生相同的诊断消息,但不包含任何密码。如果您希望在这些消息中包含密码,请设置AUTHENTICATION_PAM_LOG=PAM_LOG_WITH_SECRET_INFO
。
一些消息包含对 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-password
PAM 服务的帐户:
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-password
PAM 服务文件以禁用任意密码访问。
原文:
dev.mysql.com/doc/refman/8.0/en/windows-pluggable-authentication.html
8.4.1.6 Windows 可插拔认证
注意
Windows 可插拔认证是 MySQL 企业版中包含的扩展,这是一个商业产品。要了解更多关于商业产品的信息,请查看www.mysql.com/products/
。
Windows 版 MySQL 企业版支持一种在 Windows 上执行外部认证的认证方法,使 MySQL 服务器能够使用本机 Windows 服务对客户端连接进行认证。已登录到 Windows 的用户可以根据其环境中的信息从 MySQL 客户端程序连接到服务器,而无需指定额外的密码。
客户端和服务器在认证握手中交换数据包。由于这种交换,服务器创建一个代表客户端在 Windows OS 中身份的安全上下文对象。这个身份包括客户端账户的名称。Windows 可插拔认证使用客户端的身份来检查它是否是给定账户或组的成员。默认情况下,协商使用 Kerberos 进行认证,如果 Kerberos 不可用,则使用 NTLM。
Windows 可插拔认证提供了以下功能:
- 外部认证:Windows 认证使 MySQL 服务器能够接受来自在 Windows 登录的 MySQL 授权表之外定义的用户的连接。
- 代理用户支持:Windows 认证可以将一个与客户端程序传递的外部用户名不同的用户名返回给 MySQL。这意味着插件可以返回定义外部 Windows 认证用户应具有的权限的 MySQL 用户。例如,一个名为
joe
的 Windows 用户可以连接并具有名为developer
的 MySQL 用户的权限。
以下表格显示了插件和库文件的名称。文件必须位于由plugin_dir
系统变量命名的目录中。
表 8.21 Windows 认证的插件和库名称
插件或文件 | 插件或文件名 |
服务器端插件 | authentication_windows |
客户端插件 | authentication_windows_client |
库文件 | authentication_windows.dll |
库文件仅包含服务器端插件。客户端插件内置于libmysqlclient
客户端库中。
服务器端 Windows 认证插件仅包含在 MySQL 企业版中。它不包含在 MySQL 社区发行版中。客户端插件包含在所有发行版中,包括社区发行版。这使得来自任何发行版的客户端都能连接到加载了服务器端插件的服务器。
以下部分提供了特定于 Windows 可插拔认证的安装和使用信息:
- 安装 Windows 可插拔认证
- 卸载 Windows 可插拔认证
- 使用 Windows 可插拔认证
有关 MySQL 中可插拔认证的一般信息,请参阅 Section 8.2.17, “Pluggable Authentication”。有关代理用户信息,请参阅 Section 8.2.19, “Proxy Users”。
安装 Windows 可插拔认证
本节描述了如何安装服务器端 Windows 认证插件。有关安装插件的一般信息,请参阅 Section 7.6.1, “Installing and Uninstalling Plugins”。
要被服务器使用,插件库文件必须位于 MySQL 插件目录中(由plugin_dir
系统变量命名的目录)。如果需要,通过在服务器启动时设置plugin_dir
的值来配置插件目录位置。
要在服务器启动时加载插件,请使用--plugin-load-add
选项命名包含插件的库文件。使用此插件加载方法,每次服务器启动时都必须提供该选项。例如,将以下行放入服务器my.cnf
文件中:
[mysqld] plugin-load-add=authentication_windows.dll
修改my.cnf
后,重新启动服务器以使新设置生效。
或者,要在运行时加载插件,请使用以下语句:
INSTALL PLUGIN authentication_windows SONAME 'authentication_windows.dll';
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 '%windows%'; +------------------------+---------------+ | PLUGIN_NAME | PLUGIN_STATUS | +------------------------+---------------+ | authentication_windows | ACTIVE | +------------------------+---------------+
如果插件初始化失败,请检查服务器错误日志以获取诊断消息。
要将 MySQL 帐户与 Windows 认证插件关联,请参阅使用 Windows 可插拔认证。 通过authentication_windows_use_principal_name
和authentication_windows_log_level
系统变量提供了额外的插件控制。 请参阅第 7.1.8 节,“服务器系统变量”。
卸载 Windows 可插拔认证
卸载 Windows 认证插件的方法取决于您安装它的方式:
- 如果您在服务器启动时使用
--plugin-load-add
选项安装插件,请在不带该选项的情况下重新启动服务器。 - 如果您使用
INSTALL PLUGIN
语句在运行时安装插件,则插件将在服务器重新启动时保持安装状态。 要卸载它,请使用UNINSTALL PLUGIN
:
UNINSTALL PLUGIN authentication_windows;
另外,删除任何设置 Windows 插件相关系统变量的启动选项。
使用 Windows 可插拔认证
Windows 认证插件支持使用 MySQL 帐户,使得已登录 Windows 的用户可以连接到 MySQL 服务器,而无需指定额外的密码。 假定服务器正在运行并启用了服务器端插件,如安装 Windows 可插拔认证中所述。 一旦 DBA 启用了服务器端插件并设置了要使用它的帐户,客户端就可以使用这些帐户连接,而无需进行其他设置。
在CREATE USER
语句的IDENTIFIED WITH
子句中引用 Windows 认证插件,请使用名称authentication_windows
。 假设 Windows 用户Rafal
和Tasha
应被允许连接到 MySQL,以及Administrators
或Power Users
组中的任何用户。 要设置这一点,请创建一个名为sql_admin
的 MySQL 帐户,该帐户使用 Windows 插件进行身份验证:
CREATE USER sql_admin IDENTIFIED WITH authentication_windows AS 'Rafal, Tasha, Administrators, "Power Users"';
插件名称为authentication_windows
。 AS
关键字后面的字符串是认证字符串。 它指定了名为Rafal
或Tasha
的 Windows 用户被允许作为 MySQL 用户sql_admin
进行服务器身份验证,以及Administrators
或Power Users
组中的任何 Windows 用户。 后一个组名包含一个空格,因此必须用双引号括起来。
创建sql_admin
账户后,已登录到 Windows 的用户可以尝试使用该账户连接到服务器:
C:\> mysql --user=sql_admin
这里不需要密码。authentication_windows
插件使用 Windows 安全 API 来检查连接的是哪个 Windows 用户。如果该用户名为Rafal
或Tasha
,或者是Administrators
或Power Users
组的成员,则服务器授予访问权限,并将客户端验证为sql_admin
,并具有授予sql_admin
账户的任何权限。否则,服务器将拒绝访问。
Windows 认证插件的认证字符串语法遵循以下规则:
- 该字符串由一个或多个以逗号分隔的用户映射组成。
- 每个用户映射将 Windows 用户或组名与 MySQL 用户名称关联起来:
*win_user_or_group_name=mysql_user_name* *win_user_or_group_name*
- 对于后一种语法,如果没有给出*
mysql_user_name
*值,则隐式值是由CREATE USER
语句创建的 MySQL 用户。因此,以下语句是等效的:
CREATE USER sql_admin IDENTIFIED WITH authentication_windows AS 'Rafal, Tasha, Administrators, "Power Users"'; CREATE USER sql_admin IDENTIFIED WITH authentication_windows AS 'Rafal=sql_admin, Tasha=sql_admin, Administrators=sql_admin, "Power Users"=sql_admin';
- 值中的每个反斜杠字符(
\
)都必须加倍,因为反斜杠是 MySQL 字符串中的转义字符。 - 在双引号内部的前导和尾随空格将被忽略。
- 未引用的*
win_user_or_group_name
和mysql_user_name
*值可以包含除等号、逗号或空格之外的任何内容。 - 如果*
win_user_or_group_name
和/或mysql_user_name
*值用双引号引起来,那么引号之间的所有内容都是值的一部分。例如,如果名称包含空格字符,则这是必要的。双引号内的所有字符都是合法的,除了双引号和反斜杠。要包含这两个字符,需要用反斜杠进行转义。 - *
win_user_or_group_name
*值使用 Windows 主体的传统语法,可以是本地的或域中的。示例(注意反斜杠的加倍):
domain\\user .\\user domain\\group .\\group BUILTIN\\WellKnownGroup
当服务器调用插件来验证客户端时,插件从左到右扫描认证字符串,以查找与 Windows 用户匹配的用户或组。如果有匹配,插件将相应的*mysql_user_name
*返回给 MySQL 服务器。如果没有匹配,则认证失败。
用户名称匹配优先于组名称匹配。假设名为win_user
的 Windows 用户是win_group
的成员,并且认证字符串如下所示:
'win_group = sql_user1, win_user = sql_user2'
当win_user
连接到 MySQL 服务器时,既与win_group
匹配,也与win_user
匹配。插件将用户验证为sql_user2
,因为更具体的用户匹配优先于组匹配,即使组在认证字符串中首先列出。
Windows 身份验证始终适用于从运行服务器的同一台计算机发起的连接。对于跨计算机连接,两台计算机必须在 Microsoft Active Directory 中注册。如果它们在同一个 Windows 域中,则无需指定域名。也可以允许来自不同域的连接,就像这个例子中一样:
CREATE USER sql_accounting IDENTIFIED WITH authentication_windows AS 'SomeDomain\\Accounting';
这里 SomeDomain
是另一个域的名称。反斜杠字符被加倍,因为它是字符串中的 MySQL 转义字符。
MySQL 支持代理用户的概念,即客户端可以使用一个账户连接和认证到 MySQL 服务器,但在连接时具有另一个账户的权限(参见 Section 8.2.19, “Proxy Users”)。假设您希望 Windows 用户使用单个用户名连接,但根据其 Windows 用户和组名称映射到特定的 MySQL 账户,如下所示:
local_user
和MyDomain\domain_user
本地和域 Windows 用户应映射到local_wlad
MySQL 账户。MyDomain\Developers
域组中的用户应映射到local_dev
MySQL 账户。- 本地机器管理员应映射到
local_admin
MySQL 账户。
要设置这个,为 Windows 用户创建一个代理账户进行连接,并配置此账户,使用户和组映射到适当的 MySQL 账户(local_wlad
、local_dev
、local_admin
)。此外,授予 MySQL 账户执行所需操作的适当权限。以下说明使用 win_proxy
作为代理账户,local_wlad
、local_dev
和 local_admin
作为代理账户。
- 创建代理 MySQL 账户:
CREATE USER win_proxy IDENTIFIED WITH authentication_windows AS 'local_user = local_wlad, MyDomain\\domain_user = local_wlad, MyDomain\\Developers = local_dev, BUILTIN\\Administrators = local_admin';
- 为了使代理工作,代理账户必须存在,因此创建它们:
CREATE USER local_wlad IDENTIFIED WITH mysql_no_login; CREATE USER local_dev IDENTIFIED WITH mysql_no_login; CREATE USER local_admin IDENTIFIED WITH mysql_no_login;
- 代理账户使用
mysql_no_login
认证插件,以防止客户端直接使用这些账户登录到 MySQL 服务器。相反,使用 Windows 进行身份验证的用户应该使用win_proxy
代理账户。(这假定插件已安装。有关说明,请参见 Section 8.4.1.9, “No-Login Pluggable Authentication”。)有关保护代理账户免受直接使用的替代方法,请参见 Preventing Direct Login to Proxied Accounts。
您还应该执行GRANT
语句(未显示),为每个代理账户授予所需的 MySQL 访问权限。 - 为代理账户授予
PROXY
权限,以代表每个代理账户:
GRANT PROXY ON local_wlad TO win_proxy; GRANT PROXY ON local_dev TO win_proxy; GRANT PROXY ON local_admin TO win_proxy;
现在,Windows 用户local_user
和MyDomain\domain_user
可以作为win_proxy
连接到 MySQL 服务器,并在经过身份验证后具有身份验证字符串中指定帐户(在本例中为local_wlad
)的权限。以win_proxy
身份连接的MyDomain\Developers
组中的用户具有local_dev
帐户的权限。BUILTIN\Administrators
组中的用户具有local_admin
帐户的权限。
要配置身份验证,使所有没有自己的 MySQL 帐户的 Windows 用户通过代理帐户进行身份验证,请在上述说明中将默认代理帐户(''@''
)替换为win_proxy
。有关默认代理帐户的信息,请参阅 Section 8.2.19, “Proxy Users”。
注意
如果您的 MySQL 安装中存在匿名用户,则它们可能与默认代理用户发生冲突。有关此问题的更多信息以及处理方法,请参阅 Default Proxy User and Anonymous User Conflicts。
要在 Connector/NET 8.0 及更高版本中使用 Windows 身份验证插件与 Connector/NET 连接字符串,请参阅 Connector/NET Authentication。
原文:
dev.mysql.com/doc/refman/8.0/en/ldap-pluggable-authentication.html
MySQL8 中文参考(二十七)(3)https://developer.aliyun.com/article/1566140