[转帖]SSL Certificate Exporter
https://github.com/ribbybibby/ssl_exporter
Exports metrics for certificates collected from various sources:
The metrics are labelled with fields from the certificate, which allows for informational dashboards and flexible alert routing.
Building
make
./ssl_exporter <flags>
Similarly to the blackbox_exporter, visiting http://localhost:9219/probe?target=example.com:443 will return certificate metrics for example.com. The ssl_probe_success
metric indicates if the probe has been successful.
Docker
docker run -p 9219:9219 ribbybibby/ssl-exporter:latest <flags>
Release process
- Create a release in Github with a semver tag and GH actions will:
- Add a changelog
- Upload binaries
- Build and push a Docker image
Usage
usage: ssl_exporter [<flags>]
Flags:
-h, --help Show context-sensitive help (also try --help-long and
--help-man).
--web.listen-address=":9219"
Address to listen on for web interface and telemetry.
--web.metrics-path="/metrics"
Path under which to expose metrics
--web.probe-path="/probe" Path under which to expose the probe endpoint
--config.file="" SSL exporter configuration file
--log.level="info" Only log messages with the given severity or above. Valid
levels: [debug, info, warn, error, fatal]
--log.format="logger:stderr"
Set the log target and format. Example:
"logger:syslog?appname=bob&local=7" or
"logger:stdout?json=true"
--version Show application version.
Metrics
Metric | Meaning | Labels | Probers |
---|---|---|---|
ssl_cert_not_after | The date after which a peer certificate expires. Expressed as a Unix Epoch Time. | serial_no, issuer_cn, cn, dnsnames, ips, emails, ou | tcp, https |
ssl_cert_not_before | The date before which a peer certificate is not valid. Expressed as a Unix Epoch Time. | serial_no, issuer_cn, cn, dnsnames, ips, emails, ou | tcp, https |
ssl_file_cert_not_after | The date after which a certificate found by the file prober expires. Expressed as a Unix Epoch Time. | file, serial_no, issuer_cn, cn, dnsnames, ips, emails, ou | file |
ssl_file_cert_not_before | The date before which a certificate found by the file prober is not valid. Expressed as a Unix Epoch Time. | file, serial_no, issuer_cn, cn, dnsnames, ips, emails, ou | file |
ssl_kubernetes_cert_not_after | The date after which a certificate found by the kubernetes prober expires. Expressed as a Unix Epoch Time. | namespace, secret, key, serial_no, issuer_cn, cn, dnsnames, ips, emails, ou | kubernetes |
ssl_kubernetes_cert_not_before | The date before which a certificate found by the kubernetes prober is not valid. Expressed as a Unix Epoch Time. | namespace, secret, key, serial_no, issuer_cn, cn, dnsnames, ips, emails, ou | kubernetes |
ssl_kubeconfig_cert_not_after | The date after which a certificate found by the kubeconfig prober expires. Expressed as a Unix Epoch Time. | kubeconfig, name, type, serial_no, issuer_cn, cn, dnsnames, ips, emails, ou | kubeconfig |
ssl_kubeconfig_cert_not_before | The date before which a certificate found by the kubeconfig prober is not valid. Expressed as a Unix Epoch Time. | kubeconfig, name, type, serial_no, issuer_cn, cn, dnsnames, ips, emails, ou | kubeconfig |
ssl_ocsp_response_next_update | The nextUpdate value in the OCSP response. Expressed as a Unix Epoch Time | tcp, https | |
ssl_ocsp_response_produced_at | The producedAt value in the OCSP response. Expressed as a Unix Epoch Time | tcp, https | |
ssl_ocsp_response_revoked_at | The revocationTime value in the OCSP response. Expressed as a Unix Epoch Time | tcp, https | |
ssl_ocsp_response_status | The status in the OCSP response. 0=Good 1=Revoked 2=Unknown | tcp, https | |
ssl_ocsp_response_stapled | Does the connection state contain a stapled OCSP response? Boolean. | tcp, https | |
ssl_ocsp_response_this_update | The thisUpdate value in the OCSP response. Expressed as a Unix Epoch Time | tcp, https | |
ssl_probe_success | Was the probe successful? Boolean. | all | |
ssl_prober | The prober used by the exporter to connect to the target. Boolean. | prober | all |
ssl_tls_version_info | The TLS version used. Always 1. | version | tcp, https |
ssl_verified_cert_not_after | The date after which a certificate in the verified chain expires. Expressed as a Unix Epoch Time. | chain_no, serial_no, issuer_cn, cn, dnsnames, ips, emails, ou | tcp, https |
ssl_verified_cert_not_before | The date before which a certificate in the verified chain is not valid. Expressed as a Unix Epoch Time. | chain_no, serial_no, issuer_cn, cn, dnsnames, ips, emails, ou | tcp, https |
Configuration
TCP
Just like with the blackbox_exporter, you should pass the targets to a single instance of the exporter in a scrape config with a clever bit of relabelling. This allows you to leverage service discovery and keeps configuration centralised to your Prometheus config.
scrape_configs:
- job_name: "ssl"
metrics_path: /probe
static_configs:
- targets:
- example.com:443
- prometheus.io:443
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 127.0.0.1:9219 # SSL exporter.
HTTPS
By default the exporter will make a TCP connection to the target. This will be suitable for most cases but if you want to take advantage of http proxying you can use a HTTPS client by setting the https
module parameter:
scrape_configs:
- job_name: "ssl"
metrics_path: /probe
params:
module: ["https"] # <-----
static_configs:
- targets:
- example.com:443
- prometheus.io:443
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 127.0.0.1:9219
This will use proxy servers discovered by the environment variables HTTP_PROXY
, HTTPS_PROXY
and ALL_PROXY
. Or, you can set the proxy_url
option in the module configuration.
The latter takes precedence.
File
The file
prober exports ssl_file_cert_not_after
and ssl_file_cert_not_before
for PEM encoded certificates found in local files.
Files local to the exporter can be scraped by providing them as the target parameter:
curl "localhost:9219/probe?module=file&target=/etc/ssl/cert.pem"
The target parameter supports globbing (as provided by the doublestar package), which allows you to capture multiple files at once:
curl "localhost:9219/probe?module=file&target=/etc/ssl/**/*.pem"
One specific usage of this prober could be to run the exporter as a DaemonSet in Kubernetes and then scrape each instance to check the expiry of certificates on each node:
scrape_configs:
- job_name: "ssl-kubernetes-file"
metrics_path: /probe
params:
module: ["file"]
target: ["/etc/kubernetes/**/*.crt"]
kubernetes_sd_configs:
- role: node
relabel_configs:
- source_labels: [__address__]
regex: ^(.*):(.*)$
target_label: __address__
replacement: ${1}:9219
Kubernetes
The kubernetes
prober exports ssl_kubernetes_cert_not_after
and ssl_kubernetes_cert_not_before
for PEM encoded certificates found in secrets of type kubernetes.io/tls
.
Provide the namespace and name of the secret in the form <namespace>/<name>
as the target:
curl "localhost:9219/probe?module=kubernetes&target=kube-system/secret-name"
Both the namespace and name portions of the target support glob matching (as provided by the doublestar package):
curl "localhost:9219/probe?module=kubernetes&target=kube-system/*"
curl "localhost:9219/probe?module=kubernetes&target=*/*"
The exporter retrieves credentials and context configuration from the following sources in the following order:
- The
kubeconfig
path in the module configuration - The
$KUBECONFIG
environment variable - The default configuration file (
$HOME/.kube/config
) - The in-cluster environment, if running in a pod
- job_name: "ssl-kubernetes"
metrics_path: /probe
params:
module: ["kubernetes"]
static_configs:
- targets:
- "test-namespace/nginx-cert"
relabel_configs:
- source_labels: [ __address__ ]
target_label: __param_target
- source_labels: [ __param_target ]
target_label: instance
- target_label: __address__
replacement: 127.0.0.1:9219
Kubeconfig
The kubeconfig
prober exports ssl_kubeconfig_cert_not_after
and ssl_kubeconfig_cert_not_before
for PEM encoded certificates found in the specified kubeconfig file.
Kubeconfigs local to the exporter can be scraped by providing them as the target parameter:
curl "localhost:9219/probe?module=kubeconfig&target=/etc/kubernetes/admin.conf"
One specific usage of this prober could be to run the exporter as a DaemonSet in Kubernetes and then scrape each instance to check the expiry of certificates on each node:
scrape_configs:
- job_name: "ssl-kubernetes-kubeconfig"
metrics_path: /probe
params:
module: ["kubeconfig"]
target: ["/etc/kubernetes/admin.conf"]
kubernetes_sd_configs:
- role: node
relabel_configs:
- source_labels: [__address__]
regex: ^(.*):(.*)$
target_label: __address__
replacement: ${1}:9219
Configuration file
You can provide further module configuration by providing the path to a configuration file with --config.file
. The file is written in yaml format, defined by the schema below.
# The default module to use. If omitted, then the module must be provided by the
# 'module' query parameter
default_module: <string>
# Module configuration
modules: [<module>]
<module>
# The type of probe (https, tcp, file, kubernetes, kubeconfig)
prober: <prober_string>
# The probe target. If set, then the 'target' query parameter is ignored.
# If omitted, then the 'target' query parameter is required.
target: <string>
# How long the probe will wait before giving up.
[ timeout: <duration> ]
# Configuration for TLS
[ tls_config: <tls_config> ]
# The specific probe configuration
[ https: <https_probe> ]
[ tcp: <tcp_probe> ]
[ kubernetes: <kubernetes_probe> ]
<tls_config>
# Disable target certificate validation.
[ insecure_skip_verify: <boolean> | default = false ]
# Configure TLS renegotiation support.
# Valid options: never, once, freely
[ renegotiation: <string> | default = never ]
# The CA cert to use for the targets.
[ ca_file: <filename> ]
# The client cert file for the targets.
[ cert_file: <filename> ]
# The client key file for the targets.
[ key_file: <filename> ]
# Used to verify the hostname for the targets.
[ server_name: <string> ]
<https_probe>
# HTTP proxy server to use to connect to the targets.
[ proxy_url: <string> ]
<tcp_probe>
# Use the STARTTLS command before starting TLS for those protocols that support it (smtp, ftp, imap, pop3, postgres)
[ starttls: <string> ]
<kubernetes_probe>
# The path of a kubeconfig file to configure the probe
[ kubeconfig: <string> ]
Example Queries
Certificates that expire within 7 days:
ssl_cert_not_after - time() < 86400 * 7
Wildcard certificates that are expiring:
ssl_cert_not_after{cn=~"\*.*"} - time() < 86400 * 7
Certificates that expire within 7 days in the verified chain that expires latest:
ssl_verified_cert_not_after{chain_no="0"} - time() < 86400 * 7
Number of certificates presented by the server:
count(ssl_cert_not_after) by (instance)
Identify failed probes:
ssl_probe_success == 0
Peer Certificates vs Verified Chain Certificates
Metrics are exported for the NotAfter
and NotBefore
fields for peer certificates as well as for the verified chain that is constructed by the client.
The former only includes the certificates that are served explicitly by the target, while the latter can contain multiple chains of trust that are constructed from root certificates held by the client to the target's server certificate.
This has important implications when monitoring certificate expiry.
For instance, it may be the case that ssl_cert_not_after
reports that the root certificate served by the target is expiring soon even though clients can form another, much longer lived, chain of trust using another valid root certificate held locally. In this case, you may want to use ssl_verified_cert_not_after
to alert on expiry instead, as this will contain the chain that the client actually constructs:
ssl_verified_cert_not_after{chain_no="0"} - time() < 86400 * 7
Each chain is numbered by the exporter in reverse order of expiry, so that chain_no="0"
is the chain that will expire the latest. Therefore the query above will only alert when the chain of trust between the exporter and the target is truly nearing expiry.
It's very important to note that a query of this kind only represents the chain of trust between the exporter and the target. Genuine clients may hold different root certs than the exporter and therefore have different verified chains of trust.
Grafana
You can find a simple dashboard here that tracks certificate expiration dates and target connection errors.
[转帖]SSL Certificate Exporter的更多相关文章
- SSL certificate problem unable to get local issuer certificate解决办法
SSL certificate problem unable to get local issuer certificate 解决办法: 下载:ca-bundle.crt 将它放在自己的wamp或者x ...
- How To Set Up Apache with a Free Signed SSL Certificate on a VPS
Prerequisites Before we get started, here are the web tools you need for this tutorial: Google Chrom ...
- How To Create a SSL Certificate on Apache for CentOS 6
About Self-Signed Certificates 自签证书.一个SSL证书,是加密网站的信息,并创建更安全的链接的一种方式.附加地,证书可以给网站浏览者显示VPS的的身份证明信息.如果一个 ...
- Configure custom SSL certificate for RDP on Windows Server 2012 in Remote Administration mode
Q: So the release of Windows Server 2012 has removed a lot of the old Remote Desktop related configu ...
- (转)How to renew your Apple Push Notification Push SSL Certificate
转自:https://blog.serverdensity.com/how-to-renew-your-apple-push-notification-push-ssl-certificate/ It ...
- 执行Git命令时出现 SSL certificate problem 的解决办法
比如我在windows下用git clone gitURL 就提示 SSL certificate problem: self signed certificate 这种问题,在windows下出现 ...
- last error : SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate veri
今天在用搜狐提供的邮件群发系统的sdk,做发送邮件的测试时,提示: last error : SSL certificate problem, verify that the CA cert is O ...
- Failed to connect to VMware Lookup Service……SSL certificate verification failed
今天登陆vsphere web-client时候,报错如下: Failed to connect to VMware Lookup Service https://vc-test.cebbank.co ...
- The SSL certificate used to load resources from xxx will be distrusted in M70.
今天在浏览网站的时候遇到如下报警信息: The SSL certificate used to load resources from https://xxx.com will be distrust ...
- 执行Git命令时出现各种 SSL certificate problem 的解决办法
执行Git命令时出现各种 SSL certificate problem 的解决办法 来源 https://www.cnblogs.com/chenzc/p/5842932.html 比如我在win ...
随机推荐
- 19、Flutter StatelessWidget 、 StatefulWidget
在Flutter中自定义组件其实就是一个类,这个类需要继承StatelessWidget / StatefulWidget. StatelessWidget是无状态组件,状态不可变的widget ...
- 物联网为什么需要5G?
摘要:5G,这个词,我想每个接触ICT行业的朋友都有听过,可5G的到来,对物联网行业的帮助究竟是什么? 我相信,95%的ICT从业者对5G这一概念没有一个清晰的认知. 这一期文章的主题主要是普及一些5 ...
- Python图像处理丨图像的灰度线性变换
摘要:本文主要讲解灰度线性变换. 本文分享自华为云社区<[Python图像处理] 十五.图像的灰度线性变换>,作者:eastmount. 一.图像灰度线性变换原理 图像的灰度线性变换是通过 ...
- 华为云GaussDB新产品特性亮相DTC2021,重磅新品开源预告
摘要:华为云数据库产品部CTO庄乾锋携3位GaussDB技术专家在DTC2021大会上分享了产品最新技术.优秀实践案例,以及透露了重大新品即将开源,以数据驱动业务发展,为企业数字化转型持续注入新动力. ...
- SEAL 0.3 正式发布:国内首个全链路软件供应链安全管理平台
12月1日,软件供应链安全管理平台 SEAL 0.3 正式发布(以下简称"SEAL"),这是国内首个以全链路视角保护软件供应链的安全管理平台.两个月前 SEAL 0.2 发布,该版 ...
- 高性能 Jsonpath 框架,Snack3 3.2.57 发布
Snack3,一个高性能的 JsonPath 框架 借鉴了 Javascript 所有变量由 var 申明,及 Xml dom 一切都是 Node 的设计.其下一切数据都以ONode表示,ONode也 ...
- Kubernetes(K8S) helm chart
感觉和放到一个 yaml 文件中,用 ---- 分隔,操作繁琐程度上,没有太大区别 创建自定义 Chart # 创建自定义的 chart 名为 mychart [root@k8smaster ~]# ...
- docker中安装的mysql无法远程连接问题解决
背景: 在ubuntu1804的docker中安装了mysql,版本是5.7.34.因为有复杂的数据要插入到数据库中,所以从宿主机通过pycharm和DBeaver连接,但是一直报错: Can not ...
- RocketMQ事务消息在订单创建和库存扣减的使用
前言 下单的过程包括订单创建,还有库存的扣减,为提高系统的性能,将库存放在redis扣减,则会涉及到Mysql和redis之间的数据同步,其中,这个过程还涉及到,必须是订单创建成功才进行库存的扣减操作 ...
- 基于分发与计算的GRTN全球实时传输网络
一张能同时满足「分发」与「计算」需求的网. 从直播趋势看「分发」与「计算」 阿里云直播产品架构图中,主要分为端和云两个部分:在端侧,主要包含推流端和播放端:在云侧,一是基于分布式节点构建的传输网,二是 ...