为 Prometheus Node Exporter 加上认证

这篇文章主要是为了庆祝 Node Exporter 终于迎来了 v1.0.0 版本。

Prometheus 是最早由 SoundCloud 开源的监控告警解决方案。并已经成长为继 Kubernetes 之后,第二个从 CNCF 毕业的项目。伴随着云原生理念的普及和 Kubernetes 等技术的发展, Prometheus 在监控领域也有了长足的发展。

其主要组件包括 Prometheus,Alertmanager,Node Exporter,Blackbox Exporter 和 Pushgateway 等。

本文主要是为了庆祝 Node Exporter 终于迎来了 v1.0.0 版本, 所以重点主要放在一直被人诟病的安全性相关上,具体而言就是利用 TLS 和 Basic Auth 提升其安全性。

背景

Node Exporter 是 Prometheus 官方发布的,用于采集节点的系统信息,比如 CPU,内存,磁盘和网络等信息。
通常情况下,如果我们在使用 Prometheus 作为监控方案,那 Node Exporter 基本都会用到的。

在 Promethues 的监控体系中,社区中一直存在的一个观点是,Metrics 不包含过于私密的信息。所以你可以看到,大多数的 /metrics 接口都是直接暴露出来的,没什么特别的安全措施。

但随着 Prometheus 在生产中的大量应用,安全问题变得更加重要。

大家最先想到的解决办法就是,为 Prometheus 与监控目标之间的连接启用 TLS。 但由于各类 exporter 并不原生支持 TLS 连接,所以通常情况下我们会选择配合反向代理来完成。

这种方式能满足需求,但未免复杂了些。近期 Prometheus 对其安全模型做了修改 , 从 Node Exporter 开始到后续其他的组件,都将支持 TLS 和 basic auth, 同时也列出了最新的安全基准(默认情况下都支持 TLS v1.2 及以上)

使用 TLS

这里我们直接实践下看看如何启用 TLS 。

准备证书

(MoeLove) ➜  ~ mkdir -p prometheus-tls
(MoeLove) ➜  ~ cd prometheus-tls
(MoeLove) ➜  prometheus-tls openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout node_exporter.key -out node_exporter.crt -subj "/C=CN/ST=Beijing/L=Beijing/O=Moelove.info/CN=localhost"
Generating a RSA private key
...........................................+++++
..+++++
writing new private key to 'node_exporter.key'
-----
(MoeLove) ➜  prometheus-tls ls
node_exporter.crt  node_exporter.key

通过上面的步骤,我们得到了 node_exporter.crt node_exporter.key 这两个文件。

Node Exporter 使用 TLS

下载 v1.0.0 版本的 Node Exporter, 并对其进行解压等操作

(MoeLove) ➜  /tmp tar -zxvf node_exporter-1.0.0.linux-amd64.tar.gz 
node_exporter-1.0.0.linux-amd64/
node_exporter-1.0.0.linux-amd64/node_exporter
node_exporter-1.0.0.linux-amd64/NOTICE
node_exporter-1.0.0.linux-amd64/LICENSE
(MoeLove) ➜  /tmp cd node_exporter-1.0.0.linux-amd64 
(MoeLove) ➜  node_exporter-1.0.0.linux-amd64 ls
LICENSE  node_exporter  NOTICE

复制前面生成的 node_exporter.crt node_exporter.key 这两个文件到当前目录下。

(MoeLove) ➜  node_exporter-1.0.0.linux-amd64 cp ~/prometheus-tls/node_exporter.* .
(MoeLove) ➜  node_exporter-1.0.0.linux-amd64 ls
LICENSE  node_exporter  node_exporter.crt  node_exporter.key  NOTICE

编写配置文件,并保存为 config.yaml (命名随意):

tls_server_config:
  cert_file: node_exporter.crt
  key_file: node_exporter.key

接下来就使用 --web.config 将配置文件传递给 Node Exporter

