Sync all scripts from website downloads — 352 scripts total
Includes updated JS challenge scripts with Claude-User whitelist, same-site referer bypass, Blackbox-Exporter allowed bot, and all new exporters, cheat sheets, and automation scripts.
This commit is contained in:
@@ -0,0 +1,368 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#########################################################################################
|
||||
#### ssl-cert-checker.sh — Check SSL certificate expiry across multiple endpoints ####
|
||||
#### Reads hosts from CLI args, a file, or stdin and reports days remaining ####
|
||||
#### ####
|
||||
#### Author: Phil Connor ####
|
||||
#### Contact: contact@mylinux.work ####
|
||||
#### License: MIT ####
|
||||
#### Version 1.00 ####
|
||||
#### ####
|
||||
#### Usage: ####
|
||||
#### ./ssl-cert-checker.sh example.com google.com:443 ####
|
||||
#### ./ssl-cert-checker.sh --file hosts.txt ####
|
||||
#### echo "example.com" | ./ssl-cert-checker.sh ####
|
||||
#### ####
|
||||
#### See --help for all options. ####
|
||||
#########################################################################################
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ── Defaults ──────────────────────────────────────────────────────────
|
||||
CERT_CHECK_TIMEOUT="${CERT_CHECK_TIMEOUT:-5}"
|
||||
WARN_DAYS="${WARN_DAYS:-30}"
|
||||
CRIT_DAYS="${CRIT_DAYS:-7}"
|
||||
VERBOSE="${VERBOSE:-false}"
|
||||
COLOR="${COLOR:-auto}"
|
||||
JSON_OUTPUT="${JSON_OUTPUT:-false}"
|
||||
HOST_FILE=""
|
||||
|
||||
# ── State ─────────────────────────────────────────────────────────────
|
||||
SCRIPT_NAME="$(basename "$0")"
|
||||
readonly SCRIPT_NAME
|
||||
HOSTS=()
|
||||
COUNT_OK=0
|
||||
COUNT_WARN=0
|
||||
COUNT_CRIT=0
|
||||
COUNT_EXPIRED=0
|
||||
COUNT_ERROR=0
|
||||
COUNT_TOTAL=0
|
||||
JSON_RESULTS=()
|
||||
|
||||
# ── Colors ────────────────────────────────────────────────────────────
|
||||
setup_colors() {
|
||||
if [[ "$COLOR" == "never" ]]; then
|
||||
RED="" GREEN="" YELLOW="" CYAN="" BOLD="" DIM="" RESET=""
|
||||
return
|
||||
fi
|
||||
if [[ "$COLOR" == "always" ]] || [[ -t 1 ]]; then
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[0;33m'
|
||||
CYAN='\033[0;36m'
|
||||
BOLD='\033[1m'
|
||||
DIM='\033[2m'
|
||||
RESET='\033[0m'
|
||||
else
|
||||
RED="" GREEN="" YELLOW="" CYAN="" BOLD="" DIM="" RESET=""
|
||||
fi
|
||||
}
|
||||
|
||||
# ── Logging ───────────────────────────────────────────────────────────
|
||||
log() { echo -e "${CYAN}[INFO]${RESET} $*"; }
|
||||
warn() { echo -e "${YELLOW}[WARN]${RESET} $*" >&2; }
|
||||
err() { echo -e "${RED}[ERROR]${RESET} $*" >&2; }
|
||||
verbose() { if [[ "$VERBOSE" == "true" ]]; then echo -e "${DIM}[DEBUG]${RESET} $*"; fi; }
|
||||
|
||||
# ── Helpers ───────────────────────────────────────────────────────────
|
||||
section_header() {
|
||||
echo ""
|
||||
echo -e " ${BOLD}${CYAN}── $1 ──${RESET}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
field() {
|
||||
printf " ${BOLD}%-22s${RESET} %s\n" "$1" "$2"
|
||||
}
|
||||
|
||||
field_color() {
|
||||
printf " ${BOLD}%-22s${RESET} %b\n" "$1" "$2"
|
||||
}
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
# CERTIFICATE CHECK
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
|
||||
check_cert() {
|
||||
local host="$1"
|
||||
local port="$2"
|
||||
|
||||
verbose "Connecting to ${host}:${port} (timeout ${CERT_CHECK_TIMEOUT}s)"
|
||||
|
||||
local cert_output
|
||||
if ! cert_output=$(openssl s_client -servername "$host" -connect "${host}:${port}" 2>/dev/null <<< "" | openssl x509 -noout -subject -issuer -dates 2>/dev/null); then
|
||||
err "Failed to retrieve certificate from ${host}:${port}"
|
||||
COUNT_ERROR=$((COUNT_ERROR + 1))
|
||||
if [[ "$JSON_OUTPUT" == "true" ]]; then
|
||||
JSON_RESULTS+=("{\"host\":\"${host}\",\"port\":${port},\"status\":\"ERROR\",\"error\":\"connection failed\"}")
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
local subject issuer not_after
|
||||
subject=$(echo "$cert_output" | grep "^subject=" | sed 's/^subject=//')
|
||||
issuer=$(echo "$cert_output" | grep "^issuer=" | sed 's/^issuer=//')
|
||||
not_after=$(echo "$cert_output" | grep "^notAfter=" | sed 's/^notAfter=//')
|
||||
|
||||
if [[ -z "$not_after" ]]; then
|
||||
err "Could not parse certificate dates for ${host}:${port}"
|
||||
COUNT_ERROR=$((COUNT_ERROR + 1))
|
||||
return
|
||||
fi
|
||||
|
||||
local expiry_epoch now_epoch days_remaining
|
||||
expiry_epoch=$(date -d "$not_after" +%s 2>/dev/null)
|
||||
now_epoch=$(date +%s)
|
||||
days_remaining=$(( (expiry_epoch - now_epoch) / 86400 ))
|
||||
|
||||
local status color
|
||||
if [[ "$days_remaining" -lt 0 ]]; then
|
||||
status="EXPIRED"
|
||||
color="$RED"
|
||||
COUNT_EXPIRED=$((COUNT_EXPIRED + 1))
|
||||
elif [[ "$days_remaining" -le "$CRIT_DAYS" ]]; then
|
||||
status="CRITICAL"
|
||||
color="$RED"
|
||||
COUNT_CRIT=$((COUNT_CRIT + 1))
|
||||
elif [[ "$days_remaining" -le "$WARN_DAYS" ]]; then
|
||||
status="WARNING"
|
||||
color="$YELLOW"
|
||||
COUNT_WARN=$((COUNT_WARN + 1))
|
||||
else
|
||||
status="OK"
|
||||
color="$GREEN"
|
||||
COUNT_OK=$((COUNT_OK + 1))
|
||||
fi
|
||||
|
||||
if [[ "$JSON_OUTPUT" == "true" ]]; then
|
||||
# Escape double quotes in subject/issuer for JSON
|
||||
local json_subject json_issuer
|
||||
json_subject="${subject//\"/\\\"}"
|
||||
json_issuer="${issuer//\"/\\\"}"
|
||||
JSON_RESULTS+=("{\"host\":\"${host}\",\"port\":${port},\"subject\":\"${json_subject}\",\"issuer\":\"${json_issuer}\",\"expiry\":\"${not_after}\",\"days_remaining\":${days_remaining},\"status\":\"${status}\"}")
|
||||
else
|
||||
echo ""
|
||||
field "Host:" "${host}:${port}"
|
||||
field "Subject:" "$subject"
|
||||
field "Issuer:" "$issuer"
|
||||
field "Expiry:" "$not_after"
|
||||
field_color "Days remaining:" "${color}${days_remaining}${RESET}"
|
||||
field_color "Status:" "${color}${status}${RESET}"
|
||||
fi
|
||||
}
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
# INPUT PARSING
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
|
||||
parse_host() {
|
||||
local entry="$1"
|
||||
local host port
|
||||
|
||||
# Strip whitespace and skip empty/comment lines
|
||||
entry=$(echo "$entry" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||
[[ -z "$entry" || "$entry" == \#* ]] && return
|
||||
|
||||
if [[ "$entry" == *:* ]]; then
|
||||
host="${entry%%:*}"
|
||||
port="${entry##*:}"
|
||||
else
|
||||
host="$entry"
|
||||
port="443"
|
||||
fi
|
||||
|
||||
HOSTS+=("${host}:${port}")
|
||||
}
|
||||
|
||||
load_hosts_from_file() {
|
||||
local file="$1"
|
||||
if [[ ! -f "$file" ]]; then
|
||||
err "File not found: $file"
|
||||
exit 1
|
||||
fi
|
||||
while IFS= read -r line; do
|
||||
parse_host "$line"
|
||||
done < "$file"
|
||||
}
|
||||
|
||||
load_hosts_from_stdin() {
|
||||
while IFS= read -r line; do
|
||||
parse_host "$line"
|
||||
done
|
||||
}
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
# USAGE
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
${SCRIPT_NAME} — Check SSL certificate expiry across multiple endpoints
|
||||
|
||||
USAGE:
|
||||
${SCRIPT_NAME} [OPTIONS] [HOST[:PORT] ...]
|
||||
${SCRIPT_NAME} --file hosts.txt
|
||||
echo "example.com" | ${SCRIPT_NAME}
|
||||
|
||||
OPTIONS:
|
||||
--file FILE Read hosts from file (one host:port per line)
|
||||
--warn-days N Warning threshold in days (default: ${WARN_DAYS})
|
||||
--crit-days N Critical threshold in days (default: ${CRIT_DAYS})
|
||||
--json Output results as JSON
|
||||
--verbose Enable debug output
|
||||
--no-color Disable colored output
|
||||
--help Show this help
|
||||
|
||||
ENVIRONMENT VARIABLES:
|
||||
CERT_CHECK_TIMEOUT Connection timeout in seconds (default: 5)
|
||||
WARN_DAYS Warning threshold (default: 30)
|
||||
CRIT_DAYS Critical threshold (default: 7)
|
||||
|
||||
EXAMPLES:
|
||||
# Check a single host
|
||||
./ssl-cert-checker.sh example.com
|
||||
|
||||
# Check multiple hosts with custom port
|
||||
./ssl-cert-checker.sh example.com:443 mail.example.com:993
|
||||
|
||||
# Check from a file
|
||||
./ssl-cert-checker.sh --file hosts.txt
|
||||
|
||||
# JSON output with custom thresholds
|
||||
./ssl-cert-checker.sh --json --warn-days 60 --crit-days 14 example.com
|
||||
EOF
|
||||
}
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
# ARGUMENT PARSING
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
|
||||
parse_args() {
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--file)
|
||||
HOST_FILE="$2"; shift 2 ;;
|
||||
--warn-days)
|
||||
WARN_DAYS="$2"; shift 2 ;;
|
||||
--crit-days)
|
||||
CRIT_DAYS="$2"; shift 2 ;;
|
||||
--json)
|
||||
JSON_OUTPUT="true"; shift ;;
|
||||
--verbose)
|
||||
VERBOSE="true"; shift ;;
|
||||
--no-color)
|
||||
COLOR="never"; shift ;;
|
||||
--help|-h)
|
||||
setup_colors
|
||||
usage
|
||||
exit 0 ;;
|
||||
-*)
|
||||
err "Unknown option: $1"
|
||||
echo "Run ${SCRIPT_NAME} --help for usage" >&2
|
||||
exit 1 ;;
|
||||
*)
|
||||
parse_host "$1"; shift ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
# MAIN
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
|
||||
main() {
|
||||
parse_args "$@"
|
||||
setup_colors
|
||||
|
||||
# Require openssl
|
||||
if ! command -v openssl &>/dev/null; then
|
||||
err "openssl is required but not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Load hosts from file if specified
|
||||
if [[ -n "$HOST_FILE" ]]; then
|
||||
load_hosts_from_file "$HOST_FILE"
|
||||
fi
|
||||
|
||||
# Load from stdin if no hosts yet and stdin is not a terminal
|
||||
if [[ ${#HOSTS[@]} -eq 0 ]] && ! [[ -t 0 ]]; then
|
||||
load_hosts_from_stdin
|
||||
fi
|
||||
|
||||
if [[ ${#HOSTS[@]} -eq 0 ]]; then
|
||||
err "No hosts specified"
|
||||
echo "Run ${SCRIPT_NAME} --help for usage" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
COUNT_TOTAL=${#HOSTS[@]}
|
||||
|
||||
if [[ "$JSON_OUTPUT" != "true" ]]; then
|
||||
echo ""
|
||||
echo -e "${BOLD}SSL Certificate Check${RESET}"
|
||||
echo -e "${DIM}$(date '+%Y-%m-%d %H:%M:%S %Z')${RESET}"
|
||||
echo -e "${DIM}Thresholds: warn=${WARN_DAYS}d, crit=${CRIT_DAYS}d, timeout=${CERT_CHECK_TIMEOUT}s${RESET}"
|
||||
section_header "Certificates"
|
||||
fi
|
||||
|
||||
for entry in "${HOSTS[@]}"; do
|
||||
local host port
|
||||
host="${entry%%:*}"
|
||||
port="${entry##*:}"
|
||||
check_cert "$host" "$port"
|
||||
done
|
||||
|
||||
if [[ "$JSON_OUTPUT" == "true" ]]; then
|
||||
echo "{"
|
||||
echo " \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\","
|
||||
echo " \"summary\": {"
|
||||
echo " \"total\": ${COUNT_TOTAL},"
|
||||
echo " \"ok\": ${COUNT_OK},"
|
||||
echo " \"warning\": ${COUNT_WARN},"
|
||||
echo " \"critical\": ${COUNT_CRIT},"
|
||||
echo " \"expired\": ${COUNT_EXPIRED},"
|
||||
echo " \"error\": ${COUNT_ERROR}"
|
||||
echo " },"
|
||||
echo " \"results\": ["
|
||||
local i=0
|
||||
for result in "${JSON_RESULTS[@]}"; do
|
||||
i=$((i + 1))
|
||||
if [[ $i -lt ${#JSON_RESULTS[@]} ]]; then
|
||||
echo " ${result},"
|
||||
else
|
||||
echo " ${result}"
|
||||
fi
|
||||
done
|
||||
echo " ]"
|
||||
echo "}"
|
||||
else
|
||||
section_header "Summary"
|
||||
field "Total checked:" "$COUNT_TOTAL"
|
||||
field_color "OK:" "${GREEN}${COUNT_OK}${RESET}"
|
||||
if [[ "$COUNT_WARN" -gt 0 ]]; then
|
||||
field_color "Warning:" "${YELLOW}${COUNT_WARN}${RESET}"
|
||||
else
|
||||
field "Warning:" "$COUNT_WARN"
|
||||
fi
|
||||
if [[ "$COUNT_CRIT" -gt 0 ]]; then
|
||||
field_color "Critical:" "${RED}${COUNT_CRIT}${RESET}"
|
||||
else
|
||||
field "Critical:" "$COUNT_CRIT"
|
||||
fi
|
||||
if [[ "$COUNT_EXPIRED" -gt 0 ]]; then
|
||||
field_color "Expired:" "${RED}${COUNT_EXPIRED}${RESET}"
|
||||
else
|
||||
field "Expired:" "$COUNT_EXPIRED"
|
||||
fi
|
||||
if [[ "$COUNT_ERROR" -gt 0 ]]; then
|
||||
field_color "Errors:" "${RED}${COUNT_ERROR}${RESET}"
|
||||
else
|
||||
field "Errors:" "$COUNT_ERROR"
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user