在生产环境里,“打开就完事”几乎从来行不通。从技术上看只有四步:auth、重启、管理员、更新客户端。实际操作时,它几乎总会破坏某个不显眼的东西:夜间 worker、操作员手动脚本,或者半年没人碰过的 BI 仪表盘。
所以不要把它当成一次配置修改,而要当成一个小版本发布:先盘点客户端,再测试,最后切换。这样你会提前看到哪些地方会被拒绝,而不是在事故模式下临时修所有东西。
这份清单面向计划启用身份验证、并希望尽量安全地保护当前系统的用户。请记住,在你配置 auth 之前,身份验证一直处于禁用状态;切换之后,仍然不带凭据的客户端会被拒绝。
阶段 1:在做任何更改之前先盘点
先把每一个与 Manticore Search 通信的客户端——一个应用,或应用中相对独立的一部分——都列出来。这一步要在动配置之前完成。
通常需要检查的内容:
- 应用的搜索前端
- 数据写入 worker
- cron 任务
- 仪表盘和 BI 工具
- 支持或管理工具
- 表结构变更/更新脚本
- 备份和维护脚本
- 手动运行的本地脚本
对每个客户端,大致记录这些信息:
| 客户端 | 协议 | 表或集群 | 所需操作 | 备注 |
|---|---|---|---|---|
| 商品搜索应用 | HTTP | products | read | 将使用 Bearer Token |
| 目录数据写入 worker | SQL | products | write | 使用密码身份验证 |
| 表结构迁移任务 | SQL | products | schema | 仅在部署期间运行 |
| 访问管理员 | SQL | * | admin | 管理用户和权限 |
然后确认部署的基本情况:
- 你运行的是 RT 模式还是 plain 模式?
- 在 plain 模式下,身份验证文件应当放在哪里?
- 配置文件里设置了
pid_file吗?初始化需要它。 - 当凭据跨网络传输时,SQL 客户端会使用 SSL、HTTP 客户端会使用 HTTPS 吗?
- 凭据(包括临时 Bearer Token)将在哪里安全保存?
- 谁有权查看第一个管理员的密码?
不要跳过最后两项。CREATE USER 会返回明文 Bearer Token;TOKEN 会为指定用户生成新 Token。之后用 SHOW TOKEN 查看时,显示的是存储的 Token 哈希,而不是明文。如果明文 Token 丢失,用 TOKEN 轮换它并更新应用中的 Token。
阶段 2:设置最小权限用户
围绕任务来创建用户,而不是靠猜“以后或许用得上”。
使用一个像这样的小矩阵:
| 工作负载 | 用户 | 权限 |
|---|---|---|
| 搜索前端 | app_read | GRANT read ON 'products' TO 'app_read' |
| 数据写入 worker | app_ingest | GRANT write ON 'products' TO 'app_ingest' |
| 表结构迁移任务 | schema_job | GRANT schema ON 'products' TO 'schema_job' |
| 身份验证操作员 | security_admin | GRANT admin ON * TO 'security_admin' |
请记住,admin 是一个范围很窄的权限。它只允许管理身份验证与授权状态,并不意味着同时拥有 read、write、schema 或 replication。
这一点很重要,因为管理凭据的人未必需要读取业务数据。搜索商品的服务不需要写入文档。迁移任务也不需要管理用户。
现在就把拒绝测试一并规划好。对要创建的每个用户,至少挑一件它应该能做的事,和一件它不应该能做的事。
例如:
app_read可以搜索products。app_read不能向products插入数据。app_ingest可以写入products。app_ingest不能管理身份验证。schema_job可以修改products的表结构。schema_job在你授予read之前不能读取表。
阶段 3:在 staging 中测试
使用 staging 环境,提前演练计划在生产环境中执行的操作顺序。
在 RT 模式下:
searchd {
data_dir = /var/lib/manticore
auth = 1
auth_log_level = info
...
}
在 RT 模式下显式关闭身份验证:
searchd {
data_dir = /var/lib/manticore
auth = 0
...
}
在 plain 模式下:
searchd {
auth = /var/lib/manticore/auth.json
auth_log_level = info
...
}
身份验证文件要保持私有。在首次初始化之前,Manticore Search 可能会创建一个空的身份验证文件。初始化之后,该文件会存储身份验证数据和凭据哈希。
启动 searchd,然后初始化第一个管理员:
searchd --config /etc/manticoresearch/manticore.conf --auth
用于脚本化设置:
printf 'admin\nStrongPass#2026\nStrongPass#2026\n' | \
searchd --config /etc/manticoresearch/manticore.conf --auth-non-interactive
⚠️ 警告:这种情况下,密码会以明文形式通过命令行传递,可能进入 shell 历史记录和进程列表。只应在受控环境中使用。
这条命令会创建第一个管理员,并把所有操作授予该用户。它不会返回 Bearer Token。如果该管理员需要 HTTP Bearer 访问,请以管理员身份连接并运行 TOKEN,或使用 HTTP POST /token 端点。
接下来,根据前面阶段的记录创建 staging 用户。例如:
CREATE USER 'app_read' IDENTIFIED BY 'ReadPass#2026';
GRANT read ON 'products' TO 'app_read';
CREATE USER 'app_ingest' IDENTIFIED BY 'IngestPass#2026';
GRANT write ON 'products' TO 'app_ingest';
CREATE USER 'schema_job' IDENTIFIED BY 'SchemaPass#2026';
GRANT schema ON 'products' TO 'schema_job';
CREATE USER 'security_admin' IDENTIFIED BY 'AdminPass#2026';
GRANT admin ON * TO 'security_admin';
把返回的 Bearer Token 保存到安全存储中。请记住:明文 Token 不能留在日志、shell 历史记录或未受保护的文件中。如果需要轮换其中某一个,请使用:
TOKEN 'app_read';
SHOW TOKEN 不能用于找回明文 Token:
SHOW TOKEN FOR 'app_read';
查看用户和权限:
SHOW USERS;
SHOW PERMISSIONS;
SHOW PERMISSIONS FOR 'app_read';
为每个用户运行一次允许测试和一次拒绝测试。对只读用户:
curl -H "Authorization: Bearer *** \
http://127.0.0.1:9308/sql?mode=raw \
-d "SELECT * FROM products LIMIT 10"
然后测试权限不足的情况:
curl -H "Authorization: Bearer *** \
http://127.0.0.1:9308/sql?mode=raw \
-d "INSERT INTO products(id,title) VALUES(1,'test')"
对于这个 HTTP 检查,预期结果是 403 Forbidden。通过 SQL/MySQL 时,权限不足会返回 ERROR 1045,并附带权限被拒绝的报错信息。
SQL 客户端应当用 Manticore Search 的用户名和密码连接。Manticore 的 SQL/MySQL 协议支持 mysql_native_password。
MYSQL_PWD=ReadPass#2026 \
mysql -h127.0.0.1 -P9306 -uapp_read \
-e "SELECT * FROM products LIMIT 10"
HTTP 客户端可以使用 Basic 认证或 Bearer Token:
curl -u app_read:ReadPass#2026 \
http://127.0.0.1:9308/sql?mode=raw \
-d "SELECT * FROM products LIMIT 10"
HTTP 身份验证方案(Basic、Bearer)不区分大小写;用户名区分大小写。
如果你在维护期间绕过守护进程直接编辑了身份验证文件,请重新加载它:
RELOAD AUTH;
阶段 4:生产上线清单
把它当作切换上线时的清单。你甚至可以打印出来逐项打勾。
- 确认你有一份当前的配置备份。
- 确认现有的网络防护仍然到位。
- 确认
pid_file已在配置文件中设置。 - 确认身份验证文件将在哪里创建或从哪里加载。
- 确认密码和 Token 的存放位置已经就绪。
- 在计划好的上线窗口内启用身份验证。
- 启用身份验证后,未带凭据的客户端会失败——这是预期行为。
- 初始化第一个管理员。
- 创建生产环境的用户和权限。
- Token 一经签发,立即保存到受保护的 secrets 存储中。不要把明文 Token 保存在文件、shell 历史记录或日志里。
- 更新 SQL 连接代码,使其发送用户名和密码。
- 更新 HTTP 连接代码,使其使用 Basic 认证或 Bearer Token。
- 把 staging 里的允许和拒绝测试再跑一遍。
- 检查身份验证日志。
- 对应用做一轮压力测试,覆盖搜索、数据写入、仪表盘和维护脚本。
- 轮换上线过程中用过的所有临时凭据。
- 不要把第一个管理员的凭据用于应用的日常访问。
当启用身份验证时,身份验证事件会被写入一个单独的身份验证日志。如果守护进程日志是 /var/log/manticore/searchd.log,那么身份验证日志就是 /var/log/manticore/searchd.log.auth。
auth_log_level 的取值有:
disablederrorwarninginfoalltrace
默认是 info。除非你有理由让日志更少,或者相反,需要更详细,否则就从它开始。trace 只用于诊断;它还会记录所有成功的内部身份验证流量。
有用的清理和维护命令:
SET PASSWORD 'NewReadPass#2026' FOR 'app_read';
REVOKE read ON 'products' FROM 'app_read';
DROP USER 'app_read';
SET PASSWORD 更改用于 SQL/MySQL 和 HTTP Basic 认证的密码。它不会吊销已有的 Bearer Token。若要轮换 Bearer 访问,请用 TOKEN 或 POST /token 创建新的 Token 并更新客户端。
阶段 5:回滚与排查
如果出了问题,回滚应当平淡无奇:
- 恢复之前的配置
- 重启 Manticore
- 恢复身份验证上线之前就存在的旧访问限制
- 如果客户端已经切换到新凭据,也要准备好把应用配置一并回滚。
不要删除上线笔记。要想弄清哪个客户端更新过、哪个 Token 存放在哪里、创建了哪些权限,它们通常是最快的途径。
| 症状 | 可能原因 | 检查 |
|---|---|---|
| SQL 访问被拒绝 | 用户错误、密码错误,或客户端身份验证方式不匹配 | 检查所配置的用户,并确认客户端能够使用 mysql_native_password。 |
| HTTP 401 | 缺少或无效的凭据 | 检查 Authorization 头,以及客户端使用的是 Basic 认证还是 Bearer Token。 |
| HTTP 403 | 用户已通过身份验证但缺少权限 | 检查 SHOW PERMISSIONS FOR '<user>'。 |
| Bearer Token 不再有效 | Token 丢失、复制有误,或已经被吊销 | 运行 TOKEN '<user>',保存返回的 Token,并更新客户端。 |
| 用户能做的比预期少 | 缺少对应操作的授权 | 检查该操作需要的是 read、write、schema、replication 还是 admin。 |
| 用户能做的比预期多 | 目标过宽或缺少显式拒绝 | 检查通配符授权、精确目标授权,以及任何 WITH ALLOW 0 规则。 |
权限规则按操作类型确定。规则冲突时,显式拒绝始终优先于允许,即使允许规则更具体。如果没有匹配的允许规则,访问就会被拒绝。
复制中的身份验证注意事项
如果你使用复制,请规划一次单独的身份验证上线。上面的单节点清单仍然有用,但集群会带来一些容易被忽略的失败模式。
对分布式远程代理的查询以当前会话用户的身份进行身份验证。远程守护进程需要有该用户匹配的身份验证数据,以及对远程目标表的相应权限。
复制相关的操作使用 replication 这个操作。只把它授予应当运行并负责复制操作的用户。
启用身份验证后,加入集群时,本地的身份验证数据可能会被你所加入集群的身份验证数据替换。在加入之前,确保复制用户和身份验证数据在各节点之间保持一致。在集群操作期间,请把 searchd.log.auth 视为敏感数据,因为身份验证备份可能包含盐值和凭据哈希。
请把完整的集群迁移流程放到单独的文档中:这里重要的是指出与集群身份验证相关的风险。
最终检查
在宣布上线完成之前,请确认:
- 使用 Manticore Search 的每个系统独立部分都有自己的用户。
- 每个用户都只有自己需要的操作。
- Bearer Token 保存在受保护的 secrets 存储中;明文 Token 不会保存在受控环境之外。
- 运维团队知道
SHOW TOKEN不会返回明文 Token,而是显示它的哈希;如需获取新 Token,应使用TOKEN或 HTTP 端点。 - SQL 和 HTTP 客户端都已更新。
- 已测试预期的拒绝。
- 身份验证日志可查看。
- 回滚流程清楚且已有文档。
祝你顺利完成身份验证和授权上线!
