⚠️ 此页面为自动翻译,翻译可能不完美。
blog-post

如何用内置的认证与授权保护 Manticore Search

搜索常常被当作基础设施来对待。但在生产环境里,它更像一个应用 API:接收用户流量、暴露业务数据、支撑仪表盘,而且常常紧挨着那些不该对网络上所有客户端开放的记录。

27.1.5 版本起,Manticore Search 现在已为通过 MySQL 协议的 SQL、HTTP/HTTPS 端点以及与复制相关的操作内置了认证和授权。

认证回答“是谁在调用”,授权回答“这个用户能做什么”。

已经在使用 Manticore 的用户可以在保持熟悉工作流不变的情况下使用这些新功能。现有的 SQL 和 HTTP 客户端仍然保留原有的连接方式。应用程序只需要做很少的改动。

Manticore 新增的内容

  • 使用 mysql_native_password 的 SQL/MySQL 密码认证。
  • 使用相同用户名和密码的 HTTP Basic 认证。
  • HTTP Bearer token,适合不希望每次请求都发送密码的客户端。
  • 五种清晰的权限:readwriteschemareplicationadmin
  • 目标对象,例如 productslogs_*posts*
  • 用于管理用户、token 和权限的 SQL 命令。
  • 认证日志,级别包括 disablederrorwarninginfoalltrace,默认是 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,不需要 writeschemareplicationadmin

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 访问权限,请使用 TOKENPOST /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 权限只管理认证和授权状态。它们并不意味着拥有 readwriteschemareplication 权限。如果同一个用户确实需要这些权限,请分别授予。

通过 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 USERTOKENPOST /token 命令返回的 bearer 令牌:

curl -H "Authorization: Bearer <app_read_token>" \
  http://127.0.0.1:9308/sql?mode=raw \
  -d "SELECT * FROM products LIMIT 10"

BasicBearer 认证方案不区分大小写。用户名区分大小写。

两种方式的权限校验相同:客户端完成认证后,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 不能满足 readwriteschemareplication
  • 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 部署,应将认证作为分阶段上线来处理,而不是一次性全部切换:

  1. 梳理所有连接到 Manticore 的 SQL 和 HTTP 客户端。
  2. 选择认证文件路径:RT 模式下放在 data_dir 下的 auth.json,plain 模式下使用显式路径。
  3. 先在 staging 环境启用认证。
  4. 创建第一位管理员。
  5. 为搜索、写入、表结构变更、复制和认证管理分别创建最小权限用户。
  6. 更新应用的 SQL 连接代码,以发送用户名和密码。
  7. 更新 HTTP/HTTPS 连接代码,改用 Basic 认证或 Bearer 令牌。
  8. 对每个应用用户分别验证预期的成功与预期的拒绝。
  9. 配置合适的认证日志级别,并确保该日志与其他运维日志一起被安全存储。
  10. 逐步发布,在切换后轮换凭据,以获得额外的安全性,并再做一次测试和培训。

分布式表还需要多做一项检查。Remote-agent 查询以当前会话用户身份进行认证,因此远程守护进程上需要有该用户的匹配认证数据,该用户也要具备远程目标表的相应权限。

复制集群使用 replication 操作。启用认证后,集群加入可能会用来自捐赠集群的认证数据替换本地认证数据,因此在加入之前要确保各节点之间的认证材料保持一致。在处理集群时,要谨慎对待认证日志(默认是 searchd.log.auth 文件),因为其中可能包含盐值和凭据哈希。

完整参考

该手册页覆盖了新功能的完整命令集和运维细节,包括密码策略、认证日志级别、SHOW USERSSHOW PERMISSIONSRELOAD AUTH、分布式远程代理以及复制集群:

认证与授权手册

但对大多数应用来说,路径很直接:启用认证,初始化管理员,创建最小权限用户,更新客户端,并验证正确的请求被允许,而错误的请求被拒绝。

安装Manticore Search

在 Linux 或 macOS 上用一条命令安装 Manticore Search:

curl https://manticoresearch.com | sh

有关高级安装选项,请参阅完整安装指南手册

安装Manticore Search