首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Linux 与国产操作系统登录如何接入国密双因子:PAM 栈改造实战

Linux 与国产操作系统登录如何接入国密双因子:PAM 栈改造实战

原创
作者头像
用户12597027
发布于 2026-09-24 15:18:32
发布于 2026-09-24 15:18:32
580
举报

摘要:本文面向运维与安全工程师,拆解 Linux 与国产操作系统登录链路中 PAM 可插拔认证模块的工作机制,给出将国密双因子无缝接入 SSH 与图形桌面登录的完整改造路径,涵盖 PAM 模块编排、gdm/lightdm 集成、会话级因子校验、失败锁定策略与统一策略下发,并对比单机、联网、SaaS 三类部署形态在离线应急与审计上的取舍。 正在上传图片...

关键词:操作系统双因素认证, 国密USBKey, Linux 指纹登录, 等保2.0, 远程登录安全, PAM 模块

在等保 2.0 三级及以上系统中,"仅口令认证"早已不满足身份鉴别项的强度要求。对运行 CentOS、Ubuntu、麒麟 V10、统信 UOS 的服务器与办公终端而言,真正的难点不在于"有没有第二因子",而在于"第二因子能不能接进既有的登录链路,且不影响既有运维习惯"。本文以 Linux/国产操作系统的 PAM(Pluggable Authentication Modules,可插拔认证模块)栈为切入点,逐步拆开从 SSH 远程接入到图形桌面会话的认证改造过程,并讨论失败锁定、统一策略下发与离线应急等工程化问题。

一、先理解 PAM 的四类栈

PAM 是类 Unix 系统统一身份鉴别的事实标准,在应用程序(login、sshd、gdm、sudo 等)与具体认证实现之间插入一层配置化接口。每个调用 PAM 的程序按顺序执行四种类别的栈:

栈类别

触发时机

常见用途

auth

鉴别用户身份

口令校验、USBKey 挑战应答、OTP 比对、指纹仪校验

account

鉴别通过后

账号是否过期、是否允许此时此地登录

password

改密时

口令复杂度、旧口令校验

session

登录前后

挂载家目录、环境变量、拔 Key 锁屏钩子

理解这一点很关键:我们要把"国密双因子"塞进 auth 栈,把"拔 Key 自动锁屏"挂到 session 栈,把"失败锁定"通过 account 或 auth 的失败计数实现。只要编排正确,应用层(无论 SSH 还是桌面)几乎零改动,这也是双因子方案大多选 PAM 而非重写登录器的原因——改造面小、回滚快、跨应用一致。

更进一步看,PAM 的"可插拔"本质是一份栈式责任链:每个模块返回 success、ignore、die、reset 等状态,控制字如 required、requisite、sufficient、optional 决定状态如何汇总。掌握控制字语义才能兼顾安全与体验,后文会反复用到。

二、SSH 远程接入:最小侵入的改造起点

Linux 与国产系统登录链路示意(PAM 四类栈与因子编排)
Linux 与国产系统登录链路示意(PAM 四类栈与因子编排)

SSH 是运维主入口,改造风险最敏感——认证栈配错可能把自己挡在门外。稳妥做法:先用跳板机灰度,保留带口令的兜底账号与带外控制台,确认双因子链路稳定再铺开。

典型的 /etc/pam.d/sshd 改造如下(示意,非某产品原生命令):

代码语言:pam
复制
# 先尝试国密 USBKey 挑战应答
auth    sufficient   pam_sm3_challenge.so try_first_pass
# Key 缺失或失败,则回落到 OTP
auth    [success=1 default=ignore] pam_otp.so
# 两者都失败才用口令,且口令仅在第二因子通过后被采纳
auth    requisite    pam_unix.so try_first_pass
# 任意一次失败即记录并计数
auth    required     pam_faillock.so preauth

