Mike Gerwitz

Activist for User Freedom

aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Gerwitz <mtg@gnu.org>2021-06-15 22:57:20 -0400
committerMike Gerwitz <mtg@gnu.org>2021-06-15 23:19:24 -0400
commit3142db006a3cdf6b7a95eb94f7428e5f4cd5fbd5 (patch)
tree7bd025a000281edb240c58e83c755ac3b313f39c
parent9c7961bb5c5f7a5a05d8cc981f22daffedd264c4 (diff)
downloadpromscripts-3142db006a3cdf6b7a95eb94f7428e5f4cd5fbd5.tar.gz
promscripts-3142db006a3cdf6b7a95eb94f7428e5f4cd5fbd5.tar.bz2
promscripts-3142db006a3cdf6b7a95eb94f7428e5f4cd5fbd5.zip
x509/expiry: Add script
-rw-r--r--README.md3
-rw-r--r--x509/expiry/README.md33
-rwxr-xr-xx509/expiry/metrics74
3 files changed, 109 insertions, 1 deletions
diff --git a/README.md b/README.md
index bde4726..9861d6f 100644
--- a/README.md
+++ b/README.md
@@ -18,4 +18,5 @@ These scripts are intended to be used with the textfile exporter of
## Available Metrics
- [Printers](./printer/)
- [Epson ET-2720](./printer/epson/et-2720)
-
+- [X.509](./x509/)
+ - [expiry](./x509/expiry/)
diff --git a/x509/expiry/README.md b/x509/expiry/README.md
new file mode 100644
index 0000000..0fe5798
--- /dev/null
+++ b/x509/expiry/README.md
@@ -0,0 +1,33 @@
+X.509 Certificate Expiry Metrics
+================================
+
+This script simply retrieves a X.509 certificate from a given host and port
+using OpenSSL and returns the number of seconds from the current time until
+it expires (is no longer valid).
+
+This script produces the following metrics:
+
+ - `x509_expire_seconds` with the number of seconds until the certificate
+ reaches its "not after" date, where a value of `0` means that it will
+ expire the next second;
+ - `x509_expire_success` holding `1` if OpenSSL succeeded retrieving and
+ parsing the certificate, otherwise `0`; and
+ - `x509_expire_scrape_duration_seconds` containing the number of seconds
+ that it took to produce `x509_expire_seconds`.
+
+
+How To Use
+----------
+Provide the intended host and port number. Note that there is no parameter
+for SNI, since I didn't need it.
+
+```sh
+# Generate metrics
+$ ./metrics HOST PORT > expiry.$$
+
+# Atomic move to avoid Prometheus reading incomplete writes
+$ mv expiry.$$ expiry.prom
+```
+
+_Warning:_ This script assumes trusted inputs and does not escape the
+hostname in label value output.
diff --git a/x509/expiry/metrics b/x509/expiry/metrics
new file mode 100755
index 0000000..5119e44
--- /dev/null
+++ b/x509/expiry/metrics
@@ -0,0 +1,74 @@
+#!/bin/bash
+# Retrieve X.509 certificate expiry information for a given host and port
+#
+# Copyright (C) 2021 Mike Gerwitz
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# This will produce `x509_expire_seconds`, `x509_expire_success`, and
+#`x509_expire_scrape_duration_seconds`.
+#
+# WARNING: This script assumes trusted input and does not perform escaping
+# of label values.
+
+set -uo pipefail
+
+cd "$(dirname "$0")"
+
+
+main()
+{
+ local host="${1?Missing domain}"
+ local -i port="${2?Missing port}"
+
+ local -ri start=$(date +%s)
+
+ local expire_date expire_ts=0 ok=0
+ expire_date=$( openssl s_client -showcerts \
+ -connect "$host":"$port" \
+ 2>/dev/null \
+ </dev/null \
+ | openssl x509 -noout -dates \
+ | grep ^notAfter \
+ | cut -d= -f2 )
+ ok=$(( PIPESTATUS[0] == 0 ))
+
+ (( ok == 1 )) && expire_ts=$( date --date="$expire_date" +%s )
+ local -i expire_in=$(( expire_ts - EPOCHSECONDS ))
+
+ local -ri end=$(date +%s)
+ local -ri duration=$(( end - start ))
+
+ # Note that this does not perform any escaping; it assumes trusted input.
+ local labels=$( printf 'domain="%s", port="%d"' "$host" "$port" )
+
+ if [[ "$ok" == 1 ]]; then
+ echo -n '# HELP x509_expire_seconds '
+ echo 'Number of seconds until X.509 certificate reaches its "not after" date.'
+ echo '# TYPE x509_expire_seconds gauge'
+ printf 'x509_expire_seconds{%s} %d\n' "$labels" "$expire_in"
+ fi
+
+ echo -n '# HELP x509_expire_success '
+ echo 'Whether the certificate was successfully retrieved and parsed.'
+ echo '# TYPE x509_expire_success gauge'
+ printf 'x509_expire_success{%s} %d\n' "$labels" "$ok"
+
+ echo -n '# HELP x509_expire_scrape_duration_seconds '
+ echo 'Number of seconds spent retrieving and parsing certificate expiry data.'
+ echo '# TYPE x509_expire_scrape_duration_seconds gauge'
+ printf 'x509_expire_scrape_duration_seconds{%s} %d\n' "$labels" "$duration"
+}
+
+main "$@"