
1. 先说结论这个报错到底在提示什么如果你在 Ranger Admin 里配了 LDAP 认证打开登录页输入 FreeIPA 账号结果页面干脆利落地甩给你一句 “Bad credentials”十有八九不是 Ranger 本身坏了而是它拿“你给的这组用户名 密码”去做 LDAP 绑定或搜索时被 FreeIPA 拒了。这句话是你排查链路里最有价值的线索“Bad credentials” 在 LDAP 协议里对应的是错误码 49invalidCredentials意思是服务端确实收到了连接请求但用户名或密码没能通过身份校验。FreeIPA 环境下这个报错尤其容易冒出来因为它不像 Active Directory 那样“随便拿个 userPrincipalName 就能 bind”也不像裸装的 OpenLDAP 那样默认目录结构简单直白。FreeIPA 的默认目录基础是dcexample,dccom这种形式用户放在cnusers,cnaccounts下组放在cngroups,cnaccounts下管理员账号是uidadmin,cnusers,cnaccounts,dcexample,dccom。如果你在 Ranger 里填的 Bind DN、User Search Base 和实际目录结构对不上或者证书信任链不对那 FreeIPA 不会给你任何有歧义的提示直接返回 49。这篇文章不绕弯子直接按我实际排障的顺序把这个报错从“看到报错”到“彻底解决”的完整链路拆给你看。1.1 Bad credentials 在 Ranger 里的真实含义Ranger Admin 的 LDAP 认证本质上不是 Ranger 自己写了套 LDAP 客户端而是走 Java JNDI / Spring LDAP 那套逻辑。你配置好ranger-admin-site.xml里的ranger.admin.auth.methodLDAP、ranger.admin.ldap.url、ranger.admin.ldap.bind.dn、ranger.admin.ldap.bind.password、ranger.admin.ldap.user.searchbase之后用户登录时流程大致是这样Ranger 先用配置里的 Bind DN 和 Bind Password 去连 FreeIPA建立一条“管理通道”用这条管理通道去 User Search Base 里检索你输入的用户名拿到这个用户的完整 DN再用你输入的用户名、密码绑到这条 DN 上进行认证。这三步任何一步失败最终都可能表现为 “Bad credentials”。但其中有个容易被忽略的细节如果是第一步管理通道绑定失败Ranger 通常会在服务端日志里留下更明确的信息比如javax.naming.AuthenticationException: [LDAP: error code 49]或者InvalidCredentialsException而登录界面只给你一句笼统的 “Bad credentials”。所以我的习惯是先看 Ranger 的log/ranger-admin-username.log再回来看界面报错。日志里的原始异常基本能定位到是哪一步出了问题。另外注意“Bad credentials” 不等于“用户不存在”。FreeIPA 出于安全考虑在 LDAP 绑定失败时不会告诉你到底是“用户不存在”还是“密码错误”统一返回 invalidCredentials。这就意味着哪怕你把 User Search Base 配错了找不到用户也可能报 Bad credentials哪怕用户名对、密码对但 Bind DN 没权限搜索同样可能报 Bad credentials。搞清楚这一点你就不会傻乎乎地只改密码了。1.2 为什么 FreeIPA 特别容易触发这类报错我在生产环境里同时维护过 OpenLDAP、AD 和 FreeIPA说实话FreeIPA 在 LDAP 集成这一步的“规矩”是最多的。它默认是 389 端口明文 LDAP 和 636 端口 LDAPS 同时开着但为了安全很多部署只允许 TLS 连接甚至强制要求客户端校验服务端证书。Ranger 的 JVM 默认信任库只信任公开 CAFreeIPA 的证书是自建的 IPA CA 签发你要是没把这个 CA 证书导入 Ranger 所在 Tomcat 的cacerts那么即使密码完全正确TLS 握手也会失败最终表现同样可能被封装成 “Bad credentials”。再一个坑是目录结构。FreeIPA 默认的 users 容器是cnusers,cnaccounts不是大多数 LDAP 文档里写的oupeople。有的人把其它系统的配置习惯直接抄过来把 Search Base 写成oupeople,dcexample,dccomFreeIPA 上压根不存在这个节点搜索返回 0 条记录Ranger 找不到用户对应的 DN自然无法完成后续绑定于是又变成 Bad credentials。还有一个极其隐蔽的点FreeIPA 的默认密码策略里连续多次失败会锁定账号。我见过有人排错时一遍一遍在界面试密码结果把uidadmin这个绑定账号本身给锁了。后面所有请求都失败看起来还是 Bad credentials但实际是账号锁定。所以“先看日志再动配置少做无意义重试”是排障铁律。2. 环境准备与前置检查2.1 FreeIPA 侧的账户与目录结构确认动手改 Ranger 配置之前先把 FreeIPA 侧该确认的信息确认完。你先用 ipa 管理员账号登到一台 FreeIPA 服务器上用ldapsearch或ipa user-find看看当前真实结构。最常见的验证命令是ldapsearch -x -H ldap://ipa.example.com -D uidadmin,cnusers,cnaccounts,dcexample,dccom -W -b dcexample,dccom (objectClassposixAccount) uid cn这里要重点确认几个值Base DN例子里是dcexample,dccom真实环境请用ipa-server-install时设置的域名。如果你不确定可以在 FreeIPA 服务器上执行ipa env或查看/etc/ipa/default.conf里的basedn。用户搜索基址FreeIPA 默认是cnusers,cnaccounts,Base DN。有些版本或自定义 schema 会变所以最好用上面的命令实际确认一下返回条目的 DN 格式。绑定账号Ranger 里配置的 LDAP Bind DN 需要用有权读目录的账号。常规做法是直接用uidadmin,cnusers,cnaccounts,dcexample,dccom简单归简单但权限过大。如果你希望更规范可以在 FreeIPA 里建一个专用服务账号比如uidrangerbind,cnusers,cnaccounts,dcexample,dccom然后用ipa role-add-member给它只读权限。检查完目录结构顺手验证一下这个绑定账号能不能正常用密码绑定。不要跳过这步很多人在 Ranger 里配完报错最后发现其实是绑定账号密码在 FreeIPA 里早就过期了。验证命令ldapsearch -x -H ldap://ipa.example.com -D uidrangerbind,cnusers,cnaccounts,dcexample,dccom -W -b cnusers,cnaccounts,dcexample,dccom (uidalice) uid如果这一步能正常返回用户条目说明账号和密码没问题。如果返回ldap_bind: Invalid credentials (49)那就是密码错误或者账号本身状态有问题去 FreeIPA 侧先处理。2.2 Ranger 侧几个最容易被忽略的配置项Ranger 的 LDAP 配置集中在ranger-admin-site.xml和ranger-ams-*.properties之类文件里。我建议你直接去安装目录的conf下看ranger-admin-site.xml重点关注这些参数参数名作用FreeIPA 常见坑ranger.admin.auth.method认证方式必须为LDAP否则其它配置不生效ranger.admin.ldap.urlLDAP 服务器地址ldap://ipa.example.com:389或ldaps://ipa.example.com:636别混协议ranger.admin.ldap.bind.dn管理通道绑定账号必须写完整 DN不能只写用户名ranger.admin.ldap.bind.password绑定账号密码密码里有特殊字符时注意 XML 转义ranger.admin.ldap.user.searchbase用户搜索基址FreeIPA 默认cnusers,cnaccounts不是oupeopleranger.admin.ldap.user.searchfilter用户搜索过滤条件FreeIPA 用户对象是posixAccount可以用(objectClassposixAccount)ranger.admin.ldap.group.searchbase组搜索基址FreeIPA 默认cngroups,cnaccountsranger.admin.ldap.group.searchfilter组搜索过滤条件常见(objectClassposixGroup)ranger.admin.ldap.referral是否跟随 LDAP 引用FreeIPA 默认不开启建议ignore这些问题里最容易忽略的是ranger.admin.ldap.referral。FreeIPA 在配置了复制拓扑时某个 LDAP 请求可能返回 referral 到另一台副本如果 Ranger 不跟随引用查找用户可能失败表现为找不到用户最终也会演变成 Bad credentials。虽然多数单机部署没这问题但集群部署建议显式配置。另外如果你修改了ranger-admin-site.xml必须重启 Ranger Admin 服务或者至少调用它的 reload 接口。别改完文件就以为立刻生效我见过太多人在这个环节卡半小时。2.3 证书与 JVM 信任库检查如果ranger.admin.ldap.url配的是ldaps://你就要在 Ranger 所在节点的 JVM 里把 FreeIPA 的 CA 证书导入cacerts否则 JVM 在 TLS 握手阶段就会报PKIX path building failed。操作命令如下# 从 FreeIPA 服务器拉取 CA 证书 scp rootipa.example.com:/etc/ipa/ca.crt /tmp/ipa-ca.crt # 找到 Ranger 使用的 JVM # 通常就是 JAVA_HOME/jre/lib/security/cacerts keytool -importcert -alias ipa-ca -file /tmp/ipa-ca.crt \ -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -noprompt导入后用以下命令验证keytool -list -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit | grep -i ipa还有一个容易被忽略的版本问题如果你使用的是ldap://明文协议FreeIPA 默认允许明文绑定吗看部署参数。大部分 FreeIPA 安装默认是允许 389 明文 LDAP 绑定的但建议生产环境用 LDAPS。如果你初期只想快速验证账号密码是否正确可以先用 389 明文调通再切到 636。走 LDAPS 时一定确认防火墙放行 636。3. 认证过程拆解从点击登录到 Bad credentials3.1 Ranger 拿到用户名后到底做了什么事为了讲清楚 Bad credentials 在哪一步产生我画一条最简单链路用户在 Ranger 登录页输入alice和密码点击登录。Ranger 内部顺序不是“拿用户名密码直接绑”而是先配置的管理员 DN 绑定再执行搜索。为什么非得这样因为 LDAP 协议里普通用户绑定需要完整 DN而用户通常只输入短用户名比如alice你要先查出来uidalice,cnusers,cnaccounts,dcexample,dccom再拿这个 DN 去绑定。这里“查找”的动作就需要一个有权搜索目录的服务账号。所以整个逻辑顺序是使用ranger.admin.ldap.bind.dn和ranger.admin.ldap.bind.password建立 JNDI 连接在这个连接上执行ranger.admin.ldap.user.searchfilter搜索ranger.admin.ldap.user.searchbase参数为用户名如果结果恰好返回一个条目取出它的 DN关闭原来的连接拿这个 DN 和用户输入的密码再绑一次绑定成功则认证通过失败则抛出 invalidCredentials界面上就是 “Bad credentials”。理解了这条链路你就能明白Bad credentials 不一定是“你的账户密码不对”也可能是“第一步管理员绑定就失败了”或是“第二步没搜到用户”。所以排查时不能只盯用户密码。3.2 用命令行工具逐步验证每个环节我排 LDAP 认证问题的时候基本不依赖 Ranger 界面直接用命令行把三步验证一遍。建议你也这样效率最高。第一步验证管理员绑定是否成功ldapsearch -x -H ldap://ipa.example.com:389 \ -D uidrangerbind,cnusers,cnaccounts,dcexample,dccom \ -w your-password \ -b cnusers,cnaccounts,dcexample,dccom \ (uidalice) dn如果这里返回ldap_bind: Invalid credentials (49)说明绑定账号密码就不对直接去 FreeIPA 改密码或换账号。第二步验证用户搜索是否能拿到唯一 DN。如果上一步绑定成功但搜索结果为空可能是 searchbase 不对或者 searchfilter 太严格。可以先用宽松一点的过滤器实验ldapsearch -x -H ldap://ipa.example.com:389 \ -D uidrangerbind,cnusers,cnaccounts,dcexample,dccom \ -w your-password \ -b dcexample,dccom \ (uidalice) dn把 base 一栏直接放到域根看能不能扫到。能扫到说明 base 写窄了扫不到说明过滤器或者数据真有问题。第三步模拟用户绑定。拿到uidalice,cnusers,cnaccounts,dcexample,dccom后直接拿这个 DN 和用户的密码绑定ldapsearch -x -H ldap://ipa.example.com:389 \ -D uidalice,cnusers,cnaccounts,dcexample,dccom \ -w alice-password \ -b uidalice,cnusers,cnaccounts,dcexample,dccom \ -s base objectClass*能绑定就说明用户账号没问题。这三条命令分别对应 Ranger 的三步内部逻辑哪一步挂在命令行里原样暴露。这比看一堆 Java 堆栈直观得多。3.3 证书与 TLS 在链路里的隐藏作用很多人忽略一个细节Ranger 绑定 FreeIPA 时即使你配置的是ldaps://JVM 也默认不会直接信任“私有 CA 签发的证书”。如果没导入证书你看到的可能是另一类异常比如javax.net.ssl.SSLHandshakeException但在某些封装版本里前端仍然显示 Bad credentials。排查方法是在 Ranger 日志里搜SSLHandshakeException或PKIX一旦出现优先怀疑信任库。FreeIPA 的目录服务同时监听 389 和 636但 636 上的证书默认是 IPA CA 签发的并且通常包含服务器主机名。你在配置 LDAPS URL 时最好使用 FreeIPA 服务器的真实主机名或 IP 与证书对应的地址别用ipa.example.com结果解析到别的 IP。如果主机名对不上证书校验也会失败。另一个经验是先用openssl s_client验证服务端证书链确保 Ranger 所在节点能正常建立 TLS 连接openssl s_client -connect ipa.example.com:636 -showcerts /dev/null | head -20看输出里的subject和issuer确认它确实是由 IPA CA 签发的并且证书没过期。这一步能为你省下不少回头看日志的时间。4. 解决方案与配置示范4.1 在 ranger-admin-site.xml 中的正确配置方式当你已经把前置检查都做完确认 FreeIPA 侧的账号密码和目录结构都没问题接下来就改 Ranger 配置。下面是我在一套 CentOS 上部署的 Ranger 与 FreeIPA 集成时用的最小可用配置直接贴在ranger-admin-site.xml里property nameranger.admin.auth.method/name valueLDAP/value /property property nameranger.admin.ldap.url/name valueldaps://ipa.example.com:636/value /property property nameranger.admin.ldap.bind.dn/name valueuidrangerbind,cnusers,cnaccounts,dcexample,dccom/value /property property nameranger.admin.ldap.bind.password/name valueyour-bind-password/value /property property nameranger.admin.ldap.user.searchbase/name valuecnusers,cnaccounts,dcexample,dccom/value /property property nameranger.admin.ldap.user.searchfilter/name value(objectClassposixAccount)/value /property property nameranger.admin.ldap.group.searchbase/name valuecngroups,cnaccounts,dcexample,dccom/value /property property nameranger.admin.ldap.group.searchfilter/name value(objectClassposixGroup)/value /property property nameranger.admin.ldap.referral/name valueignore/value /property需要注意一点bind.password是明文存在 XML 里的。如果密码里有、、这类特殊字符记得做 XML 转义否则 Tomcat 会直接解析失败。我更推荐的做法是先用一段纯文本的配置调通再考虑用 Ranger 的加密工具或者交给配置管理系统管理。改完配置文件重启 Ranger Admin 服务。不同发行版命令不一样常见的是sudo systemctl restart ranger-admin如果用的是旧版安装方式可能是/usr/bin/ranger-admin start。重启后在日志目录里能看到新的启动记录确认没有 LDAP 相关报错。4.2 FreeIPA 的“管理员 DN”到底该怎么填这是 Bad credentials 排障中最高频的坑。很多人把 FreeIPA 的管理员填成admin或者填成cnDirectory Manager然后被拒。FreeIPA 有两个容易混淆的管理身份IPA 管理用户默认是admin但它不是一个 LDAP 根节点它的完整 DN 是uidadmin,cnusers,cnaccounts,dcexample,dccomDirectory ManagerFreeIPA 基于 389 Directory Server底层确实存在一个cnDirectory Manager但它在 FreeIPA 里默认是禁用的只有通过特定配置才能启用或重置密码常规部署下别指望用它连。所以在 Ranger 里Bind DN 要么填uidadmin,cnusers,cnaccounts,dcexample,dccom要么像我前面说的单独建一个rangerbind专用账号。单独建账号的好处很多权限可控、日志清晰、不会因为管理员密码轮换而影响 Ranger。创建方式是ipa user-add rangerbind --firstRanger --lastBind --password然后给它只读权限。最简单粗暴的方式是把rangerbind加进User Administrators或IPA Read User Administrators这种角色但更稳妥的做法是只授予它读取用户和组的权限。FreeIPA 里没有特别精细的“LDAP 只读”一说但你可以通过ipa permission-add和ipa privilege-add来定制。我的个人建议是如果测试阶段只是内网环境直接用uidadmin也没什么大问题但投产环境务必建专用账号避免哪天有人把 admin 密码改了或锁了连带 Ranger 也瘫痪。这个坑我踩过当时整个 Ranger Admin 都登不进去最后还是 SSH 到宿主机上临时把认证方式改成本地用户才缓过来。4.3 配置完成后如何完整自检配置改完、服务重启后别急着在浏览器里输密码先做一轮命令行自检。第一步用ldapsearch以rangerbind身份验证连通性。这一步其实你前置检查时就应该做过这里再重复一次确保当前状态一切正常。第二步确认 JVM 能成功连接 LDAPS。可以写一个极简的 Java 示例或直接用jshell跑 JNDI 调用但说实话有点重。更轻量的是直接看 Ranger 日志。启动 Ranger 后如果 LDAP 配置正确日志里一般不会出现Caused by: javax.naming.AuthenticationException。如果配置错误日志会非常清晰。常用的日志路径tail -f /opt/ranger/log/ranger-admin-user.log第三步在 Ranger UI 上先用一个已知正常的 FreeIPA 用户登录同时观察日志。如果日志里出现authentication failed for alice但是命令行验证 alice 密码没问题那问题大概率出在搜索过滤器或者证书。如果日志里出现no results found for user alice那搜索基址写错了的可能性更大。我一直强调自检要全链路是因为 Bad credentials 是真“敷衍”的报错它把每一步失败都折叠成同一个提示。只有你自己一步步把链路摊开才能确认问题到底在哪。5. 常见问题与实操避坑5.1 现实中踩过的几个典型错误配置下面这几类问题我几乎每隔一段时间就会碰到一次列成表方便你对照检查。现象直接原因解决方案界面 Bad credentials日志里出现PKIX path building failed没导入 FreeIPA CA 到 JVMcacerts用 keytool 导入/etc/ipa/ca.crt界面 Bad credentials日志里出现no results foundUser Search Base 或过滤条件不对把 Search Base 改成cnusers,cnaccounts先用(uid%s)测试界面 Bad credentials日志里显示AuthenticationExceptionBind DN 或密码错误命令行手动绑定验证必要时重置绑定账号密码界面 Bad credentials命令行绑定正常Ranger 的 JNDI 没有跟随 referral设置ranger.admin.ldap.referralignore所有账号登录都失败且每个账号尝试后间隔变长FreeIPA 密码策略锁定了绑定账号或不间断重试检查 FreeIPA 侧锁定状态等待解锁或手动解锁第五种情况值得多说两句。FreeIPA 默认密码策略会在错误尝试次数达到阈值后锁定账号常见的阈值在/etc/ipa/default.conf或通过ipa pwpolicy-show查看。如果你用uidadmin做绑定账号一旦它被锁整个 Ranger 的 LDAP 通道就断了。这个状态下你从 UI 看什么都像 Bad credentials但本质是绑定账号失效。临时办法是通过 IPA 控制台或命令行解除锁定根本办法就是别把高权限账号直接暴露给中间件。5.2 日志与排查工具速查排障时建议优先翻这几类日志Ranger Admin 日志/opt/ranger/log/ranger-admin-user.log重点关注Caused by字段FreeIPA 目录服务器日志journalctl -u dirsrvHOSTNAME或/var/log/dirsrv/slapd-HOSTNAME/errors能看到客户端传来的绑定请求和错误码Tomcat 日志如果 Ranger 跑在 Tomcat 里catalina.out里可能有连接池或 JNDI 相关异常。工具方面我强烈建议你掌握ldapsearch和openssl s_client这两条命令。前者能验证 LDAP 协议层的所有认证细节后者能验证 TLS 层证书状态。Ranger 界面上的报错信息量太少了全靠命令行补。如果你希望看得更细一点还可以在 Ranger 日志级别上调到 DEBUG。不同版本入口不一样常见做法是在logback.xml或log4j2.xml里将org.apache.ranger.admin的级别调成 DEBUG然后重现一次登录失败。输出里会包含 JNDI 调用栈和具体 LDAP 错误码能省掉不少猜谜时间。5.3 一次真实案例的排错记录最后分享一个我印象比较深的案例。客户环境是 FreeIPA 加 Ranger现象是任何 FreeIPA 用户都登不上界面稳定报 Bad credentials。我登录 FreeIPA 服务器用rangerbind手动绑定成功用普通用户绑定成功目录搜索也没问题。当时我就想问题多半不在 FreeIPA 侧而在 Ranger 侧。登录 Ranger 服务器看日志发现报错里有SSLHandshakeException但日志头部却显示它连的是ldap://而不是ldaps://。这就怪了。后来发现ranger-admin-site.xml里的 URL 确实写的是ldap://ipa.example.com:389但 Ranger 某些内部服务配置文件里残留了旧的ldaps://ipa.example.com:636地址导致实际验证走的是 LDAPS而证书又没导入。这个环境里有两处配置文件不一致属于“历史遗留”问题。处理方式很简单统一改成ldaps://ipa.example.com:636并确认 TLS 证书导入成功。改完后重新登录一次通过。这个案例说明了一件事排障时别只盯一个文件Ranger 里和 LDAP 相关的配置可能分布在多个配置文件和服务实例里ranger-admin-site.xml、ranger-usersync-site.xml甚至一些环境变量都可能覆盖默认值。遇到 Bad credentials先全局搜一遍 LDAP 相关配置再去判断谁生效。最后说点个人体会排了这么多年 LDAP 认证问题我最大的感触是遇到 “Bad credentials” 先别急着猜密码花十分钟把命令行链路跑一遍往往比在界面上反复试快得多。尤其 FreeIPA 这种自带 Kerberos、自带 CA、密码策略又严格的环境它的设计逻辑和普通 OpenLDAP 差别很大很多坑不是它“有问题”而是我们对它的目录约定不熟。我个人现在每集成一套 FreeIPA都会顺手建一个专用的低权限绑定账号并把这个账号、DN、搜索基址、证书导入步骤都写进交付文档。后续出了任何认证问题团队成员按文档里的验证命令 5 分钟就能定位。你不用“一把梭”去追求最复杂的安全方案但一定别把排障步骤省掉。Bad credentials 只是一个结果真正的解法永远在“查到哪一步失败”这个过程里。