4、启用 Basic Auth:使用 bcrypt 生成密码哈希、配置 web.yml 文件、重启 Prometheus 使配置生效

Basic Auth 是 Prometheus 2.24+ 版本内置的最轻量级认证方案。它通过 HTTP 请求头中的 Authorization: Basic <base64> 传递用户名与密码,服务端使用 bcrypt 哈希进行比对。本节将完整演示从密码生成、配置文件编写到服务重启的全流程。

4.1 整体流程概览

下图展示了启用 Basic Auth 的完整操作链路:

Prometheus Basic Auth 启用流程 Basic Auth 启用流程 ① 安装 htpasswd ② 生成 bcrypt 哈希 ③ 编写 web.yml ④ 验证配置语法 ⑤ 重启 Prometheus ⑥ 验证访问 提示:bcrypt 哈希是单向加密,Prometheus 不会存储明文密码,仅比对哈希值。

4.2 使用 bcrypt 生成密码哈希

Prometheus 要求密码哈希必须使用 bcrypt 算法。推荐使用 htpasswd 工具(Apache 发行版)或 Python 的 bcrypt 库生成。

4.2.1 方法一:使用 htpasswd(推荐)

安装 htpasswd:

# CentOS / RHEL
sudo yum install -y httpd-tools

# Ubuntu / Debian
sudo apt-get install -y apache2-utils

# macOS(已预装)
# 无需额外安装

生成 bcrypt 哈希密码:

# -B 强制使用 bcrypt 算法,-c 创建新文件
htpasswd -nB admin

# 输出示例:
# admin:$2y$05$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# 如果只需要哈希值(不含用户名),使用 -b 参数:
htpasswd -nbB admin YourStrongPassword! | cut -d: -f2
参数说明:
  • -B:强制使用 bcrypt 加密算法(Prometheus 唯一支持的算法)
  • -n:输出到标准输出,不写入文件
  • -b:从命令行直接提供密码(非交互式)
  • -c:创建新文件(首次使用)

4.2.2 方法二:使用 Python bcrypt 库

适用于自动化脚本或 CI/CD 场景:

# 安装 bcrypt 库
pip install bcrypt

# 生成哈希
python3 -c "
import bcrypt
password = b'YourStrongPassword!'
salt = bcrypt.gensalt(rounds=10)
hashed = bcrypt.hashpw(password, salt)
print(hashed.decode())
"

4.2.3 方法三:使用 openssl(不推荐)

注意:Prometheus 仅支持 $2y$ 或 $2b$ 前缀的 bcrypt 哈希。openssl passwd 默认生成的是 MD5 或 SHA-512 哈希,不可用于 Prometheus。请勿使用此方法。

4.3 配置 web.yml 文件

在 Prometheus 配置目录(通常为 /etc/prometheus)下创建 web.yml 文件:

# /etc/prometheus/web.yml
basic_auth_users:
  admin: $2y$05$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  readonly: $2y$05$yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy

配置文件结构说明:

字段 类型 说明 是否必填
basic_auth_users map[string]string 用户名到 bcrypt 哈希的映射 是
tls_server_config object TLS 证书配置(可选,建议与 Basic Auth 配合使用) 否
http_server_config object HTTP 服务器参数(如最大连接数、超时等) 否
安全最佳实践:
  • 为不同用户分配不同权限:admin 用于管理,readonly 用于查询
  • 设置 web.yml 文件权限为 600:chmod 600 /etc/prometheus/web.yml
  • 文件属主应为 prometheus 用户:chown prometheus:prometheus /etc/prometheus/web.yml
  • 建议同时启用 TLS 加密传输,避免密码在网络上明文传输

4.4 验证配置语法

在重启之前,使用 promtool 验证 web.yml 语法:

# 检查 web.yml 语法
promtool check web-config /etc/prometheus/web.yml

# 成功输出示例:
# web/config OK
常见错误:
  • yaml: unmarshal errors:YAML 格式错误,检查缩进和冒号后的空格
  • invalid bcrypt hash:哈希值不是有效的 bcrypt 格式,检查是否以 $2y$ 或 $2b$ 开头
  • file not found:web.yml 路径错误或文件不存在

4.5 重启 Prometheus 服务

根据部署方式选择重启命令:

# systemd 管理(推荐)
sudo systemctl restart prometheus
sudo systemctl status prometheus

# 直接启动(开发环境)
kill -HUP $(pgrep prometheus)   # 优雅重载配置
# 或
pkill prometheus && prometheus --config.file=/etc/prometheus/prometheus.yml --web.config.file=/etc/prometheus/web.yml
重要:使用 kill -HUP 重载配置时,Prometheus 会重新读取 web.yml,但不会中断现有连接。如果修改了用户或密码,建议使用 systemctl restart 确保所有连接都使用新配置。

4.6 验证 Basic Auth 生效

重启后,使用 curl 测试认证是否生效:

# 不带认证信息(应返回 401)
curl -v http://localhost:9090/metrics 2>&1 | grep "HTTP/"
# 输出:HTTP/1.1 401 Unauthorized

# 带正确认证信息(应返回 200)
curl -u admin:YourStrongPassword! http://localhost:9090/metrics -o /dev/null -w "%{http_code}"
# 输出:200

# 带错误密码(应返回 401)
curl -u admin:wrongpassword http://localhost:9090/metrics -o /dev/null -w "%{http_code}"
# 输出:401

4.7 多用户配置示例

实际生产环境中通常需要多个用户:

# /etc/prometheus/web.yml
basic_auth_users:
  # 管理员:拥有全部权限
  admin: $2y$05$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  # 只读用户:仅能查询指标
  readonly: $2y$05$yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
  # 监控系统:用于 Prometheus 之间的联邦采集
  federate: $2y$05$zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

用户权限对照表:

用户名 用途 推荐权限 密码策略
admin 运维管理 全部 API 访问 强密码 + 定期轮换
readonly Grafana 数据源 查询、读取指标 可适当简化,但需满足复杂度
federate 联邦集群 仅 /federate 端点 建议使用 API 替代

4.8 常见问题排查

问题现象 可能原因 解决方案
重启后仍可无密码访问 Prometheus 版本低于 2.24 升级 Prometheus 至 2.24+
密码正确但返回 401 哈希算法不是 bcrypt 使用 htpasswd -B 重新生成
web.yml 语法检查通过但重启失败 文件权限不足 检查 chmod 600 和 chown prometheus
curl 测试返回 403 Forbidden IP 白名单或防火墙限制 检查 --web.listen-address 和 iptables
生产环境检查清单:
  1. ✅ 使用 htpasswd -nB 生成 bcrypt 哈希
  2. ✅ web.yml 文件权限设置为 600
  3. ✅ 使用 promtool check web-config 验证语法
  4. ✅ 重启后使用 curl 验证 401/200 响应
  5. ✅ 检查 Prometheus 日志无认证相关错误
  6. ✅ 确认 Grafana 数据源配置了正确的用户名密码