(MoeLove) ➜  node_exporter-1.0.0.linux-amd64 ./node_exporter --web.config=config.yaml
level=info ts=2020-05-26T17:50:12.123Z caller=node_exporter.go:177 msg="Starting node_exporter" version="(version=1.0.0, branch=HEAD, revision=b9c96706a7425383902b6143d097cf6d7cfd1960)"
level=info ts=2020-05-26T17:50:12.124Z caller=node_exporter.go:178 msg="Build context" build_context="(go=go1.14.3, user=root@3e55cc20ccc0, date=20200526-06:01:48)" 
level=info ts=2020-05-26T17:50:12.130Z caller=node_exporter.go:105 msg="Enabled collectors"
...
level=info ts=2020-05-26T17:50:12.135Z caller=tls_config.go:200 msg="TLS is enabled and it cannot be disabled on the fly." http2=true

当你看到最后这句日志时,就说明你的 Node Exporter 已经启用了 TLS 连接。

当然,我们也可以选择手动验证下:

# 直接 curl 请求
(MoeLove) ➜  prometheus-tls curl localhost:9100/metrics
Client sent an HTTP request to an HTTPS server.

(MoeLove) ➜  prometheus-tls curl https://localhost:9100/metrics                 
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

可以看到不能直接 curl 进行请求了,我们可以将证书传递给 curl ,用来验证刚才的配置是否正确。

(MoeLove) ➜  prometheus-tls curl -s  --cacert node_exporter.crt https://localhost:9100/metrics  |grep node_exporter_build_info
# HELP node_exporter_build_info A metric with a constant '1' value labeled by version, revision, branch, and goversion from which node_exporter was built.
# TYPE node_exporter_build_info gauge
node_exporter_build_info{branch="HEAD",goversion="go1.14.3",revision="b9c96706a7425383902b6143d097cf6d7cfd1960",version="1.0.0"} 1

当然,除了通过 --cacert 参数将证书传递给 curl 外,也可以通过 -k 参数来忽略证书检查。

(MoeLove) ➜  prometheus-tls curl -s  -k https://localhost:9100/metrics  |grep node_exporter_build_info        
# HELP node_exporter_build_info A metric with a constant '1' value labeled by version, revision, branch, and goversion from which node_exporter was built.
# TYPE node_exporter_build_info gauge
node_exporter_build_info{branch="HEAD",goversion="go1.14.3",revision="b9c96706a7425383902b6143d097cf6d7cfd1960",version="1.0.0"} 1

配置 Prometheus 使用 TLS

接下来,我们就要配置 Prometheus 通过 HTTPS 从 Node Exporter 获取指标了。安装过程很简单,无论直接下载最新的二进制版本,或是直接使用 Docker 镜像均可。

注意,我这里把上文中签发的证书复制到了当前目录中。

(MoeLove) ➜  prometheus-2.18.1.linux-amd64 cp ~/prometheus-tls/node_exporter.crt .
(MoeLove) ➜  prometheus-2.18.1.linux-amd64 ls
console_libraries  consoles  LICENSE  node_exporter.crt  NOTICE  prometheus  prometheus.yml  promtool  tsdb

接下来,需要修改下配置文件,让 Prometheus 可以抓取 Node Exporter 暴露的 metrics 。

global:
  scrape_interval:     15s 
  evaluation_interval: 15s 

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
    - targets: ['localhost:9090']

  - job_name: 'node_exporter'
    scheme: https
    tls_config:
      ca_file: node_exporter.crt
    static_configs:
    - targets: ['localhost:9100']

这里额外增加了 scheme: https 表示通过 HTTPS 建立连接,tls_config 中指定了所用的证书文件。完整的配置可以参考 官方文档中对 tls_config 的说明

最后,启动 Prometheus 并在浏览器中访问 /targets ,如果你在 endpoint 中看到 https://localhost:9100/metrics 了,那么恭喜你,Prometheus 和 Node Exporter 已经通过 TLS 连接了。

