您的位置:  首页 > 技术杂谈 > 正文

Prometheus配置Basic Auth进行安全防护,实现登录控制

2024-01-17 14:00 https://my.oschina.net/u/4526289/blog/10823572 华为云开发者联盟 次阅读 条评论

本文分享自华为云社区《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

 

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

 

展开阅读全文
  • 0
    感动
  • 0
    路过
  • 0
    高兴
  • 0
    难过
  • 0
    搞笑
  • 0
    无聊
  • 0
    愤怒
  • 0
    同情
热度排行
友情链接