From 083f42ca51f59fae5e05374a43cbe3f50ecd0dc5 Mon Sep 17 00:00:00 2001 From: peignerpausz Date: Wed, 16 Sep 2026 17:52:06 +0200 Subject: [PATCH 1/2] Added sslchecker.sh to domaintools --- README.md | 16 +++- domaintools/README.md | 3 + domaintools/sslchecker/README.md | 101 +++++++++++++++++++++++ domaintools/sslchecker/sslchecker.sh | 115 +++++++++++++++++++++++++++ 4 files changed, 233 insertions(+), 2 deletions(-) create mode 100644 domaintools/sslchecker/README.md create mode 100644 domaintools/sslchecker/sslchecker.sh diff --git a/README.md b/README.md index 99f647a..d86b8a2 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,8 @@ Optimierte Bash-Konfigurationen für verschiedene Support-Umgebungen: Tool zur `dig`-Massenabfrage von Domains und DNS-Records. - [`histodomain`](./domaintools/histodomain/README.md) Abfrage zu historischen DNS-Einträgen über die [Securitytrails-API](https://securitytrails.com). +- [`sslchecker`](./domaintools/sslchecker/README.md) + Tool zur schnellen SSL-Prüfung mehrerer Domains gleichzeitig. ## Legacy Snippets @@ -149,9 +151,10 @@ cd /pfad/zu/esn-support-tools Um ein neues Bash-Skript in dieses Repository aufzunehmen, bitte folgende Schritte: 1. **Ordnerstruktur anlegen** - Je nach Kategorie (`bashprofiles`, `legacy` oder `wh20`) einen Unterordner erstellen: + Je nach Kategorie (`bashprofiles`, `domaintools`, `legacy` oder `wh20`) einen Unterordner erstellen: ``` bashprofiles// + domaintools// legacy// wh20// ``` @@ -159,6 +162,10 @@ Um ein neues Bash-Skript in dieses Repository aufzunehmen, bitte folgende Schrit 2. **Skript hinzufügen** Das eigentliche Skript im neuen Ordner ablegen: ``` + domaintools// + ``` + oder + ``` legacy// ``` oder @@ -176,16 +183,21 @@ Um ein neues Bash-Skript in dieses Repository aufzunehmen, bitte folgende Schrit [README_template_script.md](./README_template.md) → kopieren, anpassen und ins Skript-Verzeichnis legen: ``` - legacy//README.md + domaintools//README.md ``` oder ``` + legacy//README.md + ``` + oder + ``` wh20//README.md ``` 4. **Übersicht aktualisieren** Das Skript in die Übersicht der passenden Kategorie-README eintragen: - [`bashprofiles/README.md`](./bashprofiles/README.md) + - [`domaintools/README.md`](./domaintools/README.md) - [`legacy/README.md`](./legacy/README.md) - [`wh20/README.md`](./wh20/README.md) diff --git a/domaintools/README.md b/domaintools/README.md index 1d5f396..411d7b7 100644 --- a/domaintools/README.md +++ b/domaintools/README.md @@ -31,6 +31,9 @@ Abfrage zu historischen DNS-Einträgen über die Securitytrails-API. - [Dokumentation & Beispiele](./histodomain/README.md) +### [`sslchecker`](./sslchecker/) +Tool zur schnellen SSL-Prüfung mehrerer Domains gleichzeitig. + --- ## Voraussetzungen diff --git a/domaintools/sslchecker/README.md b/domaintools/sslchecker/README.md new file mode 100644 index 0000000..c383f88 --- /dev/null +++ b/domaintools/sslchecker/README.md @@ -0,0 +1,101 @@ +# SSLChecker + +Skript zum schnellen Prüfen der Gültigkeit und des Typs von SSL-Certs + +--- + +## Features + +- Prüft Gültigkeit +- Prüft Typ (LE oder was anderes) +- Prüft Restgültigkeit des SSL-Certs + +--- + +## Installation + +1. Repository klonen oder Skript kopieren: + ```bash + git clone git.in.loki-net.at/esn-support-bash-snippets.git + cd esn-support-bash-snippets/domaintools/sslchecker + chmod +x sslchecker.sh + ``` + +2. Abhängigkeiten (falls vorhanden) installieren: + - `curl` + - `openssl` + - beide auf der connect vorinstalliert + +--- + +## Nutzung + +### Standardaufruf +```bash +./sslchecker.sh +``` + +### Beispiele +```bash +./sslchecker.sh -d domain1.tld domain2.tld domain3.tld -t le +``` + +--- + +## Optionen + +``` +Verwendung: + bash sslchecker.sh [OPTIONEN] + Oder interaktiv: bash sslchecker.sh + + Optionen: + -d, --domains DOMAIN [DOMAINS...] + Zu prüfende Domains + -t, --type Typ + Prüft gegen erwarteten Issuer, etwa Let's Encrypt, Sectigo oder GlobalSign + -h, --help + Diese Hilfe anzeigen +``` + +--- + +## Beispielausgabe + +``` +bash sslchecker.sh -d ironsites.at myrealis.at orf.at -t le + ++++SSLCHECKER v0.1+++ + +====== ironsites.at ========= +OK valid SSL +OK SSL-Zertifikat gültig bis Nov 1 23:23:54 2026 GMT (46 Tage verbleibend) +OK Cert ist von Let's Encrypt + +====== myrealis.at ========= +OK valid SSL +OK SSL-Zertifikat gültig bis Nov 5 07:16:41 2026 GMT (49 Tage verbleibend) +OK Cert ist von Let's Encrypt + +====== orf.at ========= +OK valid SSL +OK SSL-Zertifikat gültig bis Jan 3 08:17:00 2027 GMT (108 Tage verbleibend) +X Cert ist nicht von Let's Encrypt (gefunden: GlobalSign nv-sa) +``` + +--- + +## Setup-Hinweise + +Falls notwendig, Alias in `~/.bashrc` setzen: +```bash +alias sslchecker='~/esn-support-tools/domaintools/sslchecker/sslchecker.sh' +``` +--- + +## Notes + +- To-Do: + Timeouts abfangen + eventuell Umbau auf `openssl` statt `curl` + Optionen ausbauen diff --git a/domaintools/sslchecker/sslchecker.sh b/domaintools/sslchecker/sslchecker.sh new file mode 100644 index 0000000..f43db30 --- /dev/null +++ b/domaintools/sslchecker/sslchecker.sh @@ -0,0 +1,115 @@ +#! /bin/usr/env bash +# Tool zum Prüfen von SSL-Gültigkeit mehrer Domains +# Maintainer: peignerpausz + +set -eo pipefail +RED="\033[31m" +GREEN="\033[32m" +YELLOW="\033[33m" +RESET="\033[0m" +declare -a DOMAINS + +usage() { + cat <&1 | grep -F "SSL certificate verify ok") + EXPIRE=$(echo | openssl s_client -connect $domain:443 -servername $domain 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2) + TYPE=$(echo | openssl s_client -connect "$domain:443" -servername "$domain" 2>/dev/null \ + | openssl x509 -noout -issuer \ + | grep -o 'O *= *[^,]*' \ + | sed 's/O *= *//') + expire_ts=$(date -d "$EXPIRE" +%s) + now_ts=$(date +%s) + days_left=$(((expire_ts - now_ts) / 86400)) + if [[ -n "$VALIDITY" ]]; then + printf "${GREEN}OK${RESET} valid SSL\n" + else + printf "${RED}X${RESET} not valid SSL\n" + fi + if [ "$days_left" -lt 30 ]; then + printf "${YELLOW}WARNING${RESET} SSL-Zertifikat läuft in $days_left Tagen ab ($EXPIRE)\n" + elif [ "$days_left" -lt 7 ]; then + printf "${RED}X${RESET} Zertifikat läuft in %d Tagen ab (%s)\n" "$days_left" "$EXPIRE" + else + printf "${GREEN}OK${RESET} SSL-Zertifikat gültig bis $EXPIRE ($days_left Tage verbleibend)\n" + fi + + if [[ "$TYPE" == *"$EXPECTED_ISSUER"* ]]; then + printf "${GREEN}OK${RESET} Cert ist von %s" "$EXPECTED_ISSUER" + else + printf "${YELLOW}X${RESET} Cert ist nicht von %s (gefunden: %s)" "$EXPECTED_ISSUER" "$TYPE" + fi + printf "\n" +done -- 2.54.0 From e0df6c54050ecc9b515cd90742f0a3c8b4d0e571 Mon Sep 17 00:00:00 2001 From: peignerpausz Date: Thu, 24 Sep 2026 16:53:51 +0200 Subject: [PATCH 2/2] Repair an inconsistancy within sslchecker. Now it works both interactively as well as directly via cli --- domaintools/sslchecker/sslchecker.sh | 106 ++++++++++++++------------- 1 file changed, 55 insertions(+), 51 deletions(-) diff --git a/domaintools/sslchecker/sslchecker.sh b/domaintools/sslchecker/sslchecker.sh index f43db30..0282e2e 100644 --- a/domaintools/sslchecker/sslchecker.sh +++ b/domaintools/sslchecker/sslchecker.sh @@ -1,8 +1,8 @@ -#! /bin/usr/env bash +#!/usr/bin/env bash # Tool zum Prüfen von SSL-Gültigkeit mehrer Domains # Maintainer: peignerpausz -set -eo pipefail +set -o pipefail RED="\033[31m" GREEN="\033[32m" YELLOW="\033[33m" @@ -32,64 +32,63 @@ USAGE while [[ $# -gt 0 ]]; do case "$1" in - -d|--domains) + -d | --domains) + shift + while [[ $# -gt 0 && "$1" != -* ]]; do + DOMAINS+=("$1") shift - while [[ $# -gt 0 && "$1" != -* ]]; do - DOMAINS+=("$1") - shift - done - ;; - - -t|--type) - TYPE="$2" + done + ;; - case "$TYPE" in - le) - EXPECTED_ISSUER="Let's Encrypt" - ;; - digicert) - EXPECTED_ISSUER="DigiCert" - ;; - sectigo) - EXPECTED_ISSUER="Sectigo" - ;; - global) - EXPECTED_ISSUER="GlobalSign" - ;; - *) - echo "Fehler: Ungültiger Typ '$TYPE'" - echo "Erlaubte Werte: le, digicert, sectigo, global" - exit 1 - ;; - esac + -t | --type) + ISSUER="$2" - shift 2 + case "$ISSUER" in + le) + EXPECTED_ISSUER="Let's Encrypt" ;; - - -h|--help) - usage - exit 0 + digicert) + EXPECTED_ISSUER="DigiCert" + ;; + sectigo) + EXPECTED_ISSUER="Sectigo" + ;; + global) + EXPECTED_ISSUER="GlobalSign" ;; - *) - echo "Unbekannte Option: $1" - usage + echo "Fehler: Ungültiger Typ '$ISSUER'" + echo "Erlaubte Werte: le, digicert, sectigo, global" exit 1 ;; + esac + + shift 2 + ;; + + -h | --help) + usage + exit 0 + ;; + + *) + echo "Unbekannte Option: $1" + usage + exit 1 + ;; esac done printf "+++SSLCHECKER v0.1+++\n" [[ ${#DOMAINS[@]} -eq 0 ]] && read -ra DOMAINS -p "Welche Domains sollen gesucht werden? " DOMAINS - for domain in "${DOMAINS[@]}"; do printf "\n========= %s =========\n" "$domain" VALIDITY=$(curl -vI https://$domain 2>&1 | grep -F "SSL certificate verify ok") EXPIRE=$(echo | openssl s_client -connect $domain:443 -servername $domain 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2) - TYPE=$(echo | openssl s_client -connect "$domain:443" -servername "$domain" 2>/dev/null \ - | openssl x509 -noout -issuer \ - | grep -o 'O *= *[^,]*' \ - | sed 's/O *= *//') + ISSUER=$(echo | openssl s_client -connect "$domain:443" -servername "$domain" 2>/dev/null | + openssl x509 -noout -issuer | + grep -o 'O *= *[^,]*' | + sed 's/O *= *//') expire_ts=$(date -d "$EXPIRE" +%s) now_ts=$(date +%s) days_left=$(((expire_ts - now_ts) / 86400)) @@ -98,18 +97,23 @@ for domain in "${DOMAINS[@]}"; do else printf "${RED}X${RESET} not valid SSL\n" fi - if [ "$days_left" -lt 30 ]; then - printf "${YELLOW}WARNING${RESET} SSL-Zertifikat läuft in $days_left Tagen ab ($EXPIRE)\n" + if [ "$days_left" -lt 0 ]; then + printf "${RED}CRITICAL${RESET} Zertifikat ist seit %d Tagen abgelaufen (%s)\n" "$((-days_left))" "$EXPIRE" elif [ "$days_left" -lt 7 ]; then - printf "${RED}X${RESET} Zertifikat läuft in %d Tagen ab (%s)\n" "$days_left" "$EXPIRE" + printf "${RED}CRITICAL${RESET} Zertifikat läuft in %d Tagen ab (%s)\n" "$days_left" "$EXPIRE" + elif [ "$days_left" -lt 30 ]; then + printf "${YELLOW}WARNING${RESET} SSL-Zertifikat läuft in $days_left Tagen ab ($EXPIRE)\n" else printf "${GREEN}OK${RESET} SSL-Zertifikat gültig bis $EXPIRE ($days_left Tage verbleibend)\n" - fi - - if [[ "$TYPE" == *"$EXPECTED_ISSUER"* ]]; then - printf "${GREEN}OK${RESET} Cert ist von %s" "$EXPECTED_ISSUER" + fi + if [[ -n $EXPECTED_ISSUER ]]; then + if [[ "$ISSUER" == *"$EXPECTED_ISSUER"* ]]; then + printf "${GREEN}OK${RESET} Cert ist von %s" "$EXPECTED_ISSUER" + else + printf "${YELLOW}X${RESET} Cert ist nicht von %s (gefunden: %s)" "$EXPECTED_ISSUER" "$ISSUER" + fi else - printf "${YELLOW}X${RESET} Cert ist nicht von %s (gefunden: %s)" "$EXPECTED_ISSUER" "$TYPE" + printf "${GREEN}INFO${RESET} Cert-Aussteller: %s" "$ISSUER" fi printf "\n" done -- 2.54.0