这里有几个工程细节:

  1. 因子顺序决定体验。把 USBKey 放 sufficient,带着 Key 插在机器上就能直接过、不打扰日常;Key 不在时自动回落 OTP,适合远程接入场景。
  2. requisite 与 required 的语义差异。requisite 失败立即返回,不再执行后续;required 即便失败也继续跑完再汇总。失败锁定计数建议用 required 的 pam_faillock,避免把正常回落误判为暴力破解。
  3. 远程会话的因子选择。纯远程接入(无物理 Key)时 OTP 是更现实的第二因子,但其种子下发与时钟同步需后端支撑,引出后文"联网/ SaaS 部署"。
  4. 不要忘记 UsePAM yes 与 ChallengeResponseAuthentication。OpenSSH 服务端须开 PAM 通道,键盘交互式认证才能把自定义提示透传客户端,否则用户只看到口令框。

三、图形桌面登录:gdm 与 lightdm 的差异

服务器 SSH 改造相对直白,但带显示器终端要走图形登录器。麒麟 V10 默认 gdm,统信 UOS 与部分 Ubuntu 定制版用 lightdm,二者对 PAM 调用点不同,改造易踩坑。

3.1 gdm 的会话级因子

gdm 在 /etc/pam.d/gdm-password 与 /etc/pam.d/gdm-fingerprint 两处分别处理密码与生物特征。若要"Linux 指纹登录",正确做法是在 gdm-password 的 auth 栈里串联指纹仪校验模块,而非另起独立登录器——否则会丢失调制解调器式的会话恢复能力。

代码语言:pam
复制
# gdm-password:先指纹后口令,二选一即可
auth    [success=done default=ignore] pam_print_device.so dev=/dev/fp_touch
auth    requisite    pam_unix.so try_first_pass
# 会话建立后挂拔 Key 锁屏
session required     pam_lock_on_remove.so

注意:此处指纹仪为外接触摸式设备,走 /dev 输入节点,校验在本地 PAM 模块内完成,模板不出终端;它与"指纹 USBKey"是两类东西——前者仅采集,后者兼有存储与签名,选型时易混为一谈。

3.2 lightdm 的 greeter 钩子

lightdm 多一层 greeter(登录界面)进程,PAM 对话由 greeter 转发。改造时除改 /etc/pam.d/lightdm,还要确认 greeter 支持"自定义提示文案"(如"请触摸指纹仪""请输入动态口令"),否则用户面对黑框不知所措。

代码语言:pam
复制
# lightdm:国密 OTP + 掌纹仪双因子
auth    [success=1 default=ignore] pam_palm_device.so dev=/dev/palm_touch
auth    sufficient   pam_otp.so
auth    requisite    pam_unix.so try_first_pass

掌纹仪同属外接触摸式设备,适合无接触、卫生要求高的场景(如医疗、食堂终端),在 PAM 层与指纹仪仅设备节点与比对库不同,编排一致。

四、会话级因子与"拔 Key 锁屏"

很多方案双因子只校验登录那一刻,成功后拔 Key 毫无影响——工位离座场景下的巨大安全洞。真正会话级保护要把钩子挂到 session 栈:

代码语言:pam
复制
session required pam_lock_on_remove.so \
        lock_cmd="loginctl lock-sessions" \
        poll_interval=2

该模块在会话存活期间轮询设备节点,一旦国密 USBKey 消失,立即触发锁屏。对工控、柜台这类"人走机不停"的场景尤其重要;实现上轮询间隔过短占 CPU、过长留空窗,锁屏命令要适配 systemd-logind 与老旧 ConsoleKit,否则老系统拔 Key 不锁屏。

五、失败锁定策略:别把正常回落当攻击

失败锁定与拔 Key 锁屏流程示意
失败锁定与拔 Key 锁屏流程示意

双因子引入后,失败组合变多(Key 没插、OTP 输错、口令拼错),锁定策略必须精细,否则运维会被自己锁死。

代码语言:pam
复制
# 在 auth 前预检
auth required pam_faillock.so preauth silent deny=5 unlock_time=900
# 在 auth 后记录
account required pam_faillock.so

