2

Prometheus配置Basic Auth进行安全防护,实现登录控制 - 华为云开发者联盟

 8 months ago
source link: https://www.cnblogs.com/huaweiyun/p/17964855
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

本文分享自华为云社区《Prometheus配置Basic Auth进行安全防护,实现登录控制》,作者:可以交个朋友。

一、Prometheus Basic Auth 使用背景

在日常prometheus的使用中是没有安全加密措施的,可能会导致监控信息,敏感信息遭遇泄漏。在这种情况下需要保护对Prometheus的访问。

二、方案简介

Prometheus于2.24版本(包括2.24)之后提供Basic Auth功能进行加密访问,在浏览器登录UI的时候需要输入用户密码,访问Prometheus api的时候也需要加上用户密码。

大致步骤如下

  1. 预制用户密码,其中密码使用python3工具包加密
  2. 创建对应用户密码配置文件,修改普罗启动命令(operator场景通过ngress-nginx方式)
  3. 由于Prometheus访问需要认证,如果普罗负载存在探针则修改普罗负载本身的探针配置
  4. 由于Prometheus访问需要认证,如果有grafana,需要修改grafana相关步骤

三、准备工作,预制用户密码,其中密码使用python3工具包加密

因为Basic Auth 需要user、password 信息。访问Prometheus API的所有行为都需要用户名和密码。普罗配置的密码需要加盐加密,可以使用python3工具进行生成,再配置到普罗的相关配置中,作为登录密码认证使用。

安装python3环境

apt install python3-bcrypt

Python 脚本如下

import getpass
import bcrypt

password = getpass.getpass("password: ")
hashed_password = bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt())
print(hashed_password.decode())

运行脚本,假如我们需要的密码为: test。

执行脚本后,需要我们手动键入需要使用的密码,在终端键入的时候不显示

image-20230817144302442.png

保存密码备用: $2b$12$kXxrZP74Fmjh6Wih0Ignu.uWSiojl5aKj4UnMvHN9s2h/Lc/ui0.S

四、prometheus操作配置实践操作

在prometheus的日常使用中,通常有三种方式:

  1. 容器化部署在集群中
  2. 通过kube-prometheus部署
  3. 二进制直接在虚机上部署

三种不同方式安装的prometheus,配置basic auth的方式也略有差异。本文将对这三种使用场景进行Basic auth的配置。

4.1 Prometheus容器化部署添加BasicAuth

默认无需用户、密码等认证方式,直接通过服务IP和端口就能访问到prometheus 的queryAPI和UI界面

image-20230817170721016.png

image-20230817170752121.png

如果需要给UI和 prometheus API 添加basic auth,那么该如何做呢?

确认prom的版本信息,低于2.24版本的prometheus 不支持配置Basic Auth

image-20230817171317031.png

存在该启动命令,即可配置basic auth。

创建configmap配置项

准备webconfig.yml文件

basic_auth_users:
  admin: $2b$12$kXxrZP74Fmjh6Wih0Ignu.uWSiojl5aKj4UnMvHN9s2h/Lc/ui0.S

检测webconfig.yml是否可用:

promtool check web-config webconfig.yml

image-20230825093808294.png

复用上述的webconfig.yml

kubectl -n monitoring create configmap webconfig --from-file=webconfig.yml

image-20230817171736361.png

将configmap挂载给prometheus 实例

有多处修改点。

需要修改volume配置,即增加configmap的挂载

 volumes:
 - configMap:
     name: webconfig
   name: basic-auth

修改后效果如下:

image-20230817172926583.png

需要将配置挂载给prometheus容器,添加挂载点

 volumeMounts:
 - mountPath: /etc/prometheus/basicauth
   name: basic-auth

修改后效果如下:

image-20230817172953553.png

需要修改启动命令,添加 web.config.file

- --web.config.file=/etc/prometheus/basicauth/webconfig.yml

修改后效果如下:

image-20230817172844465.png

修改完上述配置后,还得看情况继续修改探针配置。

修改探针配置 (如果有健康检查相关配置的话)

同时还需要检查prometheus负载 是否有存活探针livenessProbe,和就绪探针readinessProbe相关配置。如果配置了探针,则需要对探针信息进行修改,添加访问头信息。否则会报错:

