0. 概述
对于一些隐私数据的 Exporter,有时我只想让 Prometheus 访问而不想暴露出来,一种方式是通过双向 TLS 加密认证来完成,在这篇文章中我将介绍一下我是如何实现这个的。
所谓双向加密,那么就是双方的事情,这里分别有:
- Prometheus 怎样自带证书去拉取 Exporter
- Exporter 如何以 TLS 的形式暴露出来
所以这两个问题就是这一篇文章要解决的问题。因为第一个问题依赖于第二个问题,所以,我第一步肯定要先解决第二个问题,然后才能介绍如何解决第一个问题。
1. Exporter TLS 暴露
因为 Exporter 都是 HTTP(s) 的,所以所谓的 TLS 暴露其实就是如何将 HTTP 转换成 HTTPS,这个已经是一个老生常谈的话题了,所以就无需介绍了。但是,关键在于,在以 HTTPS 暴露的同时,还需要验证客户端,这对于很多 Exporter 来说,不是一个正常的需求,所以一般的 Exporter 都没有实现。
如果我们要抛开 Exporter 来实现,还是有很多方法的,例如我之前介绍过的:Nginx SSL 双向认证,key 生成和配置 就是一个很不错的方式,只需要配置一个 Nginx 配置,然后把证书配置在 Nginx 上,就可以实现简单的无需 Exporter 支持的 Mutal TLS 支持。
这里我就以一个 Node Exporter 为例子,来介绍一下如何配置。
1.1 运行一个 Exporter
这里为了方便,我决定运行 Node Exporter 作为我的示例 Exporter,一个是因为它很通用;另外一个是因为它很重要,很有代表性,所以可能会帮助到真的有需要的人。
但是,这里我为了方便演示,所以直接以 Docker 的形式运行,记得一定要将系统的文件映射进容器哦:
[root@liqiang.io]# cat node-exporter.yaml
version: '3'
services:
nodeexporter:
image: quay.io/prometheus/node-exporter:v0.18.1
container_name: nodeexporter
volumes:
- "/:/host:ro,rslave"
command:
- '--path.rootfs=/host'
- '--web.listen-address=127.0.0.1:8080'
restart: always
pid: host
network_mode: "host"
labels:
org.label-schema.group: "monitoring"
这里为了简便,我是通过 Docker-Compose 的方式将这个运行方式持久化了,如果你对 Docker Compose 不太熟悉,不妨可以看一下我的 Docker Compose 入门系列。
这里直接通过 Docker Compose 启动:
[root@liqiang.io]# docker-compose -f node-exporter.yaml up -d
[root@liqiang.io]# ss -anlp | grep 8080
tcp LISTEN 0 128 127.0.0.1:8080 *:* users:(("node_exporter",pid=192408,fd=3))
然后确认 Exporter 已经运行起来了。
1.2 配置 Nginx
在确保 Exporter 已经运行起来之后,那么就该配置一下 Nginx 了,根据我之前的 Nginx SSL 双向认证,key 生成和配置 的指导,可以简单得这么配置一下:
[root@liqiang.io]# cat nginx.conf
server {
listen 8443 ssl;
server_name _;
ssl on;
ssl_certificate ../ssl/httpd.crt;
ssl_certificate_key ../ssl/httpd.key;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
# 开启客户端认证
ssl_client_certificate ../ssl/cacert.pem;
ssl_verify_client on;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8080/;
}
}
1.3 测试
最后就进入到测试环境了,首先先看下什么都不加能不能访问 Exporter:
[root@liqiang.io]# curl --insecure https://localhost:8443
curl: (58) NSS: client certificate not found (nickname not specified)
OK,访问出错,提示没有客户端认证,这是期望中的,一切正常,下一步就是提供一下客户端证书看看:
[root@liqiang.io]# curl --insecure \
--cacert node_exporter.cert.pem \
--key node_exporter.key.pem \
--cert node_exporter.cert.pem \
https://localhost:8443/metrics | head
# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 3.0278e-05
go_gc_duration_seconds{quantile="0.25"} 9.5253e-05
go_gc_duration_seconds{quantile="0.5"} 0.000127839
go_gc_duration_seconds{quantile="0.75"} 0.000165952
go_gc_duration_seconds{quantile="1"} 0.002635578
go_gc_duration_seconds_sum 6.476344632
go_gc_duration_seconds_count 37170
OK,测试通过,没有问题。
2. Prometheus TLS 认证
Prometheus TLS 认证其实也是一个非常简单的话题,从 Prometheus 的文档中就可以看到,Prometheus 本身就支持 HTTPS 的抓取方式:
图 1:Prometheus 支持 http 和 https |
然后就是 Mutal TLS 双向认证的问题,这个也很简单,再仔细点阅读一下文档的话,也能发现 Prometheus 原生也支持 TLS_Config:
图 2:Prometheus 支持 TLS_Config |
这样就齐全了,那么如果我想抓取在前面第一部分部署的 https 的 Exporter 的话,那么,也只需要这么配置就可以了:
[root@liqiang.io]# cat prometheus.yaml
- job_name: 'local-node-exporter'
scrape_interval: 30s
static_configs:
- targets:
- 'localhost:8443'
scheme: https
tls_config:
ca_file: /node_exporter.cert.pem
cert_file: node_exporter.cert.pem
key_file: node_exporter.key.pem
server_name: node_exporter
然后,打开 Prometheus 的管理页面看一下效果,看下是不是 OK 的:
图 3:Scrape Target 状态 |