要点:

  • deny=5 表示连续 5 次失败锁定;SSH 远程接入建议收紧到 3 次,本地带显示器终端可放宽到 10 次,因本地有物理在场性。
  • unlock_time=900 是临时解锁,超时自动放开;同时应保留管理员手动 faillock --reset 的应急通道,避免分支机构无人能救。
  • 区分因子类型计数。理想实现应为"口令失败"与"第二因子失败"分别计数,避免用户因为 OTP 手抖三次就被整体锁死。
  • 锁定要看来源。来自公网的远程接入失败应计入更严格的桶,内网跳板可适当宽容,这需要 PAM 模块能拿到来源 IP 并做分支。

六、统一策略下发:从单机到平台

当终端规模从几台涨到几百台,"逐台改 /etc/pam.d/"就不可持续了。三部署形态在此分化:

部署形态

策略来源

离线表现

适合场景

单机

本地配置文件

完整可用,OTP 需预生成应急码

隔离网、工控、涉密机

联网

中心平台下发

断网时回落到本地缓存策略

企业内网、分支机构

SaaS

云端租户策略

同样依赖本地缓存,断网不中断

跨地域、外包终端

通用方案通常把因子组合、失败锁定次数、是否启用拔 Key 锁屏抽象为平台侧策略对象,经代理下发到各终端本地 PAM 配置生成器,使安全团队改一处策略即可让数百台麒麟、统信、CentOS 登录行为同步收敛,避免脚本漂移。

需要强调的是,无论平台多强,终端本地的 PAM 配置必须自洽可离线生效。一旦中心平台不可达就拒绝登录,等于把可用性命门交给网络,这在等保的"韧性"要求上是倒退。平台价值是"集中定义、统一收敛",而非"运行时强依赖"。

七、离线双因子:应急 OTP 与预生成码

"离线双因子"是远程登录安全里最易被忽视的环节。设想分支机构终端与中心平台网络中断,此时:

  • 国密 USBKey 仍是本地可验证的,因为它依赖 Key 内私钥做挑战应答,不联网;
  • OTP 若依赖中心时间同步则会失效,必须支持预生成一次性应急码(一组打印或离线保管的码),在断网时作为第二因子兜底;
  • 联网/ SaaS 部署的终端,平时把策略与 OTP 种子缓存在本地加密区,断网期间按缓存继续校验。

从攻击面看,离线应急码须足够随机、一次性、绑定具体终端与有效期,纸质码入柜保管并定期轮换。

更进一步,应急码的使用须被审计:哪台终端、哪个账号、何时用应急码登录应记为高亮事件并事后复核,因其天然绕过常规第二因子。运维应建立"应急码使用即告警、七日内复盘"机制,将其视为可控安全事件而非普通登录。

八、全链路审计:让每次登录可举证

等保 2.0 的"安全审计"项要求记录关键安全事件。双因子改造后,审计字段应至少包含:

审计字段

说明

价值

时间戳

登录/登出/锁屏时刻

行为回溯

终端标识

主机名/序列号

定位资产

用户标识

登录账号

责任界定

因子类型

USBKey/OTP/指纹/掌纹

鉴别强度证明

因子结果

成功/失败及原因

攻击画像

会话事件

拔 Key 锁屏、异常结束

离座风险

这些日志应同时落本地与上报平台(联网/SaaS 形态),本地留存保证断网不丢证据,平台汇聚便于跨终端关联;日志须防篡改,至少仅追加(append-only)并定期哈希校验,否则可被清除以掩盖横向移动。

在等保测评时,审计字段的"因子类型"与"因子结果"是证明落地双因子的关键证据;若日志只记"登录成功"而不记用何种第二因子成功,测评员很难采信。

九、落地排障清单

