0. 概述

对于一些隐私数据的 Exporter,有时我只想让 Prometheus 访问而不想暴露出来,一种方式是通过双向 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 的形式运行,记得一定要将系统的文件映射进容器哦:

  1. [root@liqiang.io]# cat node-exporter.yaml
  2. version: '3'
  3. services:
  4. nodeexporter:
  5. image: quay.io/prometheus/node-exporter:v0.18.1
  6. container_name: nodeexporter
  7. volumes:
  8. - "/:/host:ro,rslave"
  9. command:
  10. - '--path.rootfs=/host'
  11. - '--web.listen-address=127.0.0.1:8080'
  12. restart: always
  13. pid: host
  14. network_mode: "host"
  15. labels:
  16. org.label-schema.group: "monitoring"

这里为了简便,我是通过 Docker-Compose 的方式将这个运行方式持久化了,如果你对 Docker Compose 不太熟悉,不妨可以看一下我的 Docker Compose 入门系列。

这里直接通过 Docker Compose 启动:

  1. [root@liqiang.io]# docker-compose -f node-exporter.yaml up -d
  2. [root@liqiang.io]# ss -anlp | grep 8080
  3. 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 生成和配置 的指导,可以简单得这么配置一下:

  1. [root@liqiang.io]# cat nginx.conf
  2. server {
  3. listen 8443 ssl;
  4. server_name _;
  5. ssl on;
  6. ssl_certificate ../ssl/httpd.crt;
  7. ssl_certificate_key ../ssl/httpd.key;
  8. ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
  9. ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
  10. ssl_prefer_server_ciphers on;
  11. # 开启客户端认证
  12. ssl_client_certificate ../ssl/cacert.pem;
  13. ssl_verify_client on;
  14. location / {
  15. proxy_set_header Host $http_host;
  16. proxy_set_header X-Real-IP $remote_addr;
  17. proxy_set_header X-Scheme $scheme;
  18. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  19. proxy_pass http://localhost:8080/;
  20. }
  21. }

1.3 测试

最后就进入到测试环境了,首先先看下什么都不加能不能访问 Exporter:

  1. [root@liqiang.io]# curl --insecure https://localhost:8443
  2. curl: (58) NSS: client certificate not found (nickname not specified)

OK,访问出错,提示没有客户端认证,这是期望中的,一切正常,下一步就是提供一下客户端证书看看:

  1. [root@liqiang.io]# curl --insecure \
  2. --cacert node_exporter.cert.pem \
  3. --key node_exporter.key.pem \
  4. --cert node_exporter.cert.pem \
  5. https://localhost:8443/metrics | head
  6. # HELP go_gc_duration_seconds A summary of the GC invocation durations.
  7. # TYPE go_gc_duration_seconds summary
  8. go_gc_duration_seconds{quantile="0"} 3.0278e-05
  9. go_gc_duration_seconds{quantile="0.25"} 9.5253e-05
  10. go_gc_duration_seconds{quantile="0.5"} 0.000127839
  11. go_gc_duration_seconds{quantile="0.75"} 0.000165952
  12. go_gc_duration_seconds{quantile="1"} 0.002635578
  13. go_gc_duration_seconds_sum 6.476344632
  14. 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 的话,那么,也只需要这么配置就可以了:

  1. [root@liqiang.io]# cat prometheus.yaml
  2. - job_name: 'local-node-exporter'
  3. scrape_interval: 30s
  4. static_configs:
  5. - targets:
  6. - 'localhost:8443'
  7. scheme: https
  8. tls_config:
  9. ca_file: /node_exporter.cert.pem
  10. cert_file: node_exporter.cert.pem
  11. key_file: node_exporter.key.pem
  12. server_name: node_exporter

然后,打开 Prometheus 的管理页面看一下效果,看下是不是 OK 的:

图 3:Scrape Target 状态

3. Ref