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_PROXYHTTPS_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的更多相关文章

  1. SSL certificate problem unable to get local issuer certificate解决办法

    SSL certificate problem unable to get local issuer certificate 解决办法: 下载:ca-bundle.crt 将它放在自己的wamp或者x ...

  2. 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 ...

  3. How To Create a SSL Certificate on Apache for CentOS 6

    About Self-Signed Certificates 自签证书.一个SSL证书,是加密网站的信息,并创建更安全的链接的一种方式.附加地,证书可以给网站浏览者显示VPS的的身份证明信息.如果一个 ...

  4. 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 ...

  5. (转)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 ...

  6. 执行Git命令时出现 SSL certificate problem 的解决办法

    比如我在windows下用git clone gitURL 就提示  SSL certificate problem: self signed certificate 这种问题,在windows下出现 ...

  7. 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 ...

  8. 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 ...

  9. 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 ...

  10. 执行Git命令时出现各种 SSL certificate problem 的解决办法

    执行Git命令时出现各种 SSL certificate problem 的解决办法 来源  https://www.cnblogs.com/chenzc/p/5842932.html 比如我在win ...

随机推荐

  1. 斯坦福 UE4 C++ ActionRoguelike游戏实例教程 06.敲定AI——游戏框架拓展和细节优化

    斯坦福课程 UE4 C++ ActionRoguelike游戏实例教程 0.绪论 概述 这篇文章对应课程13课, 50~54节.虽然标题是敲定AI,实际内容和AI关联并不大,主要工作是对游戏内各种细节 ...

  2. 共筑数字化未来,金山办公携手华为云完成文档中心和GaussDB适配

    摘要:金山办公携手华为云完成金山办公自主研发的"WPS文档中心系统"与华为云GaussDB相互兼容性测试认证,并获得华为云授予的<技术认证书>. 本文分享自华为云社区& ...

  3. 玩转GaussDB 中的SET操作符

    摘要:关系数据库中提供了一个关于集合的运算符SET操作符,其中包括以下操作:UNION/UNION ALL 并集.INTERSECT 交集.MINUS 差集. 本文分享自华为云社区<GaussD ...

  4. 前端面试常考题:JS垃圾回收机制

    摘要:众所周知,应用程序在运行过程中需要占用一定的内存空间,且在运行过后就必须将不再用到的内存释放掉,否则就会出现下图中内存的占用持续升高的情况,一方面会影响程序的运行速度,另一方面严重的话则会导致整 ...

  5. 干货分享丨从MPG 线程模型,探讨Go语言的并发程序

    摘要:Go 语言的并发特性是其一大亮点,今天我们来带着大家一起看看如何使用 Go 更好地开发并发程序. 我们都知道计算机的核心为 CPU,它是计算机的运算和控制核心,承载了所有的计算任务.最近半个世纪 ...

  6. 50亿海量数据如何高效存储和分析? GaussDB (for Cassandra) 3个秘诀搞定

    摘要:信息社会正在从互联网时代走向物联网时代,企业不可避免的要面对数据量剧增带来的一系列问题:如何高效存储和扩容,如何在对原有业务改动最小的情况下做到智能化和实时分析. 本文分享自华为云社区<5 ...

  7. JAVA SQLServerException: 通过端口 1433 连接到主机 127.0.0.1 的 TCP/IP 连接失败

    [2021-01-15 13:20:14.623] ERROR [Druid-ConnectionPool-Create-497208183] DruidDataSource.java:2471 - ...

  8. 忘了 iOS(iPad、IPhone) 设备上的「屏幕使用时间」密码怎么办?找回屏幕密码

    忘了 iOS(iPad.IPhone) 设备上的「屏幕使用时间」密码怎么办? 1. 用iTunes 进行备份[备份时一定要输入密码] 备份时C盘要有足够的空间 2. 下载 pinfinder.exe ...

  9. three.js项目引入vue,因代码编写不当导致的严重影响性能的问题,卡顿掉帧严重

    three.js项目引入vue,因代码编写不当导致的严重影响性能的问题,卡顿掉帧严重 问题排查 使用谷歌浏览器的Performance分析页面性能 可以看到vue.js的reactiveGetter方 ...

  10. 它来了!真正的 python 多线程

    哈喽大家好,我是咸鱼 几天前,IBM 工程师 Martin Heinz 发文表示 python 3.12 版本回引入"Per-Interpreter GIL",有了这个 Per-I ...