实务中常见的几个坑:

  1. PAM 顺序写反导致口令绕过双因子。sufficient 因子若放在 requisite 口令之前且无约束,可能"随便一个因子成功就放行"。务必明确第二因子与口令是"与"还是"或"关系,并在注释里写清。
  2. gdm/lightdm 与 SSH 策略不一致。易出现"SSH 要双因子、桌面只要口令"的裂口,攻击者可绕到图形界面。建议用同一策略生成器产出两套 /etc/pam.d/ 片段。
  3. 指纹/掌纹仪权限问题。设备节点默认属主可能是 root,普通登录器进程无读权限,表现为"摸了没反应"。需在 udev 规则里把设备赋给登录用户组,并在 greeter 侧赋予访问能力。
  4. 改完直接退出测试会话。永远保留一个已登录救援会话或带外控制台,确认新配置能登录再关旧会话,否则只能进单用户模式救场。
  5. SELinux/AppArmor 拦截。加固系统下 PAM 模块新增读取路径可能被策略拦截,表现为加载失败却无明显报错,需补充对应域规则或布尔开关。

通用方案通常提供"配置预检 + 灰度回滚":先在新 PAM 配置上模拟认证,失败自动回退上一版,降低第 4 类事故概率。该思路具备通用性,自研方案也应保留"配置版本化 + 自动回滚"。

十、国产 OS 适配的特殊性

麒麟 V10 与统信 UOS 的 PAM 栈与上游基本一致,但有两点要注意:

  • 国密算法支持。挑战应答若用 SM2/SM3,需确认系统内核与 openssl 国密补丁到位,否则 pam_sm3_challenge.so 无法加载。CentOS 7 老内核尤需打补丁,部分裁剪镜像甚至缺国密引擎。
  • 安全启动与模块签名。部分加固镜像开启内核模块签名校验,PAM 模块虽非内核模块,但若涉及内核态驱动(如某些指纹仪驱动)需一并签名,否则开机加载失败、登录器起不来。

工控终端登录环境更苛刻:很多工控机跑裁剪版系统,glibc 版本老、缺依赖。改造前应先在镜像里用 ldd 全量扫描所有 PAM 模块的符号依赖,避免现场"登录界面转圈"却查不出原因;同时工控机常无显示器,需确认双因子在纯串口/无界面环境下的回落路径(如仅 USBKey + 应急码)。

十一、自己写一个最小 PAM 模块的视角

理解改造,最好动手写一个最小 auth 模块。PAM 模块核心是实现 pam_sm_authenticate 函数,签名约定固定,返回值用 PAM_SUCCESS / PAM_AUTH_ERR 等宏;编译为 .so 放到 /lib64/security/ 后即可在 /etc/pam.d/ 里引用。

代码语言:c
复制
#include <security/pam_modules.h>
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh,
        int flags, int argc, const char **argv) {
    const char *user = NULL;
    pam_get_user(pamh, &user, NULL);
    /* 这里接你的第二因子校验,如读取 /dev 设备做比对 */
    if (second_factor_ok(user)) return PAM_SUCCESS;
    return PAM_AUTH_ERR;
}

写模块时务必处理"用户取消""设备不存在"与"超时"三种非成功态并映射到不同返回值,否则上层会把"设备没插"误当"认证失败"而触发锁定,这也是自研方案在真实环境翻车的主因。

十二、性能与体验的平衡

双因子常被吐槽"慢",瓶颈主要在:USBKey 的 SM2 签名(几十毫秒,可接受)、OTP 网络校验往返(联网形态建议本地校验兜底)、指纹/掌纹仪采集比对(触摸式通常 < 1 秒)。优化上:把第二因子是否必要做成上下文感知(内网带 Key 免 OTP、公网强制双因子);会话级轮询改用 inotify 而非忙等;登录后会话钩子尽量异步,避免阻塞 greeter 显示。

十三、特权提权场景:sudo 与 su 也要双因子

登录双因子只守住"进门"这一关,但等保同样关注"进门之后提权"的鉴别强度。默认 sudo 只校验调用者口令,攻击者拿到低权账号后仍可凭口令提权到 root。正确做法是在 /etc/pam.d/sudo 的 auth 栈里复用同一套第二因子模块:

