做安全这么多年,每次做操作系统基线核查或者虚拟化平台风险评估,几乎都会碰到“标识与鉴别机制”这个3.4章节的内容。书面定义说得很简单:标识是用户向系统声明身份,鉴别是系统验证身份。但真正落到生产环境里,从Linux的/etc/passwd到vCenter的SSO,从TPM密钥槽到虚拟机镜像签名,这一小节覆盖的其实是一条完整信任链:只有让操作系统和虚拟化平台在允许任何操作之前,对“你是谁”这件事有确凿把握,后面的权限控制、审计追踪才有意义。
这篇文章我会跳出教材框架,把标识与鉴别拆开来讲,结合操作系统登录流程、虚拟化平台的身份模型、镜像信任、vTPM远程证明,以及我实际排查过的几个翻车场景。既适合准备安全认证考试的人梳理知识点,也适合正在做等保加固或虚拟化平台安全评估的工程师作为实操参考。
1. 标识与鉴别为什么必须分开:“报上名来”和“验明正身”是两回事
很多初学者最容易混淆的就是标识(Identification)和鉴别(Authentication),总以为它们是一件事。实际上在安全设计里,这两个环节必须严格分离,原因很简单:标识是公开的、可以声明的信息;鉴别是私密的、必须验证的信息。攻击者可以轻松获取系统中的标识列表,但如果鉴别机制做得足够好,拿到标识也没用。
1.1 操作系统里的“标识”到底标识了谁
操作系统里的标识对象可不止“人”。我在做权限梳理的时候,习惯把标识分成三类:
- 用户身份:Linux下的用户名和UID,Windows下的用户账户和SID。root的UID永远是0,普通用户通常从1000开始分配,这一类标识解决的问题是“人是谁”。
- 进程身份:每个进程都有PID,同时继承启动者的UID/GID,还有capabilities、SELinux标签这些附加标识。这一类标识解决的其实是“这个进程代表谁在做事”。
- 客体标识:文件、设备、网络连接、IPC通道,每一个客体也有自己的标识属性,用来做访问控制匹配。
虚拟化环境在此基础上又叠了一层。虚拟机有自己的UUID、实例ID、租户ID,镜像有摘要和签名,管理平台有管理员账户、API密钥、服务账号。所以你在虚拟化平台里谈标识,要同时处理两套身份:一套是平台管理员和租户用户的人身份,一套是虚拟机和镜像的非人身份。
1.2 鉴别机制的分类与强度
鉴别就是系统对“标识声明”做验证。鉴别因子分三类,我做了个表格方便对照:
| 因子类型 | 典型示例 | 操作系统中的落地实现 | 虚拟化平台中的落地实现 |
|---|---|---|---|
| 所知(Something you know) | 密码、PIN码、口令短语 | Linux /etc/shadow中的密码哈希验证;Windows密码登录 | vCenter/ESXi本地账户密码、Libvirt SASL账号密码 |
| 所有(Something you have) | 智能卡、U盾、手机令牌、SSH私钥 | PAM的pam_pkcs11模块;Windows智能卡登录 | 平台API证书、硬件安全模块(HSM)、SSH密钥 |
| 所是(Something you are) | 指纹、人脸、虹膜 | Windows Hello、Linux下fprintd指纹模块 | 机房物理门禁联动、堡垒机双因子中的生物识别 |
这里的关键点在于:单因子鉴别已经不足以应对现在的主流威胁。比如密码泄露是常态,光靠强密码策略解决不了撞库问题。因此在等保和各类安全基线里,对关键操作系统和虚拟化管理平台都明确要求双因子鉴别,这是“所有+所知”的组合,比如密码+手机令牌、证书+密码。
1.3 容易被忽略的边界问题
标识与鉴别搞清楚了,还有一个边界需要划清:鉴别不等于授权。标识回答“你是谁”,鉴别验证“你确实是你”,但“你能做什么”是授权(Authorization)的范畴,属于RBAC/ABAC的领域。我在实际评审中经常看到一个错误:管理员把所有通过鉴别的用户都放到超级管理员角色里,认为“能登录就等于可信”,结果普通用户一旦登录就能操作虚拟机迁移,这是典型的鉴别到授权之间的信任断层。
另一个边界问题是多标识映射。同一个工程师,在域里的标识、在虚拟化平台的标识、在云管系统的标识可能完全不同。SSO解决的正是这种单点认证和标识映射问题,但如果映射规则配错,比如把两个同名用户映射到同一个虚拟化平台账户,就会出现越权。这也是为什么虚拟化平台的SSO配置必须做权限复核,不能只追求“免登录”。
2. 从登录框到底层组件:操作系统中的一次完整身份验证链路
很多刚入门的人觉得登录就是一个“输密码-进系统”的简单过程。实际上一次成功的登录背后,是一整套鉴别组件按顺序联动。我在做Linux系统加固时,通常把这条链路作为重点来解释。
2.1 Linux登录流程拆解
以Linux为例,一次本地或SSH登录主要经过以下环节:
- 用户输入用户名,login程序或sshd守护进程接收这个标识声明。
- 进入PAM(可插拔鉴别模块)框架,PAM按配置文件的堆叠顺序调用模块。
- pam_unix.so模块负责查询/etc/passwd获取账户信息,并从/etc/shadow读取密码哈希。
- 系统用相同的哈希算法和盐值处理用户输入的密码,比对结果。
- 比对通过后,PAM继续执行会话模块(pam_loginuid、pam_limits等),初始化环境。
- 最终为用户创建会话并启动初始进程(shell)。
/etc/shadow里的一行记录就是一个典型的鉴别数据存储实例:
root:$6$WVfn3z8U$W1x9D0x0mS8x3Vn6G6O7lQ2G9B8y6Q3sN0jH5vF2dY4cO0lR4bT6kC0wS1uQ1jH8bO2p9LxJ7eZ5a2:19120:0:99999:7:::字段分别表示用户名、哈希值、最后修改日期、最小修改间隔、最大有效期、警告期等。格式里最值得关注的是$6$这个字段,它表示哈希算法是SHA-512,后面跟着的是随机盐值和哈希结果。盐值的作用是防止两个用户密码相同就产生相同哈希,也提高了预计算字典攻击的成本。
SSH登录跟本地登录有区别。sshd默认支持键盘交互和密钥两种方式,其中密钥登录走的是“所有”因子:客户端持有私钥,服务端验证公钥。流程比密码登录更简单,私钥本身不经过网络传输,服务器只发一个挑战,客户端用私钥签名,服务端验证签名。这也是为什么我在加固建议里一直强调:能禁用密码登录就禁用,密钥比密码抗暴力破解能力强得多。
2.2 Windows的本地登录与域登录
Windows的登录链路和Linux差异很大。本地登录由Winlogon进程接收用户输入,交给LSA(本地安全权威)验证。LSA会读取SAM注册表文件中的哈希,计算口令哈希后比对。域环境下则走Kerberos协议:客户端向KDC(密钥分发中心)申请TGT票据,再用TGT申请服务票据,全程票据代替明文密码在网络中传递。
在虚拟化平台的Windows虚拟机里,我实际遇到过一个典型问题:管理员给虚拟机配置了域账户登录,但虚拟化的时间同步服务没搭好,导致虚拟机和域控之间的时钟偏差超过默认容忍值(通常是5分钟),Kerberos鉴别直接失败,用户反复报“登录不上”。这个问题的根因和标识鉴别本身没关系,却直接导致身份验证不可用。排查此类问题时,我会先检查时钟同步,再考虑凭证问题。
2.3 虚拟化控制台的登录鉴别差异
虚拟化平台管理控制台的登录鉴别模型跟操作系统登录相比,多了一层“平台身份”的概念。拿vCenter来说,用户登录后获取的是SSO令牌,后续执行任何操作都会带着令牌去请求授权服务。KVM类的平台则依赖libvirt的安全机制,常见的是SASL认证配合polkit授权。
无论平台怎么实现,有几个原则是通用的:管理通道必须加密、管理账户必须独立于业务账户、超过失败次数必须锁定。我遇到过不止一次因为虚拟机控制台暴露在管理网而且没有做访问来源限制,被人暴力破解出弱口令的情况。这些都属于标识鉴别机制落地不到位。
3. 虚拟化安全里的“第二重身份”:虚拟机标识、镜像信任与租户边界
虚拟化引入了一个在传统单机操作系统里不存在的身份维度:虚拟机自己的身份。一个虚拟机从模板克隆出来、启动、迁移、打快照,每个环节都需要标识与鉴别机制保护,否则攻击者完全可以伪造一个恶意VM,接入管理网络后的影响面会非常大。
3.1 镜像与签名的身份锚点
虚拟机的源头是镜像。如果镜像本身被篡改,后续所有鉴别都是建立在不可信基础上。因此现代虚拟化平台普遍要求对镜像做完整性和来源校验。基础做法是在导入镜像时计算哈希:
sha256sum debian-12-genericcloud-amd64.qcow2 # 输出: 4f38bd01ab69e1b1b8c7e8bb6f1cd3fb1f6c9974d501c8a8dd7839b44d31b6b9然后比对平台或官方发布页提供的摘要值。更进一步的做法是使用数字签名,平台信任某个签名证书,只有带合法签名的镜像才允许导入和部署。这在OpenStack Glance之类的镜像服务里已经非常成熟,镜像元数据可以关联签名证书和签名值,计算节点部署时验证签名。
我在一次私有云评测中确实遇到过“镜像投毒”的事故:某个环境中的模板被植入了后门脚本,从模板创建出来的所有虚拟机都带有自动外连行为。事后追溯发现,模板的哈希值和官方不一致,但当初导入时没人做校验。从那以后,我的验收清单里必然包含“镜像完整性和签名校验”这一项,而且通常在佳能,这不仅是安全加分项,更是标配。
3.2 vTPM与可信启动中的鉴别
物理服务器上的TPM芯片相当于一个硬件信任根,它能存储平台配置寄存器(PCR)度量值,用来记录固件和引导程序的哈希。虚拟化环境下,每个虚拟机需要自己的“虚拟TPM”——vTPM。
vTPM的工作原理是:hypervisor为每个VM模拟一个TPM设备,vTPM的密钥材料由宿主机物理TPM或其他密钥管理机制保护。虚拟机启动时,vTPM对固件、引导加载程序、内核度量,并把结果写入vTPM的PCR。后续审计方可以通过远程证明(Remote Attestation)向vTPM发起挑战,让vTPM返回PCR值并签名,以此验证虚拟机是否运行在可信状态。
这里有个值得注意的边界:vTPM的信任最终仍然锚定在宿主机上。换句话说,如果宿主机本身被攻破,vTPM提供的鉴别证据也不可信。这正是嵌套虚拟化场景下身份鉴别机制最容易被质疑的地方——内层VM的vTPM证据,本质上依赖外层平台的物理密钥,信任没有真正穿透多层。
3.3 嵌套虚拟化与身份伪造风险
在嵌套虚拟化环境(比如KVM里跑KVM,或者VMware工作站里跑ESXi)进行渗透测试时,我观察到一个现象:内层VM看到的硬件信息完全由外层hypervisor模拟。如果外层不可信,它可以伪造任意平台证书、任意PCR度量值,向远程证明方宣称“我是安全的”。
这意味着,在做跨层身份鉴别时,必须明确信任边界。合理的做法是:对于高安全等级的虚拟机,不允许嵌套虚拟化;或者在策略层面禁止嵌套虚拟化功能的启用,比如在VM设置里关闭“向客户机操作系统暴露硬件辅助虚拟化”选项。热词里“该固件的虚拟化支持”“此平台不支持虚拟化的amd-v”这类报错,本质上就是hypervisor在告诉上层:我没有把你的虚拟化指令透传出去。这个限制本身就是一种安全设计。
4. 实战中容易翻车的标识鉴别场景:配置与排查经验
理论讲再多,不如实际踩坑。下面这几个场景都是我在项目或客户现场真实碰到过的,覆盖了从操作系统密码策略到虚拟化平台SSO的典型问题,每个都有完整排查思路。
4.1 场景一:Ubuntu服务器被暴力爆破
接到一个客户反馈,某台Ubuntu服务器CPU使用率异常高,登录查看时发现大量失败认证记录:
sudo grep sshd /var/log/auth.log | tail -50输出里全是类似下面的行:
Failed password for root from 203.0.113.7 port 51234 ssh2 Failed password for ubuntu from 203.0.113.7 port 51235 ssh2这就是典型的针对已知标识(root和ubuntu是Linux默认账户名)做密码爆破。客户还开着root密码登录,等于把第一层标识和鉴别同时送给了攻击者。
我的处理建议分三步:
- 修改sshd配置,禁止root直接登录,
PermitRootLogin no。 - 关闭密码登录,只保留SSH密钥,
PasswordAuthentication no。 - 部署fail2ban,对多次失败来源IP做自动封禁。
这类问题说明一个道理:标识信息在系统安装时就已经公开了,Linux发行版默认用户名、虚拟机模板预设用户名都是公开情报,如果鉴别机制只有一层弱密码,爆破只是时间问题。
4.2 场景二:PAM配置调整导致全员无法登录
还有一次某运维同事想给系统加上登录失败锁定策略,直接编辑了/etc/pam.d/common-auth,加了下面这行:
auth required pam_faillock.so preauth但是他没有在文件顶部放对位置,也没有测试,结果所有用户包括root一旦密码验证不通过,就会被计入失败状态,更严重的是,他把锁定规则配置成包括root,结果自己把密码试错了几次,root被锁,系统直接“谁也登不进去”。
排查方法是在带外管理口或单用户模式下,把PAM配置恢复到备份。根本教训是:任何PAM变更都必须遵守“先备份、先测试、带外可用”三条铁律。PAM堆叠顺序也很重要,pam_unix.so必须放在NSS或SSS之后、账户锁定模块之前,否则账户直接无法解析。
4.3 场景三:虚拟化平台SSO权限映射错误导致的越权
某虚拟化平台接入了企业AD域做SSO,运维图省事,直接创建了一条规则:所有域用户都映射为平台的管理员。结果全体员工都能通过域账号登录虚拟化控制台,可以开关虚拟机、重置管理员密码。这属于典型的“鉴别通了,授权失控”。
正确做法是:
- 平台内创建只读角色、运维角色、管理员角色多个层级,例如vCenter里分别配置只读、资源运维、管理员权限。
- 域组只映射到特定角色,而不是映射到个人或所有用户。
- 定期导出权限列表审查,至少一个季度一次,移除长期不使用的账号。
4.4 场景四:SSH agent转发把标识凭证交到了别人手里
SSH密钥登录相对安全,但我见过一个反面案例:开发人员为了跳板方便,配置了ForwardAgent yes,然后从A机器SSH到B机器,又从B机器SSH到C机器。表面上看,开发者的私钥始终没离开本地,但实际上SSH agent转发的socket文件让B机器上的进程可以代表开发者发起SSH连接。如果B被攻破,攻击者可以直接利用这个socket,用开发者的身份登录C机器,全程不需要密码和私钥。
这里的关键认知是:agent转发传递的是“已经验证过的身份凭证”,相当于把通行证实时借给了中间机器。因此对安全要求高的环境,我建议ForwardAgent no,或者在跳板机上使用代理命令,而不是转发agent。如果确实需要,也必须限定agent转发的目标主机白名单,并且避免在多级跳板中使用。
5. 标识鉴别之后的那些事:权限闭环与审计的可追溯性
标识与鉴别不是终点,而是一条完整信任链的起点。很多系统做到了强密码、双因子登录,但登录之后权限大的吓人,出了问题日志又对不上——这就是把鉴别机制孤立看待的结果。我认为标识鉴别必须和授权、审计放一起看,才能形成闭环。
5.1 从“能登录”到“只能做该做的事”
操作系统层面,sudo权限是常见的越权点。我见过不少系统给普通用户配置了ALL权限的sudo规则,这和把root密码交出去没区别。稳妥的做法是只给具体命令的授权,而不是盲目给ALL:
# 只允许devops组的用户执行维护命令,不允许切换到root %devops ALL=(ALL) /usr/bin/systemctl restart *, /usr/bin/journalctl虚拟化平台层面的角色划分同样如此。vCenter、OpenStack、KVM平台都支持细粒度的角色权限,例如:
| 角色类型 | 可执行操作 | 不可执行操作 |
|---|---|---|
| 只读审计员 | 查看虚拟机列表、事件日志、性能数据 | 启动、关闭、迁移、删除虚拟机 |
| 资源运维员 | 启动、关闭、重启指定资源池内的虚拟机 | 修改全局网络、平台配置 |
| 平台管理员 | 全部操作 | — |
我在加固时会对齐“最小权限”原则:虚拟机删除操作必须单独授权给更高级别的角色;存储卷、网络配置的变更必须走审批流。否则,即便鉴别做得再好,内部误操作也能造成业务中断,这在故障复盘里屡见不鲜。
5.2 日志审计:从鉴别记录反推攻击链路
审计日志是标识鉴别的“证据链”。Linux环境下,我一般重点看/var/log/auth.log,Windows则看安全事件日志。几个关键事件ID非常值得记录:
| 事件ID | 含义 | 分析要点 |
|---|---|---|
| 4624 | 登录成功 | 确认登录类型、来源IP、登录进程 |
| 4625 | 登录失败 | 统计失败次数、锁定策略是否触发 |
| 4648 | 使用显式凭据登录 | 排查计划任务和跳转登录 |
| 4672 | 赋予特殊权限 | 排查管理员组新增变动 |
虚拟化平台方面,vCenter会在事件日志中记录谁在什么时间执行了VM的开关机、快照、迁移等操作,ESXi主机日志也会记录SSH和DCUI登录行为。建议把平台日志统一接入集中日志平台,设置告警规则:非工作时间登录、短时间内大量登录失败、特权账户修改权限等都要产生告警。
我个人的实操习惯是:每次做完标识鉴别模块的整改,都会把“登录来源IP白名单、失败锁定阈值、双因子启用状态、审计日志采集状态”四项内容写进验收报告。原因很简单,标识鉴别机制本身设计得再好,如果无法追溯实际登录行为,那这个机制的实施效果就无从验证。
最后再分享一个小技巧。在做操作系统安全基线核查时,很多工具的自动化扫描结果会直接告诉你“账号锁定阈值未配置”“密码复杂度不符合要求”这一类结果。但真正的高手会进一步追问:“如果攻击者已经获得一个合法标识,比如拿到了用户名,这个环境的鉴别机制能拖住他多久?”带着这个思路去看待标识与鉴别这部分内容,就会发现它的价值远不止考试重点那么简单。