搜索常常被当作基础设施来对待。但在生产环境里,它更像一个应用 API:接收用户流量、暴露业务数据、支撑仪表盘,而且常常紧挨着那些不该对网络上所有客户端开放的记录。
自 27.1.5 版本起,Manticore Search 现在已为通过 MySQL 协议的 SQL、HTTP/HTTPS 端点以及与复制相关的操作内置了认证和授权。
认证回答“是谁在调用”,授权回答“这个用户能做什么”。
已经在使用 Manticore 的用户可以在保持熟悉工作流不变的情况下使用这些新功能。现有的 SQL 和 HTTP 客户端仍然保留原有的连接方式。应用程序只需要做很少的改动。
Manticore 新增的内容
- 使用
mysql_native_password的 SQL/MySQL 密码认证。 - 使用相同用户名和密码的 HTTP Basic 认证。
- HTTP Bearer token,适合不希望每次请求都发送密码的客户端。
- 五种清晰的权限:
read、write、schema、replication和admin。 - 目标对象,例如
products、logs_*、posts和*。 - 用于管理用户、token 和权限的 SQL 命令。
- 认证日志,级别包括
disabled、error、warning、info、all和trace,默认是info。
这个访问模型有意设计得很小。你只需创建用户,授予他们所需的操作权限,更新应用以发送凭据,并测试被拒绝的操作确实会被拒绝。
启用认证
认证由 searchd 段中的 auth 设置控制。
在 RT 模式
中,使用 auth = 1。Manticore 会将认证数据存储在 data_dir 下的 auth.json 中。
searchd {
data_dir = /var/lib/manticore
auth = 1
auth_log_level = info
}
要在 RT 模式下显式关闭认证,使用 auth = 0 或移除该设置。
在 plain 模式下,把 auth 设为认证文件的路径:
searchd {
auth = /var/lib/manticore/auth.json
auth_log_level = info
}
当密码或 bearer token 需要跨网络传输时,SQL 连接请使用 SSL,HTTP 客户端请使用 HTTPS。
认证文件要保管好,不要让无关人员读取。在首次引导之前,Manticore 可能会创建一个空的认证文件;引导完成后,该文件会存放认证数据和凭据哈希。
创建第一位管理员
启用 auth 之后,启动 searchd,再用同一个配置文件创建第一位管理员:
searchd --config /etc/manticoresearch/manticore.conf --auth
自动化场景下,使用非交互式引导模式:
printf 'admin\nStrongPass#2026\nStrongPass#2026\n' | \
searchd --config /etc/manticoresearch/manticore.conf --auth-non-interactive
引导需要一个正在运行的守护进程。它会创建第一个管理员并授予该用户所有操作权限。
引导过程不会返回 bearer token。如果管理员用户需要 HTTP Bearer 访问权限,请以该管理员身份连接后执行 TOKEN,或者调用 HTTP 的 POST /token 端点。
创建用户
初始化管理员后,你可以用这个账号通过 SQL 命令管理用户和权限。不过,不要在应用程序中使用它。相反,应为特定任务创建独立用户。
例如,一个只从 products 读取数据的搜索前端只需要 read,不需要 write、schema、replication 或 admin:
CREATE USER 'app_read' IDENTIFIED BY 'ReadPass#2026';
GRANT read ON 'products' TO 'app_read';
CREATE USER 会为新用户返回一个原始 bearer token。请立即妥善保存,Manticore 之后不会再显示原始 token。
之后需要创建或轮换 bearer token 时:
TOKEN 'app_read';
TOKEN 'app_read' 会返回一个可直接使用的新的原始令牌。SHOW TOKEN 显示的是已存储的令牌哈希,而不是要在 HTTP 请求中发送的令牌。这对验证和审计很有用:你可以在不暴露原始密钥的情况下,确认令牌是否存在,或在轮换后是否发生了变化:
SHOW TOKEN FOR 'app_read';
SET PASSWORD 会更改用于 SQL/MySQL 和 HTTP Basic 认证的密码:
SET PASSWORD 'NewReadPass#2026' FOR 'app_read';
它不会撤销现有的 bearer 令牌。要轮换 Bearer 访问权限,请使用 TOKEN 或 POST /token 创建新令牌:
TOKEN 'app_read';
数据写入管道可以只获得 write,而不需要其他权限:
CREATE USER 'app_ingest' IDENTIFIED BY 'IngestPass#2026';
GRANT write ON 'products' TO 'app_ingest';
表结构迁移任务可以获取 schema:
CREATE USER 'schema_job' IDENTIFIED BY 'SchemaPass#2026';
GRANT schema ON 'products' TO 'schema_job';
认证管理员可以获得 admin 权限:
CREATE USER 'security_admin' IDENTIFIED BY 'AdminPass#2026';
GRANT admin ON * TO 'security_admin';
admin 权限只管理认证和授权状态。它们并不意味着拥有 read、write、schema 或 replication 权限。如果同一个用户确实需要这些权限,请分别授予。
通过 SQL 与 HTTP 连接
mysql 客户端使用 Manticore 用户名和密码进行认证:
MYSQL_PWD=ReadPass#2026 \
mysql -h127.0.0.1 -P9306 -uapp_read \
-e "SELECT * FROM products LIMIT 10"
HTTP/HTTPS 客户端可以使用 Basic 认证:
curl -u app_read:ReadPass#2026 \
http://127.0.0.1:9308/sql?mode=raw \
-d "SELECT * FROM products LIMIT 10"
它们也可以使用 CREATE USER、TOKEN 或 POST /token 命令返回的 bearer 令牌:
curl -H "Authorization: Bearer <app_read_token>" \
http://127.0.0.1:9308/sql?mode=raw \
-d "SELECT * FROM products LIMIT 10"
Basic 和 Bearer 认证方案不区分大小写。用户名区分大小写。
两种方式的权限校验相同:客户端完成认证后,Manticore 识别出用户,再把请求的操作与该用户的权限进行比对。
启用认证后进行测试
提示:在为 Manticore 启用访问控制时,不要只验证启用认证后客户端能够连接。还要测试被拒绝的访问,以及你的应用对此的响应。
app_read 用户应该能从 products 读取:
curl -H "Authorization: Bearer <app_read_token>" \
http://127.0.0.1:9308/sql?mode=raw \
-d "SELECT * FROM products LIMIT 10"
同一个用户应该不能向 products 写入:
curl -H "Authorization: Bearer <app_read_token>" \
http://127.0.0.1:9308/sql?mode=raw \
-d "INSERT INTO products(id,title) VALUES(1,'test')"
该错误是预期行为。通过 HTTP,具有有效用户但没有权限的请求会得到 403 Forbidden。通过 SQL/MySQL,Manticore 会返回带有权限拒绝信息的 ERROR 1045。
Manticore 如何判断允许与拒绝
Manticore 的权限是“操作 + 目标”形式的规则。如果没有任何规则允许在请求的目标上执行请求的操作,访问就会被拒绝。
简而言之:
- 规则只针对所请求的操作进行匹配。
admin不能满足read、write、schema或replication。 WITH ALLOW 0创建一条显式拒绝规则。- 任何匹配的显式拒绝都会胜出,即使存在更具体的允许规则。
- 如果没有匹配的允许规则,访问被拒绝。
举个例子:
CREATE USER 'analyst' IDENTIFIED BY 'AnalystPass#2026';
GRANT read ON * TO 'analyst';
GRANT read ON 'private_logs' TO 'analyst' WITH ALLOW 0;
analyst 用户可以读其他表,但不能读 private_logs。
带通配符的拒绝无法与精确允许一起作为例外模式使用。只要拒绝匹配了请求,它就仍然优先生效。
在现有部署中逐步启用访问控制
对于已有的 Manticore 部署,应将认证作为分阶段上线来处理,而不是一次性全部切换:
- 梳理所有连接到 Manticore 的 SQL 和 HTTP 客户端。
- 选择认证文件路径:RT 模式下放在
data_dir下的auth.json,plain 模式下使用显式路径。 - 先在 staging 环境启用认证。
- 创建第一位管理员。
- 为搜索、写入、表结构变更、复制和认证管理分别创建最小权限用户。
- 更新应用的 SQL 连接代码,以发送用户名和密码。
- 更新 HTTP/HTTPS 连接代码,改用 Basic 认证或 Bearer 令牌。
- 对每个应用用户分别验证预期的成功与预期的拒绝。
- 配置合适的认证日志级别,并确保该日志与其他运维日志一起被安全存储。
- 逐步发布,在切换后轮换凭据,以获得额外的安全性,并再做一次测试和培训。
分布式表还需要多做一项检查。Remote-agent 查询以当前会话用户身份进行认证,因此远程守护进程上需要有该用户的匹配认证数据,该用户也要具备远程目标表的相应权限。
复制集群使用 replication 操作。启用认证后,集群加入可能会用来自捐赠集群的认证数据替换本地认证数据,因此在加入之前要确保各节点之间的认证材料保持一致。在处理集群时,要谨慎对待认证日志(默认是 searchd.log.auth 文件),因为其中可能包含盐值和凭据哈希。
完整参考
该手册页覆盖了新功能的完整命令集和运维细节,包括密码策略、认证日志级别、SHOW USERS、SHOW PERMISSIONS、RELOAD AUTH、分布式远程代理以及复制集群:
但对大多数应用来说,路径很直接:启用认证,初始化管理员,创建最小权限用户,更新客户端,并验证正确的请求被允许,而错误的请求被拒绝。
