MySQL 8.0+ 使用 authentication_ldap_sasl
插件连接 LDAP
MySQL 原生支持 LDAP 外部认证,但仅限于 MySQL 8.0.13 及以上版本,且必须启用
authentication_ldap_sasl插件(不是旧版的
authentication_ldap_simple)。该插件依赖 OpenLDAP 客户端库和 SASL 机制,不支持纯 LDAPS 绑定或匿名绑定。
常见错误现象包括:
Plugin 'authentication_ldap_sasl' is not loaded(未安装插件)、
Access denied for user 'xxx'@'%' (using password: YES)(LDAP 绑定失败但 MySQL 日志未明确提示)、或 MySQL 启动时报
Failed to initialize plugin 'authentication_ldap_sasl'(OpenLDAP 库缺失)。 确认插件已安装:
INSTALL PLUGIN authentication_ldap_sasl SONAME 'authentication_ldap_sasl.so';检查依赖:Linux 上需安装
openldap-clients和
cyrus-sasl-plain(RHEL/CentOS)或
libsasl2-modules(Debian/Ubuntu) MySQL 配置文件中必须设置:
plugin_load_add = authentication_ldap_sasl.so,否则重启后插件丢失 LDAP 服务器需开放
389(LDAP)或
636(LDAPS)端口,且 MySQL 服务器能直连——NAT、防火墙、SELinux 均可能拦截
创建 LDAP 映射用户时必须指定 IDENTIFIED WITH authentication_ldap_sasl
MySQL 用户不能只靠
CREATE USER指定密码;必须显式声明认证方式,并绑定 LDAP 属性。用户账户本身不存密码,仅作权限容器,实际校验由 LDAP 服务器完成。
典型误操作是漏写
AS子句或写错 DN 格式,导致创建成功但登录始终失败。例如:
CREATE USER 'alice'@'%' IDENTIFIED WITH authentication_ldap_sasl AS 'uid=alice,ou=people,dc=example,dc=com';中若
uid=alice在 LDAP 中实际为
sAMAccountName=alice(AD 环境),则匹配失败。 AD 环境常用映射格式:
AS 'CN=alice,CN=Users,DC=example,DC=com'或使用 UPN:
AS 'alice@example.com'(需 LDAP 服务器支持) OpenLDAP 常用格式:
AS 'uid=alice,ou=People,dc=example,dc=com',注意大小写敏感性和 OU 名称是否准确 若 LDAP 支持组映射,可配合
authentication_ldap_sasl的
ldap_server配置项 +
ldap_group_search_attr实现角色继承,但 MySQL 本身不自动同步组权限,仍需手动
GRANT测试映射是否有效:用
ldapsearch -x -H ldap://ldap.example.com -b "dc=example,dc=com" "(uid=alice)"先验证 DN 可查
mysql.user
表中 plugin
和 authentication_string
字段含义易混淆
启用 LDAP 后,
mysql.user表中对应用户的
plugin列值为
authentication_ldap_sasl,而
authentication_string存储的是 LDAP DN(或 UPN)字符串,**不是密码哈希**。这个字段会被 MySQL 直接用于构造 LDAP BIND 请求。
容易踩的坑是:执行
ALTER USER ... IDENTIFIED BY 'xxx'会覆盖
authentication_string为密码哈希,导致 LDAP 认证失效;或者误以为清空
authentication_string就能“禁用 LDAP”,实际会导致
Empty authentication string错误。 修改 LDAP 映射应使用:
ALTER USER 'alice'@'%' IDENTIFIED WITH authentication_ldap_sasl AS 'uid=alice-new,ou=People,dc=example,dc=com';禁用 LDAP 认证需切换回本地认证:
ALTER USER 'alice'@'%' IDENTIFIED WITH mysql_native_password BY 'newpass';不要直接
UPDATE mysql.user修改
authentication_string,MySQL 不保证事务一致性,且可能跳过插件校验逻辑 查询当前映射:
SELECT User, Host, plugin, authentication_string FROM mysql.user WHERE User = 'alice';
调试 LDAP 连接失败优先查 MySQL 错误日志与 ldapsearch
对比
MySQL 的 LDAP 插件日志非常简略,默认只在错误日志中输出
LDAP bind failed或
Cannot contact LDAP server,无法定位是网络、证书、DN 还是权限问题。最可靠的方式是复现相同参数用命令行工具验证。
关键点在于:MySQL 插件使用的 LDAP 连接参数(如
ldap_server_host、
ldap_server_port、
ldap_bind_base_dn)必须与
ldapsearch命令完全一致,否则对比无意义。 从 MySQL 配置中提取参数:
SELECT * FROM performance_schema.variables_by_thread WHERE VARIABLE_NAME LIKE 'ldap%';(需开启相关 Performance Schema 表) 等效
ldapsearch命令示例(OpenLDAP):
ldapsearch -x -H ldap://ldap.example.com:389 -D "cn=admin,dc=example,dc=com" -w 'adminpass' -b "dc=example,dc=com" "(uid=alice)"若用 LDAPS,确保 MySQL 配置了
ldap_ssl_ca路径,且该 CA 文件对 MySQL 进程可读(常因 SELinux 或文件权限拒绝) 开启插件调试日志(临时):
SET GLOBAL log_error_verbosity = 3;,然后观察错误日志中是否有更细粒度的 SASL 协商失败信息
LDAP 认证链路长、环节多,任意一环(网络、TLS 证书、DN 格式、LDAP 服务端 ACL、MySQL 插件配置)出问题都会表现为“用户名或密码错误”。比起反复改 MySQL 配置,先用
ldapsearch和
telnet ldap.example.com 389把底层通路跑通,是最省时间的做法。