Prometheus TLS - https://moelove.info

添加 Basic Auth

上文中,我已经为你介绍了如何使用让 Prometheus 和 Node Exporter 间使用 TLS 连接了,接下来,我为你介绍如何增加 Basic Auth 。

这里需要注意的是,Basic Auth 和 TLS 并不是强依赖的。你可以在不开启 TLS 的情况下使用 Basic Auth ,但我个人建议,要做就做彻底点,同时启用好了。

为 Node Exporter 配置密码

我们直接可以使用 htpasswd 来生成 bcrypt 密码 hash (这个工具想必大家不会太陌生)。

(MoeLove) ➜  prometheus-tls htpasswd -nBC 12 '' | tr -d ':\n'       
New password:
Re-type new password:                                              
$2y$12$WLw2sYa.NYZoBVoCOE84qe3xNm7kbSoKVIBXP.PvqNDna60vnZhEW

这里我只用它来生成了密码 hash , 没有传递用户名。

接下来,修改上文中提到的 Node Exporter 所用的配置文件,如下:

tls_server_config:
  cert_file: node_exporter.crt
  key_file: node_exporter.key
basic_auth_users:
  # 当前设置的用户名为 prometheus , 可以设置多个
  prometheus: $2y$12$WLw2sYa.NYZoBVoCOE84qe3xNm7kbSoKVIBXP.PvqNDna60vnZhEW

再次启动 Node Exporter,并使用 curl 请求 metrics 接口,可以看到当前返回 401 。

(MoeLove) ➜  prometheus-tls curl -Ik https://127.0.0.1:9100/metrics 
HTTP/1.1 401 Unauthorized
Content-Type: text/plain; charset=utf-8
Www-Authenticate: Basic
X-Content-Type-Options: nosniff
Date: Wed, 27 May 2020 11:45:16 GMT
Content-Length: 13

打开 Prometheus 的 Targets 页面,也会看到当前提示 401 ,无法抓取 metrics 。

Prometheus Basic Auth - https://moelove.info

配置 Prometheus 使用 Basic Auth

接下来,只要修改 Prometheus 的配置文件,为其增加 basic_auth 的配置项即可。

global:
  scrape_interval:     15s 
  evaluation_interval: 15s 

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
    - targets: ['localhost:9090']

  - job_name: 'node_exporter'
    scheme: https
    tls_config:
      ca_file: node_exporter.crt
    basic_auth:
      username: prometheus
      password: moelove.info
    static_configs:
    - targets: ['localhost:9100']

修改配置文件后,只要让 Prometheus 重新加载配置文件即可:

(MoeLove) ➜  killall -HUP prometheus

现在刷新 Prometheus 的 Targets 页面,就可以看到已经正常抓取 metrics 了。

总结

本文介绍了如何开启 Prometheus 和 Node Exporter 之间的 TLS 连接, 以及开启 Node Exporter 的 Basic Auth 认证。 在此之前,可能有小伙伴是通过加反代来完成的,比如: 给 Node Exporter 加上 Basic 认证

在生产中使用时,建议更加规范化操作,比如 CA 的选择,密码的管理等,比如 Node Exporter 的 Basic Auth 其实支持配置多个用户名密码的。

接下来,在 Prometheus 官方提供的基础组件中,都将逐步推进本文中所提到的这类安全特性的支持,包括 Prometheus,Alertmanager, Pushgateway 和官方 exporter ,后续社区提供的 exporter 大概率也会逐步跟进的。

最后,再次恭喜 Node Exporter 迎来了 v1.0.0 版本。


欢迎订阅我的文章公众号【MoeLove】

TheMoeLove

阅读 667

推荐阅读
K8S生态
用户专栏

Container, Docker, Go, Kubernetes, Python, Vim; 微信公众号: MoeLove

52 人关注
68 篇文章
专栏主页