请把那句话理解为关于共享对象和函数指针的陈述,而不是关于密码。同样的词可能来自一个 OpenVPN 插件、为单一服务加载的 PAM 栈,或 RADIUS 守护进程内部,而这是三种不同的排查。先确定进程。

以下检查假定该消息是通过 VPN 登录时的 Linux-PAM 集成出现的。如果它来自 RADIUS 服务器自身的配置,应从那个守护进程的证据入手。

先命名进程,再命名软件包

有三个组件都被称为模块,而它们并不能互换。OpenVPN 认证插件由 VPN 守护进程加载,实现该守护进程的回调接口。PAM 模块则是一个共享对象,由 libpam 为具名服务加载,并实现如下入口点:pam_sm_authenticate。FreeRADIUS 模块是该守护进程自身配置的一部分。同样措辞的消息可能来自这三者中的任何一个,所以第一个问题是哪一行日志产生了它。

把一次失败尝试的时间戳在 VPN 日志与系统认证日志之间对齐,然后读取摘要之前的那几行。具体的加载器消息通常已经在那里了。

先读加载错误,再读入口点

当 PAM 无法加载所选的共享对象,或已加载的对象没有提供该栈条目所需的函数时,它会报告未知模块。这两者是不同的修复:前者是路径、打包或 ABI 问题,后者是入口点不匹配。认证行需要 pam_sm_authenticate,而账户行需要 pam_sm_acct_mgmt,只实现其中一个的库会在另一个上失败,正如 分发器代码 所示。在磁盘上找到文件并不能证明其中任何一项。

从另一个发行版或另一种 CPU 架构取来同名库并不是修复,而且可能让进程加载一个从未针对其 libpam 测试过的模块。在改动任何东西之前,先检查拥有目标路径的软件包以及文件的真实架构。

保留栈原本提供的保证

让这个错误立刻消失的最快办法也是最糟的:把必需的模块标为可选、删掉账户阶段,或者插入无条件放行。这些做法都会把一次失败的检查变成一次不存在的检查,登录于是因为没人设想的理由而成功。重设密码和更换共享密钥同样补不上缺失的函数,因为失败发生在任何凭据到达后端之前。

多模块栈可能在失败条目之前已经运行过另一个后端,所以这个错误并不能证明没有发出 RADIUS 请求。

验证登录,而不是模块

修正不匹配之后,测试实际的准入路径。有效账户应当通过,凭据错误仍应失败,被禁止的账户仍应被拒绝。还要确认任何证书或附加因素要求仍在生效,因为跳过一个阶段的修复后栈从客户端看来就像是成功。

模块能干净地加载只是进展,并不等于测试完成。

记录涉及的服务名、策略文件和入口点,以及你用作证据的那一次尝试。正是这份记录让下一次事件变成一次查表,而不是一场考古。

相关文章