2026/10/11 22:16:00

Nacos未授权访问漏洞排查与修复实战:从原理到鉴权加固

Nacos未授权访问漏洞排查与修复实战:从原理到鉴权加固 最近做安全巡检漏洞扫描报告里“Nacos namespaces未授权访问漏洞【原理扫描】”这条几乎成了标配。一开始我还觉得是扫描器误报毕竟我们 Nacos 控制台一直有登录页后来仔细一测才发现问题出在 API 层——控制台加了登录但一堆核心接口在网络上完全是裸奔状态。这篇就把我的排查过程、修复方案和踩过的坑完整记录下来给同样被这条漏洞困扰的朋友一个参考。1. 漏洞到底是什么1.1 namespaces 在这里指的是什么Nacos 是常用的注册中心和配置中心namespaces命名空间是它用来做资源隔离的核心概念。你可以把命名空间理解成一套房子里的不同房间比如 dev、test、prod 各占一间房间里放着各自的配置文件和注册服务列表房间之间互不干扰。未授权访问漏洞触发点就在这里Nacos 对外提供了一组 Open API比如通过 GET 请求访问/nacos/v1/cs/configs、/nacos/v1/ns/service/list这类接口就能读取配置、查询服务列表。如果服务端没开启鉴权这些接口不需要任何凭证就能访问原理扫描器就是检测到了这种“无认证访问受限资源”的行为然后上报为未授权访问漏洞。1.2 漏洞的实际危害很多人觉得“能看配置也没什么大不了”这是大错特错。配置中心里存放的往往不只是普通参数还包括数据库账号口令、Redis 连接串、各种第三方服务的密钥。一旦这些配置被未授权读取等于把核心资产的钥匙直接交了出去。更危险的是Nacos 的 Open API 不止能读还能写。未授权的情况下攻击者可以调用 POST/nacos/v1/cs/configs来新增或修改配置内容如果下游服务开启了配置热更新Nacos 配置一变所有客户端立即拉取到恶意配置轻则业务异常重则被植入恶意逻辑引发供应链攻击。在注册中心层面攻击者还能伪造服务实例把消费者的流量导到自己的恶意节点上实现中间人窃听。1.3 为什么默认配置不安全Nacos 在早期版本里鉴权开关默认是关闭的甚至到了 1.x 和 2.x 的部分版本很多部署文档也没有专门提醒大家开启鉴权。开发人员在搭建的时候只关注了功能是否可用很少有人会在搭建完马上去检查 API 是否裸奔。而且 Nacos 控制台登录用的是独立的一套用户体系和 Open API 的鉴权并不是同一个开关这就导致很多人以为“有登录页就安全了”结果 API 层完全是另一回事。2. 修复前的准备工作2.1 确认 Nacos 版本不同的 Nacos 版本修复配置项有所差异先确认版本再动手。可以在 Nacos 的解压目录下找到/conf/application.properties查看文件头部的注释或者执行启动命令时观察日志。也可以直接看构建包名里的版本号比如nacos-server-2.2.3。我用的是 2.2.3 版本下面以这个版本为例讲解。如果你是 1.x 版本大部分配置项是通用的但部分参数名称有变化需要注意。2.0 以上版本安全性要好一些默认关闭了部分接口的匿名访问但仍然需要主动开启鉴权才算真正安全。2.2 梳理现有调用方开启鉴权是一个破坏性操作所有调用 Nacos API 的程序都必须适配否则会连不上注册中心或无法读取配置。动手前我先梳理了所有依赖 Nacos 的服务Spring Cloud Alibaba 应用通过 Nacos Discovery 注册与发现服务Spring Cloud Config 客户端从 Nacos Config 拉取配置自研的运维脚本直接 curl Nacos API 做批量配置更新这些调用方都需要在代码或脚本中加入用户名密码的认证信息否则开启鉴权后全线报错。2.3 备份关键文件改配置前一定要备份这个道理在 Nacos 上尤其重要因为改错了带来的影响是全局性的。我备份了/conf/application.properties和 Nacos 数据库中的users、roles、permissions几张表。Nacos 的账号信息存在数据库里万一改配置时操作失误可以通过 SQL 恢复。如果 Nacos 使用了外部数据库MySQL备份操作会简单很多直接在数据库上导出相关表即可。如果用的是内嵌 Derby需要先把相关目录完整拷贝一份。3. 完整修复方案3.1 修改 application.properties 配置备份完成、版本确认无误后开始正式修改配置。打开/conf/application.properties找到或新增以下配置项### 开启鉴权 nacos.core.auth.enabledtrue ### 设置身份标识 nacos.core.auth.server.identity.keynacos-server-identity nacos.core.auth.server.identity.valueexample-identity-value ### 设置 Token 密钥 nacos.core.auth.plugin.nacos.token.secret.keySecretKey012345678901234567890123456789012345678901234567890123456789这几项各自的用途需要解释清楚nacos.core.auth.enabled是总开关设为true后所有 Open API 和登录接口都会要求认证信息。这是最核心的一步。nacos.core.auth.server.identity.key和nacos.core.auth.server.identity.value是服务器之间的身份标识用于 Nacos 集群内部节点间通信的时候互相识别。如果不设置集群模式下开启鉴权后节点之间无法正常同步数据。nacos.core.auth.plugin.nacos.token.secret.key是用来做用户登录的 Token 签名的密钥。这里必须设置一个足够复杂的自定义字符串如果留空或使用默认值存在密钥被爆破的风险。注意token.secret.key的长度要求是 Base64 编码后不小于 32 字节。使用示例中的字符串可以但最好自己生成一个随机长字符串可以用openssl rand -base64 64生成。3.2 用 Docker Compose 部署的修改方式如果你用的是 Docker Compose 方式部署 Nacos修改方式是在 docker-compose.yml 中注入环境变量services: nacos: image: nacos/nacos-server:v2.2.3 environment: - NACOS_AUTH_ENABLEtrue - NACOS_AUTH_IDENTITY_KEYnacos-server-identity - NACOS_AUTH_IDENTITY_VALUEexample-identity-value - NACOS_AUTH_TOKENSecretKey012345678901234567890123456789012345678901234567890123456789 ports: - 8848:8848修改完后执行docker-compose up -dDocker 部署时要注意环境变量名和新版本配置项的对应关系。Nacos 的 Docker 镜像对环境变量做了映射NACOS_AUTH_ENABLE对应nacos.core.auth.enabledNACOS_AUTH_TOKEN对应nacos.core.auth.plugin.nacos.token.secret.key。用错变量名会导致配置不生效。3.3 配置集群节点的所有实例单机模式下只需改一台但如果线上环境是 Nacos 集群通常至少 3 个节点必须确保每一个节点的application.properties文件配置完全一致包括token.secret.key和server.identity值。这里有一个很容易被坑的点集群节点之间的 Token 密钥必须一致如果某个节点单独设置了一个不同的密钥跨节点的请求校验会全部失败表现为客户端连上了 A 节点但 B 节点上的服务看不到 A 节点上的实例数据同步异常。3.4 重启 Nacos 服务配置修改完成后关闭并重启 Nacos。单机启动方式cd /usr/local/nacos/bin/ sh shutdown.sh sh startup.sh -m standalone启动完成后查看日志确认鉴权已生效tail -f /usr/local/nacos/logs/start.out日志中会出现类似Nacos started successfully的输出没有报错信息。如果启用了鉴权但没设置token.secret.key启动时日志会明确提示鉴权配置不完整需要补充注意检查。提示重启之前再次确认已经梳理过所有调用方并且准备好了用户名密码。Nacos 默认的数据库里会有nacos这个初始账号初始密码nacos如果之前没有人修改过可以用它登录控制台然后立即修改密码。如果是全新部署建议安装完成后马上执行密码修改。4. 调用方适配与验证4.1 Java/Spring Cloud 应用接入配置开启鉴权后Spring Cloud Alibaba 应用连接 Nacos 需要增加用户名密码参数。在application.properties或bootstrap.properties中添加spring.cloud.nacos.discovery.usernamenacos spring.cloud.nacos.discovery.passwordyour-new-password spring.cloud.nacos.config.usernamenacos spring.cloud.nacos.config.passwordyour-new-password注意两个都配上去一个是服务发现一个是配置中心。如果只配了 discovery 没配 config配置加载依然会报 403。如果用的是 Spring Cloud Alibaba 新版本2021 之后配置文件里会使用spring.cloud.nacos.username这种全局配置同样需要补充。具体写法取决于你所用的依赖版本建议先查看项目里 Nacos 相关依赖的版本再决定配置方式。4.2 命令行/脚本调用方式运维脚本直接通过 curl 调用 Nacos Open API 的需要在请求中增加认证信息。Nacos 支持在 Header 或参数中传入 Token先登录获取 AccessToken# 获取 Token curl -X POST http://nacos-server:8848/nacos/v1/auth/login -d usernamenacospasswordyour-new-password返回结果中拿到accessToken字段然后后续请求都带上# 查询配置带鉴权 curl -X GET http://nacos-server:8848/nacos/v1/cs/configs?dataIdexample.ymlgroupDEFAULT_GROUPtenantdev -H accessToken: YOUR_ACCESS_TOKEN登录接口本身也是受鉴权机制保护的路径在未开启鉴权前可以直接访问开完鉴权后如果账号密码错误登录会直接失败。运维脚本要记得改成动态获取 Token不要写死因为 Token 有过期时间写死的 Token 到点后请求全部 403。4.3 验证未授权访问已修复这是整个修复过程中最有成就感的环节。开启鉴权前我执行curl http://nacos-server:8848/nacos/v1/ns/service/list?pageNo1pageSize10直接返回服务列表数据。开启鉴权后再执行同样的请求返回结果是 403{timestamp:2024-xx-xxTxx:xx:xx.xxx00:00,status:403,error:Forbidden,message:Request does not match allow list,path:/nacos/v1/ns/service/list}再验证控制台登录接口curl -X POST http://nacos-server:8848/nacos/v1/auth/login -d usernamenacospasswordwrong-password返回Access denied说明登录没有绕过鉴权。最后用安全扫描器重新跑一遍原理扫描这时“Nacos namespaces未授权访问漏洞”这个条目就会从结果里消失。我在实际项目上复扫后确认高危漏洞清零。5. 常见问题与排查实录5.1 开启鉴权后应用连不上 Nacos这是最常遇到的问题通常有几个原因导致。现象是应用启动时不断报错日志中出现403或Forbidden。排查思路是先确认应用是否在配置里加了用户名密码如果没有那就先加上再重启。如果加了依然报错检查密码是否和 Nacos 控制台一致。也就是我在 4.1 里强调过的如果同时使用了 config 和 discovery两处都要配置漏配一处就会出问题。5.2 开启了鉴权但扫描器仍然报漏洞这种情况通常是因为回归验证时用的是未开启鉴权的旧接口路径或者开启了鉴权但旧的端口服务没重启又或者虽然配置了enabledtrue但因为配置格式错误实际没生效。排查时先确认配置文件中确实有nacos.core.auth.enabledtrue再通过 curl 无条件访问一个 API 看返回状态码。如果返回 200 而配置文件确实也改了多半是应用没重启干净检查进程确认没有多个 Nacos 实例共存。5.3 集群模式下节点间数据不同步开启鉴权后集群节点间通信如果不能正确认证会出现服务列表不完整。这个问题的典型原因是nacos.core.auth.server.identity.key/value各节点配置不一致或者 Token 密钥不一致。排查方法是在各节点上执行相同的 curl 请求比对节点间的返回值差异同时逐行检查配置文件的 identity 配置。这个问题在初次集群部署时碰到得最多配置统一后问题即消失。5.4 用户修改密码报错Nacos 控制台修改密码时经常出现request error, please try again later!的报错。出现这个报错原因是 Nacos 内置的密码加密机制和数据库中的旧记录不匹配或者当前登录 Token 失效后页面还在用旧 Token 发请求。我实际操作中发现最稳妥的做法是使用超级管理员账号登录然后通过数据库 SQL 直接更新用户密码字段再用新密码登录一次验证通过后在控制台再改一次密码。不要在前端页面卡住一直重试越试越乱。6. 后续加固与维护6.1 定期轮换 Token 密钥Token 密钥是鉴权体系的最后防线建议定期轮换比如每 90 天换一次。步骤是先改一个节点的配置然后滚动重启再改下一个节点确保任意时刻各节点 Token 一致避免大范围重启导致服务中断。6.2 对 Nacos 做访问控制即使开了鉴权从网络安全纵深防御的角度来说Nacos 端口也不应该对全公司网段开放。建议通过防火墙或安全组只允许应用服务器网段访问 8848 端口控制台另设限制比如仅允许运维跳板机访问。6.3 关注 Nacos 官方的安全公告Nacos 项目一直在补齐安全能力新版本会修复旧版本的安全问题也会调整鉴权配置项的行为。我建议是每季度关注一次 Nacos Release Notes及时升级到修复版本而不是停留在最初的部署版本上。7. 从原理扫描到真正理解的总结安全扫描器报出的每一条“原理扫描”漏洞其实都对应着一个具体的攻击路径。Nacos namespaces 未授权访问这条表层原因是鉴权开关没开本质上是在部署注册中心、配置中心这类基础设施时没有从全局审视“谁能访问什么”也没有把安全配置当成上线标准的一部分。我在这次修复里学到的最重要的一点是先梳理调用方再动配置最后做回归。顺序不能乱。如果一开始就改配置调用方没有适配线上直接炸。如果改完不回归验证自己都不知道漏网在哪里。按照上面的步骤操作下来的同学基本都能把这条漏洞从扫描报告里清掉。只要把鉴权配置和调用方适配放在一起考虑就不会有意外。以后部署 Nacos 新环境时建议直接把鉴权配置写到初始化脚本里从第一步就杜绝未授权访问的可能。