尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Prometheus安全加固实战:Nginx反向代理与内置认证配置详解

Prometheus安全加固实战:Nginx反向代理与内置认证配置详解 1. 项目概述为什么我们需要给Prometheus“上锁”在监控领域Prometheus 以其强大的数据抓取能力和灵活的查询语言PromQL成为了事实上的标准。但很多朋友在初次部署时往往会忽略一个关键环节安全。默认情况下Prometheus 的 Web UI 和 API 是直接暴露的没有任何访问控制。想象一下你的服务器性能指标、业务运行状态甚至是一些包含敏感信息的标签比如数据库连接串、内部服务地址就这么“裸奔”在网络上任何人只要知道 IP 和端口就能一览无余。这无异于把自家大门的钥匙插在锁上。我见过不止一个团队在内部测试环境部署了 Prometheus因为觉得是内网就跳过了认证结果某次端口意外暴露到公网差点酿成数据泄露的风险。所以给 Prometheus 加上“锁”——也就是加密配置和登录认证绝不是可有可无的“高级功能”而是生产环境部署的必备步骤。这不仅仅是防止未授权访问更是满足各类安全审计和合规性要求的基础。本次分享我将结合自己多次在生产环境落地的经验详细拆解两种主流的 Prometheus 安全加固方式基于 Web 服务器如 Nginx/Apache的反向代理认证以及 Prometheus 自身集成的 Web 配置文件和基础认证。我会把配置的每一步、背后的原理以及我踩过的那些“坑”都摊开来讲清楚。无论你是运维工程师、SRE还是正在搭建自己监控体系的开发者这篇内容都能帮你构建一个既安全又可靠的 Prometheus 监控栈。2. 安全加固的两种核心路径解析在开始动手之前我们得先理清思路。Prometheus 本身在设计上遵循“只做一件事并做好”的 Unix 哲学其核心是抓取和存储时间序列数据因此原生不提供复杂的用户认证和授权系统。要实现安全访问我们需要借助外部组件或其有限的内置功能。主流方案可以归结为以下两条路径它们各有优劣适用场景也不同。2.1 路径一反向代理网关模式这是目前生产环境中最主流、最推荐的方式。其核心思想是不直接暴露 Prometheus 服务而是在其前面部署一个成熟的 Web 服务器如 Nginx、Apache、Caddy或 API 网关如 Traefik、Envoy作为反向代理和认证网关。工作原理用户或客户端如 Grafana的所有请求首先到达反向代理服务器。代理服务器负责完成 TLS/SSL 加密HTTPS、用户认证如 Basic Auth、OAuth2、LDAP等所有安全相关的工作。认证通过后代理服务器将请求转发给后端的 Prometheus 服务通常监听在 localhost 或内部网络。Prometheus 本身无需任何修改它只接收来自可信代理的“干净”请求。为什么这是首选方案功能强大且成熟Nginx 等 Web 服务器经过多年实战检验其 TLS 实现、认证模块非常稳定和全面。你可以轻松集成多种认证方式这是 Prometheus 自身无法比拟的。职责分离安全认证、加密与业务监控数据抓取、查询解耦。Prometheus 可以专注于其核心任务安全策略的变更和升级不影响监控服务本身。统一入口在实际架构中你很可能不止有 Prometheus 需要保护还有 Alertmanager、Grafana 等其他组件。使用同一个反向代理作为统一的安全网关可以简化证书管理和认证策略配置。灵活性高你可以轻松添加 IP 白名单、限流、访问日志审计等更多安全层。2.2 路径二Prometheus 内置 Web 配置文件认证从 Prometheus 2.24 版本开始引入了通过web.config.yml文件配置 TLS 和基础认证Basic Authentication的支持。这种方式将安全配置直接内嵌到 Prometheus 进程中。工作原理你需要准备一个web.config.yml配置文件其中定义了 TLS 证书路径和 HTTP 基础认证的用户密码哈希。在启动 Prometheus 时通过--web.config.file参数指定该配置文件。Prometheus 的 Web 服务器将直接使用该配置提供 HTTPS 服务和基础认证。它的适用场景与局限优点部署简单无需引入额外组件适合小型环境或快速原型验证。所有配置集中在一个 Prometheus 实例上。缺点功能单一仅支持静态配置的基础认证无法集成 OAuth、LDAP 等复杂认证系统。管理不便用户密码以哈希形式写在配置文件中添加或修改用户需要更新配置文件并重启 Prometheus。耦合性高安全与业务耦合证书轮换等操作需要重启服务。版本依赖需要较新版本的 Prometheus2.24。我的经验选择对于任何严肃的生产环境我毫无保留地推荐路径一反向代理模式。它更符合现代云原生架构的理念扩展性和可维护性要好得多。路径二可以作为一个轻量级的备选方案或者在开发测试环境中临时使用。接下来我将以最常用的 Nginx 作为反向代理为例展开详细配置。3. 实战基于 Nginx 反向代理的完整配置流程我们将搭建一个标准的架构用户 - HTTPS (Nginx with Basic Auth) - HTTP (Prometheus)。目标是让 Prometheus 在http://localhost:9090安全地运行而外部通过https://your-domain.com/prometheus来访问。3.1 环境准备与组件安装首先确保你的服务器上已经安装了 Prometheus。如果还没安装可以通过以下步骤快速完成以 Linux 为例# 下载最新版本的 Prometheus (请从官网替换为最新版本号) wget https://github.com/prometheus/prometheus/releases/download/v2.45.0/prometheus-2.45.0.linux-amd64.tar.gz # 解压 tar xvf prometheus-*.tar.gz cd prometheus-* # 将可执行文件移动到系统路径 sudo cp prometheus promtool /usr/local/bin/ # 创建配置和数据目录 sudo mkdir -p /etc/prometheus /var/lib/prometheus sudo cp prometheus.yml /etc/prometheus/接下来安装 Nginx。大多数 Linux 发行版都可以通过包管理器安装# Ubuntu/Debian sudo apt update sudo apt install nginx apache2-utils -y # CentOS/RHEL sudo yum install nginx httpd-tools -y这里我们同时安装了apache2-utils或httpd-tools因为它包含了htpasswd工具用于生成基础认证的密码文件。3.2 生成密码文件与配置基础认证安全的第一步是创建授权用户。我们将用户名和密码哈希存储在一个文件中。# 创建密码文件首次添加用户使用 -c 参数后续添加不要用 -c否则会覆盖 sudo htpasswd -c /etc/nginx/.htpasswd prometheus_admin执行命令后会提示你输入并确认密码。prometheus_admin是你指定的用户名。请务必将生成的/etc/nginx/.htpasswd文件权限设置为仅 root 可读以保护密码哈希。sudo chmod 600 /etc/nginx/.htpasswd3.3 获取与配置 SSL/TLS 证书没有 HTTPS 的认证是“纸糊的墙”因为密码在网络上明文传输。我们必须启用 HTTPS。对于生产环境你应该使用来自 Let‘s Encrypt免费或其他商业 CA 签发的可信证书。使用 Certbot 可以自动化这个过程# 安装 Certbot (以 Nginx on Ubuntu 为例) sudo apt install certbot python3-certbot-nginx -y # 获取并自动配置证书your-domain.com 替换为你的域名 sudo certbot --nginx -d your-domain.comCertbot 会自动修改你的 Nginx 配置启用 HTTPS。对于测试或内部环境你可以使用自签名证书。虽然浏览器会警告但用于内部服务或配合 Grafana可配置跳过证书验证是可行的。# 生成自签名证书 (有效期365天) sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /etc/ssl/private/nginx-selfsigned.key \ -out /etc/ssl/certs/nginx-selfsigned.crt你需要填写一些证书信息其中Common Name最好填写你的服务器 IP 或域名。3.4 编写核心的 Nginx 服务器配置这是最关键的一步。我们将在/etc/nginx/sites-available/prometheus创建一个新的服务器块配置。假设你的域名是monitor.yourcompany.com。server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name monitor.yourcompany.com; # 你的域名 # SSL 证书路径 (使用 Certbot 的路径通常如下自签名证书需调整) ssl_certificate /etc/letsencrypt/live/monitor.yourcompany.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/monitor.yourcompany.com/privkey.pem; # 启用 SSL 会话复用提升性能 ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # 安全地转发到 Prometheus location /prometheus/ { # 1. 启用基础认证 auth_basic Prometheus Server Authentication; auth_basic_user_file /etc/nginx/.htpasswd; # 2. 反向代理到本地的 Prometheus proxy_pass http://localhost:9090/; # 注意结尾的斜杠它很重要 # 3. 传递必要的头部信息 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 4. 设置 WebSocket 支持 (Grafana Live 特性可能需要) proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; # 5. 适当调大超时时间应对大量查询 proxy_read_timeout 300; proxy_connect_timeout 300; } # 可选重定向 HTTP 到 HTTPS # server { # listen 80; # server_name monitor.yourcompany.com; # return 301 https://$server_name$request_uri; # } }配置要点解析auth_basic和auth_basic_user_file指令启用了基础认证并指定了密码文件。proxy_pass将匹配/prometheus/路径的请求转发给本地 9090 端口的 Prometheus。结尾的斜杠/至关重要它会将/prometheus/api/v1/query这样的请求正确地重写为http://localhost:9090/api/v1/query。如果没有这个斜杠路径会错乱这是最常见的配置错误之一。proxy_set_header系列指令确保了原始请求的客户端信息如真实 IP能传递给 Prometheus这对于日志记录和审计很有帮助。WebSocket 头部的设置是为了兼容 Grafana 的“实时预览”等高级功能。超时时间的调整是因为 Prometheus 的查询尤其是范围查询可能耗时较长需要避免代理层过早断开连接。3.5 启用配置并启动服务创建符号链接启用站点配置并测试 Nginx 配置语法。sudo ln -s /etc/nginx/sites-available/prometheus /etc/nginx/sites-enabled/ sudo nginx -t # 测试配置必须看到 “syntax is ok” 和 “test is successful”如果测试成功重启 Nginx 使配置生效。sudo systemctl restart nginx现在确保你的 Prometheus 服务正在运行默认监听localhost:9090。然后你就可以通过浏览器访问https://monitor.yourcompany.com/prometheus会弹出一个登录框输入之前设置的prometheus_admin和密码即可访问。4. 另一种选择配置 Prometheus 内置的 Web 认证如果你坚持使用内置方案以下是具体步骤。再次强调这更适合轻量级、非核心的场景。4.1 创建 Web 配置文件在 Prometheus 配置目录如/etc/prometheus下创建web-config.ymltls_server_config: cert_file: /etc/prometheus/ssl/prometheus.crt key_file: /etc/prometheus/ssl/prometheus.key basic_auth_users: prometheus_admin: $2y$12$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxtls_server_config指定你的 TLS 证书和私钥路径。证书生成方式同上。basic_auth_users定义用户名和密码的 bcrypt 哈希。密码不是明文4.2 生成密码哈希使用htpasswd或其他工具生成 bcrypt 哈希。这里用openssl# 生成 bcrypt 哈希 (rounds 是成本因子默认12越高越安全但也越慢) openssl passwd -6 -stdin输入你的密码后会输出一个以$2b$或$2y$开头的哈希字符串将其复制到web-config.yml中。4.3 修改 Prometheus 启动命令你需要修改 systemd 服务文件通常是/etc/systemd/system/prometheus.service或直接修改启动命令添加--web.config.file参数ExecStart/usr/local/bin/prometheus \ --config.file/etc/prometheus/prometheus.yml \ --storage.tsdb.path/var/lib/prometheus/ \ --web.console.templates/etc/prometheus/consoles \ --web.console.libraries/etc/prometheus/console_libraries \ --web.config.file/etc/prometheus/web-config.yml \ # 新增这行 --web.listen-address0.0.0.0:9090重启 Prometheus 服务后它将在 9090 端口提供 HTTPS 服务并需要基础认证。5. 关键踩坑点与疑难问题排查实录理论配置看起来简单但实操中陷阱不少。下面是我总结的几个典型“坑”及其解决方案。5.1 路径代理的“斜杠”陷阱这是 Nginxproxy_pass指令最经典的坑。错误配置location /prometheus { proxy_pass http://localhost:9090; }现象访问https://domain/prometheus可能正常但访问https://domain/prometheus/api/v1/targets时Nginx 会将请求转发给http://localhost:9090/api/v1/targets丢失了/prometheus前缀。这会导致 Prometheus 返回 404因为它的 API 根路径是/而不是/prometheus。正确配置方案A推荐在location和proxy_pass的 URL 后都加上斜杠。location /prometheus/ { proxy_pass http://localhost:9090/; }。这样 Nginx 会将/prometheus/前缀从请求路径中剥离后再转发。方案B使用rewrite指令重写路径。location /prometheus { rewrite ^/prometheus/(.*) /$1 break; proxy_pass http://localhost:9090; }。5.2 Grafana 数据源配置认证当 Prometheus 开启基础认证后Grafana 数据源必须配置对应的凭据。在 Grafana 中进入Configuration - Data Sources - Prometheus。在HTTP部分URL填写完整的代理地址如https://monitor.yourcompany.com/prometheus。Auth开启Basic Auth。User和Password填写你在.htpasswd中设置的用户名和密码。点击Save Test。如果成功会显示 “Data source is working”。常见问题证书错误如果使用自签名证书Grafana 会报 SSL 错误。需要在数据源配置的TLS/SSL Auth部分开启Skip TLS Verify仅限测试环境。生产环境请务必使用可信证书。路径错误确保 Grafana 中配置的 URL 包含了 Nginx 中设置的路径前缀如/prometheus。5.3 Prometheus 抓取配置scrape_configs的认证如果你的 Prometheus 需要从同样需要认证的 exporter如 Node Exporter with HTTPS抓取数据需要在prometheus.yml的scrape_configs中配置认证。scrape_configs: - job_name: node basic_auth: username: exporter_user password: your_secure_password tls_config: insecure_skip_verify: true # 谨慎使用仅用于测试或内部自签名证书 static_configs: - targets: [node-exporter-host:9100]这里配置的是Prometheus客户端去访问exporter服务端时使用的认证与前面讲的保护 Prometheus 自身服务端的认证是两回事不要混淆。5.4 性能与超时问题当配置了反向代理和认证后链路过长可能引入性能开销和超时风险。问题在 Grafana 中加载一个跨度较大的仪表盘时可能遇到 “504 Gateway Time-out” 错误。排查检查 Nginx 错误日志sudo tail -f /var/log/nginx/error.log。通常能看到upstream timed out相关记录。解决在 Nginx 的location块中增加超时设置如前面配置示例中的proxy_read_timeout 300;。这个值需要根据你的查询复杂度和数据量进行调整。同时也可以考虑优化 PromQL 查询避免全时间范围扫描。5.5 系统服务与权限问题SELinux/AppArmor在开启了强制安全模块的系统上Nginx 可能被禁止访问密码文件.htpasswd或代理到本地端口。可以通过审计日志排查或临时设置为宽容模式测试。防火墙确保 Nginx 的 443 端口对外部开放同时确保 Prometheus 的 9090 端口仅对本地127.0.0.1或内部网络开放不要暴露到公网。6. 进阶考量与最佳实践建议完成基础配置只是第一步要让这套安全体系更健壮还需要考虑以下几点。6.1 认证方式的升级从 Basic Auth 到 OAuth2基础认证简单但不够安全密码每次请求都传输也不便于管理多服务需重复配置。在生产环境中更推荐使用 OAuth2 代理如oauth2-proxy或直接使用支持 OAuth2 的入口网关如ingress-nginx的注解配置。其工作流程变为用户访问 - 网关重定向到身份提供商如 Google, GitHub, 企业内部 SSO登录 - 登录成功后携带令牌访问 - 网关验证令牌并转发请求给 Prometheus。这种方式用户体验更好也更安全。6.2 细粒度授权RBAC基础认证或简单的 OAuth2 只解决了“你是谁”的问题没有解决“你能做什么”。Prometheus 本身不支持基于角色的访问控制RBAC。如果你需要限制不同用户只能查看特定的监控数据例如开发团队只能看应用指标运维团队才能看主机和数据库指标目前需要借助更外层的方案使用 Grafana 的数据源权限在 Grafana 中可以为不同团队创建不同的数据源每个数据源连接到一个经过过滤的 Prometheus 查询代理如promxy或自建代理服务该代理根据用户身份对 PromQL 查询进行改写或过滤。专门的监控门户开发一个轻量级前端集成认证后端调用 Prometheus API 时根据用户角色注入不同的标签过滤条件。6.3 配置管理与自动化当你有成百上千个监控目标时手动管理认证凭据是不现实的。密码/密钥管理使用诸如 HashiCorp Vault、AWS Secrets Manager 等工具动态管理密码和 TLS 证书并通过 sidecar 或 init container 注入到 Nginx 或 Prometheus 的容器中。配置即代码将 Nginx 配置、Prometheus 的web-config.yml纳入 Git 版本控制结合 CI/CD 流水线进行自动化部署和检查。在 Kubernetes 中的实践在 K8s 中部署时通常使用 Ingress 资源来配置反向代理和 TLS。认证可以通过 Ingress Annotations 集成oauth2-proxy或使用 Service Mesh如 Istio的授权策略来实现管理起来更加云原生。安全是一个持续的过程而不是一次性的配置。给 Prometheus 加上认证和加密是构建可靠监控体系的坚实第一步。从简单的 Nginx 反向代理开始随着业务复杂度的提升再逐步演进到更完善的统一认证授权体系这是一个稳妥且实用的路径。
返回列表