image-20230824204142073.png

因为kubelet探针需要访问prometheus接口,进行存活和就绪检测。如果配置了httpGet探针,不对探针进行httpHeaders配置,就会引起pod不断重启,无法正常运行。

image-20230824204620357.png

修改方式如下:

首先需要对 用户名和明文密码进行 Base64编码处理,例如我设置的basicauth信息是: admin:test

则需要echo -n "admin:test" |base64 -w0 ,编码后的信息为: YWRtaW46dGVzdA== ,保存备用

image-20230824205308281.png

然后继续编辑Prometheus负载配置:

image-20230824205740549.png

在livenessProbe.httpGet/readinessProbe.httpGet中添加:

httpGet: 
  httpHeaders:
  - name: Authorization
    value: Basic YWRtaW46dGVzdA==
image-20230824210728316.png
修改完成后,保存退出负载配置。然后手动重启pod实例。

修改完成后,查看prometheus 实例状态。实例就绪

image-20230824211132082.png

访问prometheus的queryAPI,发现如果不带用户信息,则访问失败。basic auth生效

image-20230824211618671.png

访问Prometheus UI: 需要带用户鉴权,否则无法访问:

image-20230824211744429.png

image-20230824211839428.png

页面密码输入明文即可。

4.2 Prometheus-operator部署场景添加basic auth

当前在k8s 部署prometheus 大都选择kube-prometheus这种形式,配置文件的变更都是交由crd进行管理。统一由prometheus-operator进行识别转换。

image-20230817184612951.png

查看对应的prometheus实例,并访问http API

image-20230817190001543.png

默认是不带鉴权的。

查看prometheus crd 的配置,发现没有web.config.file 相关可以配置的地方

当前kube-prometheus 还不支持配置basic auth,详情可见https://github.com/prometheus-operator/prometheus-operator/issues/5765

借助nginx-ingress的能力配置basic auth。nginx ingress 在这方面非常灵活。

image-20230817203143324.png
即创建ingress 来实现。再创建ingress之前,我们需要先准备auth-secret

执行下述命令之前 先安装 工具: yum -y install httpd

$ htpasswd -c auth admin
New password:  test
New password:
Re-type new password:
Adding password for user admin

效果如下:

image-20230817203541970.png

使用auth文件创建secret:

kubectl create secret generic basic-auth --from-file=auth

image-20230817203814812.png

给prometheus创建ingress访问入口

由于我使用的k8s版本是1.21,ingress的写法会有所不同,1.22以后,ingress的api也不再是networking.k8s.io/v1beta1

# ingress-prom.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/auth-realm: Authentication Required
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-type: basic
    kubernetes.io/ingress.class: nginx
  name: prometheus-k8s
  namespace: monitoring
spec:
  rules:
  - host: prometheus.example.com
    http:
      paths:
      - backend:
          serviceName: prometheus-k8s
          servicePort: 9090
        path: /
        pathType: Prefix

image-20230817204202987.png

访问queryAPI&prometheus UI

可以发现queryAPI直接访问已经被限制登录

image-20230817204801398.png

如果带鉴权用户访问则可以获取监控数据

image-20230817204704246.png

同时也可以发现,访问UI已经限制登录鉴权

image-20230817204801398.png

输入用户和密码后即可登录

image-20230817204935160.png

高版本的k8s ingress写法可参考

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/auth-realm: Authentication Required
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-type: basic
    kubernetes.io/ingress.class: nginx
  name: prometheus-k8s
  namespace: monitoring
spec:
  rules:
  - host: prometheus.example.com
    http:
      paths:
      - backend:
          service:
            name: prometheus-k8s
            port:
              name: web
        path: /
        pathType: Prefix

4.3 Prometheus裸机方式部署添加Basic Auth

创建webconfig.yml

basic_auth_users:
  admin: $2b$12$kXxrZP74Fmjh6Wih0Ignu.uWSiojl5aKj4UnMvHN9s2h/Lc/ui0.S

image-20230817144833637.png

启动prometheus

