安全指南
分类:
pg_exporter 位于两个信任域之间:它先向 PostgreSQL 或 pgBouncer 认证,再通过 HTTP 暴露指标与管理端点。两侧必须独立加固;数据库 TLS 不会保护 HTTP 监听端口,HTTP Basic Auth 也不会降低数据库权限。
威胁面
| 表面 | 敏感能力 | 主要控制 |
|---|---|---|
| PostgreSQL 连接 | 读取监控视图并执行采集器 SQL | 专用登录角色、pg_monitor、pg_hba.conf、TLS |
| 目标 URL | 包含主机、用户,通常还包含密码 | .pgpass、密钥文件、文件权限、密钥管理系统 |
/metrics |
暴露拓扑、对象名、负载与容量 | 私网、防火墙、TLS/认证 |
/explain 与 /stat |
暴露采集器定义、准入、耗时与错误 | 限制或认证 HTTP 访问 |
/reload |
触发配置解析与查询计划原子替换 | 限制或认证 HTTP 访问 |
| 采集器 SQL | 消耗数据库资源,并可能通过 Label 暴露信息 | 查询审查、最小权限、超时、TTL、基数审查 |
使用专用数据库角色
PostgreSQL 10+ 内置的 pg_monitor 角色覆盖默认采集器所需的只读权限:
CREATE ROLE monitor
WITH LOGIN
PASSWORD 'replace-this-secret'
CONNECTION LIMIT 5;
GRANT pg_monitor TO monitor;
不要为了省去权限审查而让 exporter 使用超级用户。可选自定义采集器可能需要访问自己的视图、函数或 Schema,请按对象单独授权。
监控 pgBouncer 时,需要使用本地策略允许的 stats_users 或 admin_users 账户连接管理数据库。此模式下 exporter 使用管理端 SHOW 接口,而不是 PostgreSQL 系统目录。
不要把密码放进进程参数
目标 URL 的取值优先级如下:
--url/-uPG_EXPORTER_URLPGURLPG_EXPORTER_URL_FILE指向的文件postgresql:///?sslmode=disable
命令参数可能出现在进程列表中,建议使用以下方式之一。
.pgpass
db.example.com:5432:*:monitor:replace-this-secret
chmod 600 ~/.pgpass
export PG_EXPORTER_URL='postgres://[email protected]:5432/postgres?sslmode=verify-full'
RPM/DEB 服务以 prometheus 用户运行。自 v1.4.0 起该用户 HOME 为 /var/lib/prometheus,但软件包不会创建目录:
sudo install -d -o prometheus -g prometheus -m 0750 /var/lib/prometheus
sudo install -o prometheus -g prometheus -m 0600 ./pgpass /var/lib/prometheus/.pgpass
密钥文件
PG_EXPORTER_URL_FILE 适合 systemd credential、Docker/Kubernetes Secret 挂载以及其他文件型密钥交付:
export PG_EXPORTER_URL_FILE=/run/secrets/pg_exporter_url
pg_exporter --config=/etc/pg_exporter.yml
文件应包含一个 URL,可以带首尾空白。显式配置的文件不存在或不可读时,进程会致命退出。日志会遮盖 URL 用户信息与 password= 查询参数中的密码,但日志脱敏不能替代源密钥保护。
保护数据库连接
未提供 sslmode 时,pg_exporter 会为常见的同机部署主动添加 sslmode=disable。这在不可信网络上并不安全;远程目标应显式选择 libpq TLS 策略:
export PG_EXPORTER_URL='postgres://[email protected]:5432/postgres?sslmode=verify-full&sslrootcert=/etc/pg_exporter/ca.crt'
尽可能使用 verify-full,同时验证证书链与主机名。require 会加密流量,但不能提供同等的服务器身份保证。
官方 Docker 镜像基于 scratch,没有系统 CA 包。请将所需 CA 文件挂载进容器,并在 sslrootcert 中引用精确路径。
缩小 HTTP 暴露面
如果 Prometheus 与 exporter 在同一台主机上,只监听回环地址:
pg_exporter --web.listen-address=127.0.0.1:9630
需要远程抓取时,只允许监控网段通过防火墙或服务网格访问。监听端口同时包含管理端点,并不存在独立的管理端口。
TLS 与 Basic Auth
--web.config.file 使用 Prometheus exporter-toolkit 格式,并在每个 HTTP 请求时重新读取。最小示例:
tls_server_config:
cert_file: /etc/pg_exporter/web.crt
key_file: /etc/pg_exporter/web.key
min_version: TLS12
basic_auth_users:
prometheus: "$2y$10$replace_with_a_bcrypt_hash"
pg_exporter --web.config.file=/etc/pg_exporter/web.yml
请生成 bcrypt 哈希,不要把明文密码写进文件,例如使用 htpasswd -nBC 10 prometheus。mTLS、响应头与限流配置以 exporter-toolkit Web 配置为准。
启用 Basic Auth 后,Prometheus 抓取任务也要配置认证:
scrape_configs:
- job_name: postgresql
scheme: https
basic_auth:
username: prometheus
password_file: /etc/prometheus/secrets/pg_exporter_password
tls_config:
ca_file: /etc/prometheus/ca/pg_exporter-ca.crt
static_configs:
- targets: ['db.example.com:9630']
保护配置文件
发布软件包以较严格的权限将 /etc/pg_exporter.yml 与 /etc/default/pg_exporter 交给 prometheus 用户。复制或模板化文件时应保留相同的所有权与权限。数据库密码不应放在采集器 YAML 中;该文件用于查询和指标元数据,不是连接密钥。
部署前还要审查自定义 Label。数据库名、客户标识、租户名与 SQL 指纹都可能成为 Prometheus 标签,并继续流向远端存储、告警与仪表盘。
生产检查清单
- 使用有小连接上限的专用非超级用户数据库账户
- 配置明确的
pg_hba.conf规则与网络来源限制 - 使用
.pgpass或密钥文件,不在命令参数中放密码 - 远程数据库连接使用
sslmode=verify-full与可信 CA - 9630 端口只监听回环/私网,或受防火墙限制
- HTTP 跨越信任边界时启用 TLS/认证
- 将管理端点视为敏感接口
- 审查自定义 SQL 的权限、超时、TTL 与标签基数
- 验证密钥/证书轮换不会在日志或进程列表泄露值