代码语言:pam
复制
# sudo:提权也要第二因子,且与登录策略同源
auth    [success=1 default=ignore] pam_otp.so
auth    sufficient   pam_sm3_challenge.so
auth    requisite    pam_unix.so try_first_pass

这里的关键收益是"策略同源"——sudo 与 sshd、gdm 共用同一份因子定义与失败计数,不会出现"登录要双因子、sudo 却只认口令"的木桶短板。su 同理,建议一并收敛。对于审计而言,sudo 的每次提权也应带上因子类型与结果,便于事后追溯"谁在何时以何种强度拿到了 root"。

此外,运维自动化(如 Ansible、定时脚本)常依赖密钥或口令做非交互提权,强行双因子会打断流水线;应把"服务账号/自动化通道"按来源与账号白名单豁免,而非整体关闭提权保护——这是策略精细度体现,也最易与业务方扯皮。

方案参考

在把国密双因子接进 Linux/国产 OS 登录链路时,可参考以下通用落地建议与选型要点:

  1. 先吃透 PAM 四类栈语义。双因子进 auth、锁屏进 session、失败计数进 account 或 auth 的计数模块,编排顺序直接决定安全性与可用性,建议先用 pamtester 类工具逐栈验证。
  2. 坚持"单机可离线生效"底线。每台终端都应具备独立完整的双因子与锁定能力,中心平台只做"集中管控与策略汇聚",不能成为登录可用性的单点。
  3. 明确因子组合逻辑。是"口令 + 任一第二因子"还是"口令 + 指定第二因子",须写进策略并在 PAM 注释里固化,防止 sufficient/requisite 误用导致口令被绕过。
  4. 失败锁定要分因子计数。口令失败与第二因子失败应区别对待,远程接入收紧、本地在场放宽,并提供管理员手动解锁应急通道。
  5. 图形与远程登录用同一份策略源。gdm、lightdm、sshd 的 PAM 片段应由同一策略生成器产出,避免两类入口强度不一致而被绕过。
  6. 离线应急必须有。预生成一次性应急码、本地缓存的 OTP 种子、国密 Key 的本地挑战应答,三者至少备其二,保证断网不中断、不降安全。
  7. 审计字段要齐全且防篡改。时间戳、终端、用户、因子类型与结果、会话事件都应记录,本地与平台双写,日志至少做到仅追加。
  8. 国产 OS 提前验证国密与签名。SM2/SM3 依赖与内核模块签名在麒麟、统信及老版本 CentOS 上易出问题,应在镜像阶段完成符号依赖与算法可用性验证。
  9. 保留配置版本化与自动回滚。任何 PAM 改动都可能锁死登录,务必保留一个已登录救援会话,并让配置具备"预检 + 失败回退"能力。
  10. 选型时核对因子形态。外接触摸式指纹仪/掌纹仪与指纹 USBKey 是不同类别,前者模板本地、后者兼具存储与签名,选型时勿混为一谈。
  11. 关注等保条款映射。操作系统双因素认证对应身份鉴别项,拔 Key 锁屏对应访问控制与客体保护,全链路审计对应安全审计项,改造时应逐条对照测评要求留存证据,而非仅做技术堆砌。可参考安当SLA 这类以 PAM 模块编排实现双因子登录的产品形态作为对照。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、先理解 PAM 的四类栈
  • 二、SSH 远程接入:最小侵入的改造起点
  • 三、图形桌面登录:gdm 与 lightdm 的差异
    • 3.1 gdm 的会话级因子
    • 3.2 lightdm 的 greeter 钩子
  • 四、会话级因子与"拔 Key 锁屏"
  • 五、失败锁定策略:别把正常回落当攻击
  • 六、统一策略下发:从单机到平台
  • 七、离线双因子:应急 OTP 与预生成码
  • 八、全链路审计:让每次登录可举证
  • 九、落地排障清单
  • 十、国产 OS 适配的特殊性
  • 十一、自己写一个最小 PAM 模块的视角
  • 十二、性能与体验的平衡
  • 十三、特权提权场景:sudo 与 su 也要双因子
  • 方案参考
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档