./prometheus --web.config.file=webconfig.yml --config.file=prometheus.yml

其中 --web.config.file=webconfig.yml 为关键配置,prometheus 启动后会要求 带密码访问
启动成功:

image-20230817145731245.png

访问prometheus UI

要求输入用户密码信息

image-20230817145854252.png

访问prometheus http API接口

image-20230817150044916.png

带用户信息访问:

image-20230817150204288.png

五、Grafana 如何对接鉴权之后的Prometheus

正常来说,如果对Prometheus配置了Basic Auth后,所有需要访问Prometheus的组件均需做出调整,否则无法获取数据。Grafana也不例外

登录Grafana UI, 初次登录需要填写grafana的用户密码,默认是admin:admin

image-20230824212703932.png

确认数据源配置,并对数据源进行配置

image-20230824213031845.png

配置完成后,点击正下方绿色按钮Test,测试数据源的联通性(不出意外,连接失败)

如果没失败,就万事大吉,无需在往下看了。恭喜你完成对接。

失败了请看下面,如何解决:

image-20230824213249209.png

查看monitoring命名空间中grafana-datasource的configmap配置

kubectl get cm -n monitoring |grep grafana-datasources

image-20230824213541927.png

编辑该配置项:

kubectl edit cm grafana-datasources -n monitoring

将 editable: false 设置为 : editable: true

修改的原因是因为 grafana内置了默认的数据源,且数据源不允许修改。我们需要调整这个默认的规定

image-20230824213702984.png

手动重启grafana实例

cm修改完成后,无法动态加载配置,需要手动重启grafana实例加载新配置。

如果grafana没做持久化处理,之前手动配置的dashboard可能会因为重启grafana实例而丢失,建议备份dashboard,dashboard可由grafana页面以json格式导出

image-20230824214658953.png

再次访问Grafana UI

image-20230824215020714.png

查看dashboard信息:

image-20230824215208599.png

Ok,大功告成!

六、总结建议

容器化部署的prometheus 修改逻辑其实和二进制相同。将对应的Basic Auth 信息传递给prometheus,然后启动加载就可以了。低版本Promethues加载失败,会打印错误日志:

unknow long flag '--web.config.file'

要求Prometheus版本不低于2.24。

如果prometheus在部署的时候配置了存活探针和就绪探针,不对探针进行httpHeaders的配置,则会造成prometheus实例无法正常运行。

七 拓展内容

7.1 Grafana 如何取消匿名登录

正常情况下,Grafana的监控信息应该需要用户才能登录显示对接数据源指标的显示。如果谁都能登录查看,容器造成信息泄漏等安全问题

image-20230824215619716.png

如何才能实现Grafana的安全登录功能呢?

查看集群中monitoring ns下的grafana-conf 配置项

kubectl get cm -n monitoring |grep grafana-conf

image-20230824220225466.png

编辑该配置项

kubectl edit cm -n monitoring grafana-conf

根据关键字找到 auth.anonymous配置,将enabled = true 设置为 fale

image-20230824220449427.png

重启grafana 实例

修改配置后,需要重启grafana实例,加载配置(如果没做持久化处理,注意备份相关dashboard)

刷新grafana页面,重新登录

可以发现,再次登录页面,都需要填写用户信息了

image-20230824220929490.png

7.2 Prometheus BasicAuth 添加多用户

现实场景下,Prometheus的Baisc Auth信息需要配置多个提供给不同团队。

例如我之前添加的basic auth 只用一个鉴权用户: admin: test; 现在如果想添加新的鉴权用户: mike: hello

我们先用python3 工具生成hello 字段加密后的样子: $2b$12$qhdgpdq669cXNW4DLqRfI.JIBJ0KIvvf0I.I3ccie/tn8d4BxzqV2

此时只需要前往之前设置的webconfig 这个configmap中添加该信息即可:

kubectl edit cm webconfig -n monitoring

image-20230824222610149.png

修改完成后,使用prometheus的热加载命令加载新配置:

curl -u "admin:test" -XPOST http://ip:9090/-/reload

image-20230824223258717.png

多用户访问生效

image-20230824223456609.png

点击关注,第一时间了解华为云新鲜技术~


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK