From 4d6bb59fdef28e28d0acea05098efedab7eca60d Mon Sep 17 00:00:00 2001 From: pljubeko Date: Tue, 9 Sep 2025 15:03:15 +0200 Subject: [PATCH] checkms.sh first commit --- legacy/checkms/checkms.sh | 249 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 legacy/checkms/checkms.sh diff --git a/legacy/checkms/checkms.sh b/legacy/checkms/checkms.sh new file mode 100644 index 0000000..266762f --- /dev/null +++ b/legacy/checkms/checkms.sh @@ -0,0 +1,249 @@ +#!/usr/bin/env bash +# checkms - Analyse von MS-Fehlercodes im Exim-Log + Code-Management + +set -euo pipefail + +# --- Defaults --- +DATE="$(date +%Y-%m-%d)" +MINUTES=0 +HOURS=0 +CONF_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/checkms" +ADD_CODES=() +DEL_INDEXES=() +SET_USER="" +SHOW_CONF=0 + +# --- Funktionen --- +usage() { + cat <"$CONF_FILE" </dev/null 2>&1; then + echo "Fehler: Für --add-code/--del-code/--set-user wird 'jq' benötigt." >&2 + exit 1 + fi +} + +show_config() { + if [[ ! -f "$CONF_FILE" ]]; then + echo "Keine Config vorhanden. Sie wird beim nächsten Run erstellt." + exit 0 + fi + + # Roh-JSON + if command -v jq >/dev/null 2>&1; then + echo "RAW ($CONF_FILE):" + jq . "$CONF_FILE" + else + echo "RAW ($CONF_FILE):" + cat "$CONF_FILE" + fi + echo + + # Tabellarisch + if command -v jq >/dev/null 2>&1; then + SSH_USER_SHOW="$(jq -r '.ssh_user' "$CONF_FILE")" + mapfile -t CODES_SHOW < <(jq -r '.codes[]' "$CONF_FILE") + else + SSH_USER_SHOW="$(grep -o '"ssh_user":[^,}]*' "$CONF_FILE" | cut -d'"' -f4)" + CODES_LINE="$(sed -n 's/.*"codes":[[]\(.*\)[]].*/\1/p' "$CONF_FILE")" + IFS=',' read -r -a CODES_SHOW <<<"$(echo "$CODES_LINE" | tr -d ' \t"')" + fi + + echo "TABELLARISCHE ANSICHT:" + printf "%-12s %s\n" "SSH_USER" "${SSH_USER_SHOW:-}" + echo + printf "%-6s %s\n" "ID" "CODE" + printf "%-6s %s\n" "----" "-----------------------" + id=0 + for code in "${CODES_SHOW[@]}"; do + printf "%-6s %s\n" "$id" "$code" + id=$((id+1)) + done + exit 0 +} + +apply_add_codes() { + [[ ${#ADD_CODES[@]} -eq 0 ]] && return 0 + require_jq_write + local tmp; tmp="$(mktemp)" + cp "$CONF_FILE" "$tmp" + for code in "${ADD_CODES[@]}"; do + jq --arg code "$code" ' + (.codes | any(. == $code)) as $exists + | if $exists then . else (.codes += [$code]) end + ' "$tmp" > "${tmp}.new" + mv "${tmp}.new" "$tmp" + done + mv "$tmp" "$CONF_FILE" +} + +apply_del_indexes() { + [[ ${#DEL_INDEXES[@]} -eq 0 ]] && return 0 + require_jq_write + local tmp; tmp="$(mktemp)" + cp "$CONF_FILE" "$tmp" + IFS=$'\n' read -r -d '' -a sorted <<<"$(printf "%s\n" "${DEL_INDEXES[@]}" | sort -rn; printf '\0')" + for idx in "${sorted[@]}"; do + [[ "$idx" =~ ^[0-9]+$ ]] || { echo "Warnung: ungültige ID '$idx'"; continue; } + jq --argjson i "$idx" ' + if ($i >= 0 and $i < (.codes|length)) + then .codes |= del(.[$i]) + else . + end + ' "$tmp" > "${tmp}.new" + mv "${tmp}.new" "$tmp" + done + mv "$tmp" "$CONF_FILE" +} + +apply_set_user() { + [[ -z "$SET_USER" ]] && return 0 + require_jq_write + local tmp; tmp="$(mktemp)" + jq --arg u "$SET_USER" '.ssh_user = $u' "$CONF_FILE" > "$tmp" + mv "$tmp" "$CONF_FILE" +} + +# --- Argumente parsen --- +while [[ $# -gt 0 ]]; do + case "$1" in + --minutes) MINUTES="$2"; shift 2 ;; + --hours) HOURS="$2"; shift 2 ;; + --confdir) CONF_DIR="$2"; shift 2 ;; + --show-config) SHOW_CONF=1; shift ;; + --add-code) ADD_CODES+=("$2"); shift 2 ;; + --del-code) DEL_INDEXES+=("$2"); shift 2 ;; + --set-user) SET_USER="$2"; shift 2 ;; + --help) usage; exit 0 ;; + [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]) DATE="$1"; shift ;; + *) echo "Unbekannte Option: $1" >&2; usage; exit 1 ;; + esac +done + +# --- Configpfade --- +CONF_FILE="${CONF_DIR}/checkms.conf" +[[ -f "$CONF_FILE" ]] || init_conf + +# --- Reine Konfig-Operationen (frühzeitiger Exit!) --- +if [[ $SHOW_CONF -eq 1 && ${#ADD_CODES[@]} -eq 0 && ${#DEL_INDEXES[@]} -eq 0 && -z "$SET_USER" ]]; then + show_config +fi + +# Wenn Codes/User geändert werden sollen, erst anwenden … +if [[ ${#ADD_CODES[@]} -gt 0 || ${#DEL_INDEXES[@]} -gt 0 || -n "$SET_USER" ]]; then + apply_add_codes + apply_del_indexes + apply_set_user + # Wenn nur Konfig bearbeitet wurde (keine Analyse-Flags/Datum), hier enden + if [[ $MINUTES -eq 0 && $HOURS -eq 0 && "$DATE" == "$(date +%Y-%m-%d)" ]]; then + # Optional: danach anzeigen + [[ $SHOW_CONF -eq 1 ]] && show_config + exit 0 + fi +fi + +# --- Config laden für Analyse --- +if command -v jq >/dev/null 2>&1; then + SSH_USER="$(jq -r '.ssh_user' "$CONF_FILE")" + CODES_REGEX="$(jq -r '.codes[]' "$CONF_FILE" | paste -sd'|' -)" +else + SSH_USER="$(grep -o '"ssh_user":[^,}]*' "$CONF_FILE" | cut -d'"' -f4)" + CODES_REGEX="$( + sed -n 's/.*"codes":[[]\(.*\)[]].*/\1/p' "$CONF_FILE" \ + | tr -d ' \t"' | tr ',' '|' + )" +fi +[[ -n "${CODES_REGEX// }" ]] || CODES_REGEX="S3150|S775|S7771[0-9]*" + +LOGFILE="${DATE}.log" + +# --- Remote-Kommando --- +if type go >/dev/null 2>&1; then + REMOTE="go logger" +else + REMOTE="ssh ${SSH_USER}@logger.in.nessus.at" +fi + +# --- Analyse (remote) --- +$REMOTE bash -s <&2 + exit 1 + fi + + echo "Analysiere $LOGFILE" + echo + printf "%-8s %-16s %-8s\n" "COUNT" "IP" "CODE" + printf "%-8s %-16s %-8s\n" "-----" "----------------" "------" + + TF_CMD="" + if [ $MINUTES -gt 0 ]; then + START_TS=\$(date -d "-$MINUTES minutes" +"%b %_d %H:%M") + echo "Zeitraum: letzte $MINUTES Minuten (ab \$START_TS)" + TF_CMD="awk -v ts=\"\$START_TS\" '\$0 ~ ts,0'" + elif [ $HOURS -gt 0 ]; then + START_TS=\$(date -d "-$HOURS hours" +"%b %_d %H") + echo "Zeitraum: letzte $HOURS Stunden (ab \$START_TS)" + TF_CMD="awk -v ts=\"\$START_TS\" '\$0 ~ ts,0'" + fi + + eval \$SRC \${TF_CMD:+| \$TF_CMD} \ + | grep -E 'outlook|hotmail' \ + | grep -E "$CODES_REGEX" \ + | awk ' + { + code="NA"; ip="NA"; + for (i=1;i<=NF;i++) { + if (\$i ~ /\(S[0-9]+\)/) { t=\$i; gsub(/[()]/,"",t); code=t } + else if (\$i ~ /^S[0-9]+/) { code=\$i } + if (\$i ~ /^\[[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\]$/) { + ip=\$i; gsub(/[\[\]]/,"",ip) + } + } + print code, ip + } + ' \ + | sort | uniq -c | sort -nr \ + | while read count code ip; do + printf "%-8s %-16s %-8s\n" "\$count" "\$ip" "\$code" + done +EOF