Skip to content

🧭 Nacos 登录异常和异常管理员账号清理

这次遇到的问题是:开发环境 Nacos 原来的账号密码突然登录不上,页面提示“用户名或密码错误”,接口返回 user not found!。一开始很容易以为只是密码被人改了,但实际排查下来,问题更接近一次暴露服务被扫描后的异常账号写入。

这篇记录只保留排查和修复方法,不记录真实公网 IP、真实密码、token、数据库密码等敏感信息。

现象

Nacos 控制台登录失败:

text
用户名或密码错误

用登录接口测试时,返回:

text
HTTP/1.1 403
user not found!

开发环境里 Nacos 是 Docker 容器运行,鉴权已开启:

bash
docker ps | grep nacos
ps -ef | grep '[n]acos'

可以看到类似参数:

text
-Dnacos.standalone=true
-Dnacos.core.auth.enabled=true

先确认 Nacos 用的是哪个用户库

先进入服务器看 Nacos 容器的环境变量和配置。

bash
docker exec nacos sh -lc 'env | sort | grep -Ei "MYSQL|NACOS_AUTH|NACOS_CORE"'
docker exec nacos sh -lc 'grep -nE "db\\.|nacos.core.auth" /home/nacos/conf/application.properties'

这次确认 Nacos 使用的是同机 MySQL 容器里的 nacos_config 库,用户表是:

text
nacos_config.users
nacos_config.roles
nacos_config.permissions

检查用户和角色:

sql
SELECT username, enabled FROM users ORDER BY username;
SELECT username, role FROM roles ORDER BY username, role;

结果发现除了正常的 nacos,还有多个异常账号,并且有异常账号拥有 ROLE_ADMIN

备份鉴权表

修复前先备份 Nacos 鉴权相关表。

bash
mkdir -p /root/nacos_auth_backup_$(date +%Y%m%d_%H%M%S)

mysqldump nacos_config users roles permissions > nacos_auth_tables.sql

如果 MySQL 跑在 Docker 里,就用容器执行:

bash
docker exec mysql sh -lc 'mysqldump -uroot -p"$MYSQL_ROOT_PASSWORD" nacos_config users roles permissions' > nacos_auth_tables.sql

删除异常账号并还原 nacos 用户

这次保留 nacos 账号,删除异常账号和角色。

sql
START TRANSACTION;

UPDATE users
SET enabled = 1
WHERE username = 'nacos';

DELETE FROM permissions
WHERE role IN (
  SELECT role
  FROM roles
  WHERE username IN (
    'hack',
    'hacker_admin',
    'nv_276a8851',
    'nv_54860ba0',
    'nv_6eb77951',
    'nv_7fbdae4f',
    'special'
  )
);

DELETE FROM roles
WHERE username IN (
  'hack',
  'hacker_admin',
  'nv_276a8851',
  'nv_54860ba0',
  'nv_6eb77951',
  'nv_7fbdae4f',
  'special'
);

DELETE FROM users
WHERE username IN (
  'hack',
  'hacker_admin',
  'nv_276a8851',
  'nv_54860ba0',
  'nv_6eb77951',
  'nv_7fbdae4f',
  'special'
);

COMMIT;

修复后应该只剩:

text
nacos  1
nacos  ROLE_ADMIN

BCrypt 的坑

这里踩了一个坑:不能随便用系统工具生成 BCrypt hash 后直接写进 users.password

第一次用了 htpasswd -B 生成 BCrypt,表面上格式也是 $2a$,长度也是 60,但 Nacos 登录仍然返回:

text
user not found!

打开 MySQL general log 临时抓一次登录请求,确认 Nacos 确实在查用户表:

sql
SELECT username,password FROM users WHERE username='nacos';

所以问题不是“查不到用户表”,而是密码 hash 没有被 Nacos 正确校验。最终用 Nacos 容器里自带的 spring-security-crypto 生成 BCrypt hash,再写回 users.password 后登录恢复。

生成方式示例:

java
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

public class NacosHash {
  public static void main(String[] args) {
    System.out.print(new BCryptPasswordEncoder().encode(System.getenv("NACOS_RESTORE_PASS")));
  }
}

从 Nacos jar 里取对应依赖:

bash
jar xf /home/nacos/target/nacos-server.jar \
  BOOT-INF/lib/spring-security-crypto-5.7.10.jar \
  BOOT-INF/lib/spring-jcl-5.3.29.jar

再编译运行,把生成的 hash 写回:

sql
UPDATE users
SET password = '<Spring Security 生成的 BCrypt hash>',
    enabled = 1
WHERE username = 'nacos';

验证

用登录接口验证:

bash
curl -i -X POST 'http://<nacos-host>:8848/nacos/v1/auth/users/login' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'username=nacos' \
  --data-urlencode 'password=<password>'

成功时会返回:

json
{
  "accessToken": "...",
  "tokenTtl": 18000,
  "globalAdmin": true,
  "username": "nacos"
}

再用 token 读取一个配置,确认权限正常:

bash
curl 'http://<nacos-host>:8848/nacos/v1/cs/configs?dataId=xxx.yaml&group=DEFAULT_GROUP&tenant=xxx&accessToken=xxx'

入侵痕迹

MySQL general log 里看到过来自内网地址的 root 连接,查询内容里出现反连 shell 相关字符串,随后又执行了关闭 general log 的操作。

这说明问题不只是 Nacos 密码错误,而是服务器暴露面已经被扫描或尝试利用。

当时还检查了:

bash
crontab -l
grep -RInE 'bash -i|/dev/tcp|curl|wget' /etc/crontab /etc/cron.d /var/spool/cron 2>/dev/null
ss -antp | grep -E ':8848|:3306'

没有发现 cron 里已经落地反连任务,但 MySQL 和 Nacos 端口仍然公网监听,这个风险必须处理。

加固清单

这类问题修完登录只是第一步,后面更重要的是收口暴露面。

必须做:

  • Nacos 8848 不要直接公网开放,只允许 VPN、内网或固定办公 IP。
  • MySQL 3306 不要直接公网开放,只允许应用服务器或堡垒机访问。
  • 轮换 Nacos 登录密码。
  • 轮换 Nacos auth token。
  • 轮换 MySQL root 密码。
  • 删除所有异常 Nacos 账号和角色。
  • 检查 usersrolespermissions 是否又被写入异常数据。
  • 打开必要的访问日志,但不要长期开启 MySQL general log。

可以定期检查:

sql
SELECT username, enabled FROM nacos_config.users ORDER BY username;
SELECT username, role FROM nacos_config.roles ORDER BY username, role;

总结

Nacos 登录提示 user not found! 不一定是真的没有用户,也可能是密码 hash 校验失败后的泛化提示。遇到这类问题时,不要只在控制台反复试密码,应该先确认 Nacos 实际连接的数据库,再检查 usersrolespermissions

这次的关键经验有三个:

  1. 修复前先备份鉴权表。
  2. Nacos 密码 hash 用它自身依赖的 Spring Security BCrypt 生成,不要随便混用工具。
  3. 发现异常管理员账号后,要把问题当安全事件处理,重点收口 88483306

技术笔记