mysql 8.0 社区版不支持原生 mfa,必须依赖 8.0.27+ 版本及 authentication_pam 等插件,结合 linux pam 与 pam_google_authenticator 实现密码+totp 双因子;authentication_ldap_sasl 仅限企业版,社区版不可用。

MySQL 8.0 社区版不支持原生 MFA,必须靠插件组合 + 外部系统协作才能落地;8.0.27+ 是硬门槛,低于此版本连 REQUIRE MULTIFACTOR 语法都报错。
确认 MySQL 版本与关键插件是否就位
低于 8.0.27 的 MySQL 根本无法解析多因子语法,CREATE USER ... REQUIRE MULTIFACTOR 会直接报错 ERROR 1064。先验证:
- 运行
SELECT VERSION();,确保输出 ≥8.0.27 - 执行
SHOW PLUGINS LIKE 'authentication%';,检查以下三项是否状态为ACTIVE:
—authentication_pam(PAM 方案必需)
—authentication_policy(MFA 策略调度器,8.0.27+ 新增)
—authentication_fido(仅 FIDO2 安全密钥,不兼容手机 App) - 若缺失,用
INSTALL PLUGIN authentication_policy SONAME 'authentication_policy.so';安装;注意SONAME名称因发行版而异,先查SELECT @@plugin_dir;再确认文件是否存在
用 PAM 实现密码 + TOTP(Google Authenticator)双因子
这是社区版唯一能对接手机 App 动态码的路径,但极易因三处错位导致用户全部锁死:
- PAM service 名必须严格匹配:创建
/etc/pam.d/mysqld(不是mysql或mysqld_safe),权限644,属主root:root - 配置顺序不能颠倒,例如:
auth [success=ok default=ignore] pam_sss.soauth [success=done default=bad] pam_google_authenticator.so secret=/var/lib/google-authenticator/${USER} - MySQL 用户名必须与 Linux 用户名完全一致(大小写、下划线、连字符都不能差),否则 PAM 根本收不到用户名去读密钥文件
-
mysql进程用户(通常是mysql)需有权限读取密钥文件,常见做法是加 ACL:setfacl -m u:mysql:r /var/lib/google-authenticator/alice
创建用户时的语法陷阱
一旦启用 PAM 认证,IDENTIFIED BY 就失效了,写进去反而覆盖认证方式,导致登录失败:
- 正确写法:
CREATE USER 'alice'@'%' IDENTIFIED WITH authentication_pam AS 'mysqld';
其中'mysqld'必须与 PAM service 文件名(即/etc/pam.d/mysqld)完全一致 - 错误写法:
CREATE USER 'alice'@'%' IDENTIFIED BY 'xxx' IDENTIFIED WITH authentication_pam AS 'mysqld';—— 会报错或静默降级为密码认证 - 客户端连接必须加参数:
mysql -u alice -p --enable-cleartext-plugin,否则握手卡在Authentication plugin 'authentication_pam' cannot be loaded
为什么 authentication_ldap_sasl 在社区版根本装不上
官方社区二进制包(如 Ubuntu 的 mysql-server-8.0)根本不带这个插件:
- 执行
INSTALL PLUGIN authentication_ldap_sasl SONAME 'authentication_ldap_sasl.so';会报Plugin 'authentication_ldap_sasl' is not loaded或File not found -
SHOW PLUGINS;里压根搜不到该插件名 - 它只存在于 MySQL Enterprise Edition,且需有效 license;社区版唯一出路就是走 PAM 链路
- 别信网上“改源码编译”的方案——插件依赖企业版专有库,编译通不过
真正难的不是配命令,而是 PAM 配置顺序、密钥路径变量展开、SELinux 上下文、Linux 用户与 MySQL 用户映射这四层嵌套校验;任何一层出错,日志里只显示 Access denied,实际连哪一环失败都得翻 /var/log/secure 或 journalctl -u mysqld 手动对齐。











