拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

服务账号密码治理:从僵尸账号到动态凭据的完整安全改造

服务账号密码治理:从僵尸账号到动态凭据的完整安全改造 “A. Blackslex and Password”——我第一次在运维交接单上看到这行字时就想起了几乎所有安全事故的片头一个没人说得清来历的服务账号一串秘密贴在某个共享文档里的密码。这个标题本身就浓缩了一个非常典型的场景业务系统代号是 Blackslex前缀 A 代表应用归属或账号类型而 password 就是它垂垂老矣的登录凭据。很多团队把这种账号叫作“僵尸账号”或者“历史遗留服务账号”它们的共同点是没人愿意碰、没人说得清依赖关系、但所有人都在偷偷用。这篇内容就来聊一聊面对这样的账号和密码如何从现状梳理、密码加固、权限收口到长期治理做一次完整的安全改造。我平时的发言会更直接一点服务账号加上密码这两个词放在一起往往就是一个组织内部最大的安全隐患之一。很多公司被拖库、被横向移动、被勒索软件打穿第一跳就是这种不起眼的服务账号。这篇文章适合运维、安全、研发以及任何需要在服务器上部署服务的同学参考我会把思路、步骤、计算方式和踩坑点全部展开。1. 这个标题背后先搞清楚“A. Blackslex”到底是谁1.1 拆开服务账号的命名密码专业一点看A. Blackslex 这种命名很像企业内部服务账号的规范格式。“A”是前缀一般表示 Application应用或者 Account账号BlackSlex 是系统或业务模块代号。组合起来就是“给 BlackSlex 业务系统使用的应用账号”。类似的命名还有 SVC_、svc-、MSA_ 等等。为什么需要前缀因为一个企业里账号数量一旦上了几百上千没有命名规约的话根本分不清某个账号是给人用的还是给程序用的归属哪个团队改了密码会不会引发故障。命名规约不只是形式。它是后续权限治理、归属确认、风险定级的基础。我曾经接手过一批账号内部文档里写着 app_web01、db_root、backup光看名字根本判断不了用途。后来做资产盘点时跟着数据流梳理了一个月才把这些账号和业务模块一一对应上。所以如果你今天还没有账号命名规范建议哪怕从下一个新账号开始也先跑起来一个简单的规则比如“用途前缀 系统代号 环境标识”A.Blackslex 这种结构就是完全可以接受的范本。如果账号已经存在但命名混乱怎么办可以分两步走先做映射表把现有账号和系统负责人、依赖关系、权限范围列清楚再逐步把命名规范化。注意不要强行批量改名因为很多配置文件、计划任务、数据库连接串里都写死了账号名贸然改动会直接导致服务起不来。1.2 别小看一个“历史服务账号”为什么它会成为薄弱点一个看起来平平无奇的服务账号能构成多大的风险举一个真实场景BlackSlex 系统是几年前外包团队开发的交付时留下了一个管理账号密码是一串不合规的短口令这个账号同时具备数据库的读写权限和文件服务器的访问权限。后来外包团队撤场账号相关信息只留在一个已离职员工的笔记里。于是这个账号就成了谁都知道、谁都不负责、谁都可以用的状态。这种账号最大的问题不是“存在”而是“没有边界”。它没有明确的负责人、没有权限边界、没有定期轮换机制。攻击者一旦拿到这类账号就等于拿到了一张可以在内网横向移动的通行证。你可以做一个简单测试如果团队里有人能随口说出某个服务账号的密码或者密码能在聊天记录里搜到那么这个账号就应该被当作高风险件来处理。另一个容易被忽视的点是服务账号的安全等级往往低于个人账号。大家对自己个人密码会更敏感但服务账号却被当成“内部专用”而忽视。实际上服务账号常常拥有比普通员工更高的权限使用频率却更低因此它的凭据泄露更容易逃脱监控。这也是为什么“服务账号 老旧密码”的组合如此危险。2. 密码管理的底层逻辑不是“改密码”而是管“身份”2.1 服务账号和普通账号的安全模型差异要管理好服务账号先得想明白它的安全模型和普通账号有什么不同。普通员工账号对应一个真实的人有指纹、有手机、有行为日志这些都可以作为二次校验因素。但服务账号是为程序准备的它没有手机不能眨眼不会验证码通常只能靠“账号 密码”或者“密钥文件”进行认证。这种天然缺陷决定了我们不应该只把服务账号当作“密码的一个用户”来管理而是要把账号、密码、权限、调用者、调用来源放到一起考虑。一个合理的服务账号四要素是谁调用应用身份、从哪调用来源 IP/主机、调用什么接口或资源、何时调用时间窗。如果这四个要素都没有办法说清楚那就不能说这个账号是安全的。在实际设计时可以给服务账号划分等级。比如 A 级账号可用于核心数据库、密钥管理系统、支付模块B 级账号用于普通业务间通信C 级账号用于只读访问或日志采集。不同级别对应不同的密码策略、轮换频率和审批流程。不要一刀切地要求所有服务账号每 90 天轮换一次因为有些夜间批处理任务一旦中途密码失效代价非常高。合理的做法是先定优先级把最核心、最容易被攻击的账号优先治理。我本人倾向于用一个“风险矩阵”来评估服务账号账号权限、访问来源、数据敏感度、密码暴露面、变更影响范围这五个维度分别打 1-5 分乘积超过某一阈值就进入高优先级治理列表。这个方法不需要购买昂贵平台表格工具就能跑起来效果却很明显。2.2 熵值、强度与哈希算法把密码的安全边界算清楚聊密码就绕不开强度。很多人在强调“密码要长、要复杂”但身为从业者更应该追问复杂到什么程度才够这时候要用到“熵”这个概念。密码熵可以简单理解为“预测难度”单位是比特。一个随机小写字母的熵大约是 4.7 比特大小写加数字约 6 比特再加上特殊符号约 6.5 比特。一个 16 位包含大小写、数字、符号的完全随机密码熵值大约在 100 比特以上暴力破解在现实时间尺度上基本不可行。为了便于理解我做一张对照表看看不同密码的实际保护力密码类型示例熵值约破解难度纯数字 8 位1234567827 比特秒级破解小写字母 10 位blackslex47 比特分钟到小时级大小写数字 10 位BlackLex0860 比特天级大小写数字符号 16 位B1ckSlex!2024k3y约 100 比特不可行四词短语加分隔符phone-candle-river-disk约 60-70 比特较难注意熵值只有在“随机生成”的前提下才有意义。BlackLex08 这类密码虽然表面上符合复杂规则但如果你是根据业务名称变体生成的攻击者只需要把字典里加入 Blackslex、BlackLex、Blackslex2024 之类的词熵值就断崖式下降。所以对服务账号密码我强烈建议使用随机生成的密码而不是人肉拟定的“看似复杂”的密码。密码在服务端存储时也要讲科学。现在还有不少系统的数据库里存的是明文密码或者只做了一层 MD5 哈希这是一个非常危险的画面。原因很简单MD5、SHA1 这类算法设计目标是快速计算攻击者可以用 GPU 以每秒数十亿次的速度暴力破解。正确的做法是使用刻意设计为缓慢的密码哈希算法比如 bcrypt、scrypt、Argon2、PBKDF2。这些算法通过增加计算开销让单次尝试变得异常昂贵从而大幅提高破解成本。用一个公式来说明如果攻击者每秒能尝试 100 亿次 MD5破解一个 40 比特熵的密码只需要约 1.4 秒但如果换成合理参数的 Argon2每秒只能尝试几千次同样的密码就需要数万秒才能暴力完成。这个差距就是选择哈希算法的意义所在。另一点每个密码都要配一个随机盐值。相同密码在不同盐值下得到的哈希也不同这样做可以阻止“预计算彩虹表”攻击也可以避免用户之间哈希值相同的问题。2.3 多因素认证与最小权限密码之外还差什么如果只改密码而不调整权限治理工作只能算完成了一半。服务账号原则上应当只拥有完成业务功能所必需的最小权限。比如一个负责读订单数据的服务账号就不应该拥有删除表或管理账号的权限。权限越大密码泄露后的爆炸半径就越大。我在给客户做评估时见过一个读取日志的账号竟然拥有整个集群的管理员权限这种账号的存在等于把数据中心大门的钥匙挂在了公共墙上。多因素认证对服务账号而言一直是个难题。你不能让程序去收短信验证码但可以采取接近 MFA 的方案一是来源 IP 白名单只允许特定主机使用该账号二是证书或密钥文件认证让密码不再是唯一凭据三是定期同步的动态密钥或一次性令牌。比如可以在服务器上部署一个 agent通过访问令牌来获得短期临时凭证这种方案虽然搭建成本较高但安全效果远比长期静态密码好。最小权限和 MFA 可以一起构成纵深防御即使密码被钓鱼或泄露攻击者手里的凭据仍然受来源 IP 限制无法从外部直接使用即使权限被滥用也拿不到高价值目标。做安全治理时不追求一个“点”上的绝对完美而是要把多层防线都建立起来让攻击者每走一步都要付出更高代价。3. 实操复盘给 BlackSlex 账号做一次密码专项治理3.1 摸底盘点把散落在各处的凭证全部找出来治理工作的第一步永远不是改密码而是盘点。如果连这个账号用在哪里都不知道改完密码后第一个重启的应用就会把你拉回现实。我建议按照下面六个步骤来摸底第一梳理系统架构图或应用拓扑图确定 BlackSlex 模块之间的调用关系。第二排查每台服务器的配置文件、环境变量文件、部署脚本、计划任务和 systemd 服务文件。这一点是最繁琐的因为服务密码常常藏在意想不到的位置。第三检查数据库连接池配置、消息队列客户端配置、对象存储访问配置。第四翻查团队的密码管理文档、知识库、共享表格把密码出现过的位置全部标出来。第五和研发、运维开会确认哪些服务当前还在使用这个账号哪些是死账号。第六把所有信息记录成一张凭证清单包含账号名、用途、使用方、来源 IP、权限范围、密码存储位置、最后轮换时间。可以用一条简单命令快速搜索服务器上的明文密码线索比如在 Linux 服务器上搜索常见关键字grep -rn BlackSlex /etc /opt /home /root /data --include*.conf --include*.env --include*.sh --include*.yml --include*.properties 2/dev/nullfind / -name *.config -o -name *.ini 2/dev/null | xargs grep -l password 2/dev/null这里的目的是“定位风险面”并不是让所有人都去抓密码。搜索完成后把结果归类整理哪些地方是明文存储哪些地方虽然加密但密钥就在旁边哪些地方根本没人知道。3.2 密码强度审计与轮换策略盘清底数后接下来就是对密码本身的审计。专业一点的做法是取得哈希值然后使用密码破解工具进行自查。你不要觉得“破解自己系统”很奇怪这其实是最常见的红队手段自己先打一遍总比被攻击者打一遍好。如果拿不到哈希也可以至少判断密码是否属于弱口令。可以把现有密码和通用弱口令字典比对也可以直接用在线 API 进行密码泄露检测。比如查看一个密码是否出现在已知泄露集合中你只需要提交密码的哈希前缀就能得到是否存在的结果不会把完整密码发送给任何第三方。密码熵值也同样重要。你可以写一个简单的脚本统计密码长度和字符集情况但更直接的建议是服务账号密码至少 16 位随机生成不要用人名、项目名、月份这些可预测信息。轮换策略上我建议分优先级实施。对高风险账号先做紧急轮换对一般账号制定一个季度或半年周期。轮换时必须同步更新所有调用方配置否则会出现“账号密码改了但旧密码还被某台机器存着”的情况。常见的做法是把新密码写入配置中心或保险库后分批重启相关服务观察日志里是否出现认证失败。轮换过程中要特别注意依赖顺序。假设 BlackSlex 系统包含 Web 前端、后端 API、调度任务、数据库四层如果后端 API 先使用新密码而数据库连接池还保留旧密码那在切换瞬间就会出现部分请求失败。轮换最好按“数据库最低层到最上层”的顺序推进并在灰度窗口期保留旧密码的短暂有效时间等所有调用方都更新完成后再彻底禁用旧密码。3.3 用密码保险库收口统一存储、自动更新、全程审计把密码从运维人员的脑子里和共享文档里解放出来唯一靠谱的方式是引入密码保险库。密码保险库本质上是一个加密数据库把所有敏感凭据集中存储并提供访问控制和审计日志。常见的工具有开源社区的 Vault、TeamPassword、Bitwarden、KeeWeb 等按自建或 SaaS 分各有取舍。自建方案适合对数据控制力有强需求的团队。在架构上可以部署一组高可用节点后端使用支持事务的数据库。初始化时生成主密钥并采用“分片存储”的方式防止单点泄露。这种方案的好处是可控坏处是需要维护。SaaS 方案的好处是不用操心基础设施但需要评估数据合规和团队接受度。如果有条件建议直接采用“动态凭据”方案来管理数据库类的服务账号。这种方案的大致逻辑是应用不再直接配置数据库密码而是向保险库申请一个短期租约拿到了临时账号密码。这个临时密码在一段时间后自动过期应用需要续租或重新申请。这就把传统意义的“密码管理”升级成了“凭据生命周期管理”。应用侧甚至不需要知道长效密码只需要拥有向保险库请求凭证的权限。如果暂时无法实现动态凭据至少也要做到三件事第一所有服务账号密码统一存入保险库禁止明文存放在代码仓库和服务器文件第二保险库所有读写操作都有审计日志能追踪到“谁在什么时候读取了密码”第三应用启动时从保险库拉取密码而不是在环境变量或配置文件中硬编码。3.4 长期方案从“静态密码”走向“动态凭据”写到这里想特别强调一个理念转变不要把目标设置在“把密码管好”而应该把目标设置在“让密码不再是最重要的防线”。静态密码天然有泄露风险无论你加多少复杂度和轮换频率它都有一个窗口期。动态凭据、双向 TLS、SSH 证书、基于身份的工作负载认证等方式才是服务间认证的长期方向。拿容器化架构来说工作负载可以被分配一个唯一的身份信息然后在访问其他服务时用该身份动态换取短期访问令牌。这种做法彻底改变了凭据形态没有静态密存在服务器上攻击者即使拿到了令牌也很快会发现令牌过期失效。这个过程可以设计成应用在启动时请求令牌使用后缓存一段时间过期后再重新申请。需要说明的是从静态密码切换到动态凭据并不是一朝一夕能完成的改造。它依赖几个前提条件所有应用支持从环境变量或配置接口获取凭据基础设施具备动态下发凭证的能力服务能够优雅处理凭据过期。对历史包袱很重的系统可以先从风险最高的数据库账号入手将 BlackSlex 数据库账号列为第一批试点。改完核心节点其他系统的改造就可以照猫画虎。4. 常见问题与排障实战记录4.1 轮换密码后应用悄悄退出了怎么办这个场景我在各种环境里见过。通常顺序是已创建新密码→更新配置文件→重启应用→应用启动失败或运行一段时间后自动停止。原因非常多但最常见的是旧密码缓存或者连接池没有及时刷新。如果应用持续使用长连接即使配置文件已更新连接池里的数据库连接仍然拿着旧缓存密码切换后连接一旦被服务端断开应用就再也无法重建连接。处理思路是不要重启了事要按层刷新。先把应用与数据库之间依赖连接断开强制连接池重置而不是简单重启应用进程。还有一种情况是配置文件中密码前后有多余空格或者有不可见换行符导致读入的密码不是预期值。这种情况严格来说属于排错基本功但真遇到了也会卡住大半天。保险做法是在修改变量后立刻写一段小脚本打印出来校验避免“肉眼看着对、实际不对”的尴尬。另外一个我在生产环境实际踩过的坑轮换密码后凌晨的计划任务还在使用旧凭据。因为计划任务只在特定时间运行白天改动时并不会触发报错等到半夜任务启动时才炸锅。最近一次轮换密码后我都会提前把计划任务、定时脚本、批处理任务全部列一份清单然后用测试模式跑一遍确认所有调用方都同步到新密码。4.2 明文密码夹在脚本里清理与迁移在盘点过程中最容易发现的就是各种脚本里面写着密码。比如数据库备份脚本里直接写了 root 用户密码监控脚本里直接写了 API Token初始化脚本里把服务账号密码写成了变量默认值。这些问题不能简单“把密码删掉”就完事因为脚本的运行环境往往没有权限访问保险库。我总结了一个相对稳当的迁移顺序第一步先在保险库中注册这个密码并记录它的用途和归属。第二步修改脚本让它从本机受保护文件中读取敏感凭据。第三步把受保护文件的权限设为只对专用运行用户开放。第四步删掉脚本里所有明文密码并在代码仓库扫描历史记录清理掉已经泄露的版本。第五步对密码做一次强制轮换确保旧的明文密码已经失效。之所以要把“代码仓库历史中的密码”也考虑进去是因为很多人只清理了当前文件但提交记录里仍然保留着旧密码。任何一个有权访问仓库历史的人都能翻出来。如果不方便重写整个历史那至少要立即轮换密码。4.3 保险库选型与权限边界团队、设备、故障恢复选择保险库之前先想清楚一个问题谁可以读取哪个密码很多人觉得不就一个团队内部工具嘛给整个研发组开只读权限就行了。但实际上密码保险库的价值恰恰在于权限区分。负责核心数据库的密码应该只让数据库管理员读取前端服务的密码只让后端团队读取。按团队划分权限不是为了制造障碍而是为了减少攻击面和平摊责任。个人经验是在邀请成员加入保险库时遵循“按需申请、定期复核、离职回收”三原则。业务并没有上线时不急着给所有成员开通权限。每季度复核一次成员列表把已经转岗或不再需要访问的账号收回。如果团队人员变动频繁最好接入统一身份便于自动化同步启用和停用。故障恢复也要提前预案。万一保险库主节点挂了运维人员在几小时内无法获取密码怎么办一种做法是将“紧急恢复”的访问分为两段一段由高管或架构师掌握另一段由运维负责人掌握必须两段同时输入才能解密底层备份。这种把信任分散的设计能有效防止一个账号被攻破后直接控制所有凭据。4.4 密码轮换引起系统间相互依赖断裂BlackSlex 这类业务系统一般不是独立存在的。它可能要和报表平台、数据中台、监控告警系统、统一认证平台做对接。这就意味着它的账号密码也可能被下游系统引用。你改密码时如果只通知了 BlackSlex 自己的研发下游链路半夜照样会因为认证失败而报错。面对这种网状依赖必须提前建立“依赖关系清单”。每次口令轮换前把清单发给所有关联方约定切换时间窗口。如果实在无法协调多方可以采取兼容窗口的方式旧密码在短时间内仍然有效让下游系统分批切换。等所有可见依赖都切换完毕再在保险库和系统层面同时删除旧密码。这个操作虽然在严格安全模式下不太优雅但从业务连续性角度看能有效避免一次轮换引发大面积故障。我还建议在轮换完成后保留完整的变更记录包括变更时间、操作人、影响范围、回退方式。这样一旦出现问题可以快速定位是哪一次操作引入了故障而不是凭记忆和猜测去排查。5. 一些踩过坑之后更想说的话说到底“A. Blackslex and Password”并不是一个孤立的坏消息。它其实是一个提示只要还有服务在跑只要还有账号需要登录密码治理就永远不能停。我最深的体会是很多人把安全理解成买工具、上设备、装软件但真正决定安全水平的是你有没有一套完整的清单和流程清楚地知道每个账号是做什么的谁该对它负责密码存在哪里多久换一次哪些系统依赖它。账目清楚比任何高级产品都重要。另外一个小建议可以送给起步阶段的团队不用一上来就追求最复杂的动态凭据体系。先把最基础的四件事做扎实把账号理清楚把密码存进保险库把权限最小化把轮换流程固定下来。这四个动作不做买再贵的防火墙也挡不住内部账号被滥用。这四个动作做好了再慢慢向动态凭据和无密码化演进后面很多事情会顺很多。最后分享一个我在实际处理中百试百灵的方法每次完成服务账号治理后挑一个工作日深夜做一次突击检查。用安全人员的视角重新翻一遍配置、搜一下聊天记录、看一眼是否能从服务器上找到明文密码。如果这一轮还能发现新的遗漏那就说明流程还没闭环。补完这些漏洞之后再回去看看最初那个让人头疼的账号你大概会长出一口气原来真正难搞的从来不是密码本身而是那些藏在黑暗角落里、没人愿意负责的凭据。
返回列表