PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
| Dir : /root/ |
| Server: Linux server62.dnsserverboot.com 6.8.1-1.el7.elrepo.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Mar 15 15:39:22 EDT 2024 x86_64 IP: 94.23.164.13 |
| Dir : //root/rsh-serverwide-ssl-audit.sh |
#!/bin/bash
set +e
export LC_ALL=C
BASE="/root/ssl-diagnostics"
mkdir -p "$BASE"
TS="$(date +%F-%H%M%S)"
REPORT="$BASE/serverwide-ssl-attention-$TS.log"
CSV_ALL="$BASE/serverwide-ssl-all-$TS.csv"
CSV_BAD="$BASE/serverwide-ssl-attention-only-$TS.csv"
RESOLVER="${RESOLVER:-8.8.8.8}"
SSL_TIMEOUT="${SSL_TIMEOUT:-8}"
DIG_TIMEOUT="${DIG_TIMEOUT:-2}"
exec > >(tee -a "$REPORT") 2>&1
echo
echo "===== REDSERVERHOST SERVER-WIDE SSL ATTENTION AUDIT START ====="
date
echo "REPORT=$REPORT"
echo "CSV_ALL=$CSV_ALL"
echo "CSV_BAD=$CSV_BAD"
echo "RESOLVER=$RESOLVER"
echo
echo "domain,user,cpanel_ip,public_a,public_aaaa,issuer,not_after,days_left,flags" > "$CSV_ALL"
echo "domain,user,cpanel_ip,public_a,public_aaaa,issuer,not_after,days_left,flags" > "$CSV_BAD"
SERVER_IPV4S="$(ip -4 addr | grep -oE 'inet [0-9.]+' | awk '{print $2}' | sort -u | tr '\n' ' ')"
SERVER_IPV6S="$(ip -6 addr | grep -oE 'inet6 [0-9a-fA-F:]+' | awk '{print $2}' | sort -u | tr '\n' ' ')"
echo "===== SERVER IPS ====="
echo "SERVER_IPV4S=$SERVER_IPV4S"
echo "SERVER_IPV6S=$SERVER_IPV6S"
echo
echo "===== WEB SERVER LISTENING ON 80/443 ====="
ss -lntp | egrep ':80 |:443 ' || true
echo
echo "===== HTTPD / LITESPEED STATUS ====="
systemctl is-active httpd 2>/dev/null || true
/usr/local/lsws/bin/lswsctrl status 2>&1 || true
echo
TOTAL=0
BAD=0
OK=0
get_userdata_value() {
local U="$1"
local D="$2"
local K="$3"
local F=""
for F in "/var/cpanel/userdata/$U/$D" "/var/cpanel/userdata/$U/${D}_SSL"; do
[ -f "$F" ] || continue
awk -F': ' -v key="$K" '$1==key {gsub(/^[ \t]+|[ \t]+$/,"",$2); print $2; exit}' "$F"
return
done
}
json_escape() {
sed 's/"/'\''/g'
}
check_cert_storage_selfsigned() {
local D="$1"
local F=""
for F in \
"/var/cpanel/ssl/apache_tls/$D/combined" \
"/var/cpanel/ssl/apache_tls/$D/certificates" \
"/var/cpanel/ssl/domain_tls/$D/combined" \
"/var/cpanel/ssl/domain_tls/$D/certificates" \
"/var/cpanel/ssl/domain_tls/www.$D/combined" \
"/var/cpanel/ssl/domain_tls/mail.$D/combined"
do
[ -f "$F" ] || continue
SUB="$(openssl x509 -in "$F" -noout -subject 2>/dev/null)"
ISS="$(openssl x509 -in "$F" -noout -issuer 2>/dev/null)"
if [ -n "$SUB" ] && [ "$SUB" = "$ISS" ]; then
echo "SELF_SIGNED_CPANEL_STORAGE:$F"
return
fi
done
}
live_cert_info() {
local D="$1"
local OUT="/tmp/rsh-ssl-live-$D-$TS.out"
local ERR="/tmp/rsh-ssl-live-$D-$TS.err"
timeout "$SSL_TIMEOUT" openssl s_client -connect "$D:443" -servername "$D" -showcerts </dev/null >"$OUT" 2>"$ERR"
if ! openssl x509 -in "$OUT" -noout -subject >/dev/null 2>&1; then
echo "FAILED||||||||"
return
fi
SUB="$(openssl x509 -in "$OUT" -noout -subject 2>/dev/null)"
ISS="$(openssl x509 -in "$OUT" -noout -issuer 2>/dev/null)"
END="$(openssl x509 -in "$OUT" -noout -enddate 2>/dev/null | cut -d= -f2-)"
FP="$(openssl x509 -in "$OUT" -noout -fingerprint -sha256 2>/dev/null | cut -d= -f2)"
HOSTCHECK="$(openssl x509 -in "$OUT" -noout -checkhost "$D" 2>/dev/null | grep -i "does match\|does NOT match" || true)"
END_EPOCH=""
DAYS_LEFT=""
if [ -n "$END" ]; then
END_EPOCH="$(date -d "$END" +%s 2>/dev/null)"
NOW_EPOCH="$(date +%s)"
if [ -n "$END_EPOCH" ]; then
DAYS_LEFT=$(( (END_EPOCH - NOW_EPOCH) / 86400 ))
fi
fi
echo "OK|$SUB|$ISS|$END|$DAYS_LEFT|$FP|$HOSTCHECK"
}
echo "===== COLLECTING DOMAINS FROM /etc/userdomains ====="
if [ ! -s /etc/userdomains ]; then
echo "ERROR: /etc/userdomains not found or empty."
exit 1
fi
awk -F: '{gsub(/^[ \t]+|[ \t]+$/,"",$1); gsub(/^[ \t]+|[ \t]+$/,"",$2); if ($1 != "" && $2 != "") print $1":"$2}' /etc/userdomains | sort -u | while IFS=: read -r D U; do
TOTAL=$((TOTAL+1))
FLAGS=""
[ -z "$D" ] && continue
[ -z "$U" ] && U="UNKNOWN"
CPIP="$(get_userdata_value "$U" "$D" "ip")"
DOCROOT="$(get_userdata_value "$U" "$D" "documentroot")"
if [ -z "$CPIP" ]; then
FLAGS="${FLAGS}NO_CPANEL_IP;"
fi
if [ -n "$DOCROOT" ] && [ ! -d "$DOCROOT" ]; then
FLAGS="${FLAGS}DOCROOT_MISSING;"
fi
PUB_A="$(dig +time="$DIG_TIMEOUT" +tries=1 +short A "$D" @"$RESOLVER" 2>/dev/null | grep -E '^[0-9.]+' | paste -sd, -)"
PUB_AAAA="$(dig +time="$DIG_TIMEOUT" +tries=1 +short AAAA "$D" @"$RESOLVER" 2>/dev/null | grep ':' | paste -sd, -)"
if [ -z "$PUB_A" ]; then
FLAGS="${FLAGS}NO_PUBLIC_A;"
fi
if [ -n "$CPIP" ] && [ -n "$PUB_A" ] && ! echo "$PUB_A" | tr ',' '\n' | grep -qx "$CPIP"; then
FLAGS="${FLAGS}A_MISMATCH;"
fi
if [ -n "$PUB_AAAA" ]; then
BADAAAA=0
for IP6 in $(echo "$PUB_AAAA" | tr ',' ' '); do
if ! echo "$SERVER_IPV6S" | tr ' ' '\n' | grep -qx "$IP6"; then
BADAAAA=1
fi
done
if [ "$BADAAAA" = "1" ]; then
FLAGS="${FLAGS}WRONG_AAAA_OR_IPV6_NOT_ON_SERVER;"
else
FLAGS="${FLAGS}AAAA_PRESENT;"
fi
fi
CERTDATA="$(live_cert_info "$D")"
CERT_STATUS="$(echo "$CERTDATA" | awk -F'|' '{print $1}')"
SUBJECT="$(echo "$CERTDATA" | awk -F'|' '{print $2}')"
ISSUER="$(echo "$CERTDATA" | awk -F'|' '{print $3}')"
NOT_AFTER="$(echo "$CERTDATA" | awk -F'|' '{print $4}')"
DAYS_LEFT="$(echo "$CERTDATA" | awk -F'|' '{print $5}')"
LIVE_FP="$(echo "$CERTDATA" | awk -F'|' '{print $6}')"
HOSTCHECK="$(echo "$CERTDATA" | awk -F'|' '{print $7}')"
if [ "$CERT_STATUS" != "OK" ]; then
FLAGS="${FLAGS}HTTPS_CERT_READ_FAILED;"
else
if [ "$SUBJECT" = "$ISSUER" ]; then
FLAGS="${FLAGS}LIVE_SELF_SIGNED;"
fi
if ! echo "$ISSUER" | grep -qi "Let's Encrypt\|Sectigo\|ZeroSSL\|DigiCert\|GlobalSign"; then
FLAGS="${FLAGS}UNCOMMON_OR_UNTRUSTED_ISSUER;"
fi
if [ -n "$DAYS_LEFT" ]; then
if [ "$DAYS_LEFT" -lt 0 ]; then
FLAGS="${FLAGS}SSL_EXPIRED;"
elif [ "$DAYS_LEFT" -le 15 ]; then
FLAGS="${FLAGS}SSL_EXPIRING_WITHIN_15_DAYS;"
elif [ "$DAYS_LEFT" -le 30 ]; then
FLAGS="${FLAGS}SSL_EXPIRING_WITHIN_30_DAYS;"
fi
else
FLAGS="${FLAGS}SSL_EXPIRY_UNKNOWN;"
fi
if echo "$HOSTCHECK" | grep -qi "does NOT match"; then
FLAGS="${FLAGS}CERT_NAME_MISMATCH;"
fi
fi
STORAGE_PROBLEM="$(check_cert_storage_selfsigned "$D")"
if [ -n "$STORAGE_PROBLEM" ]; then
FLAGS="${FLAGS}${STORAGE_PROBLEM};"
fi
if [ -n "$LIVE_FP" ]; then
MATCH=0
for F in \
"/var/cpanel/ssl/apache_tls/$D/combined" \
"/var/cpanel/ssl/apache_tls/$D/certificates" \
"/var/cpanel/ssl/domain_tls/$D/combined" \
"/var/cpanel/ssl/domain_tls/$D/certificates" \
"/var/cpanel/ssl/domain_tls/www.$D/combined" \
"/var/cpanel/ssl/domain_tls/mail.$D/combined"
do
[ -f "$F" ] || continue
FP="$(openssl x509 -in "$F" -noout -fingerprint -sha256 2>/dev/null | cut -d= -f2)"
[ "$FP" = "$LIVE_FP" ] && MATCH=1
done
if [ "$MATCH" = "0" ]; then
FLAGS="${FLAGS}LIVE_CERT_NOT_MATCHING_STANDARD_CPANEL_STORAGE;"
fi
fi
CLEAN_ISSUER="$(echo "$ISSUER" | sed 's/issuer=//; s/,/ /g; s/"/'\''/g')"
CLEAN_NOT_AFTER="$(echo "$NOT_AFTER" | sed 's/,/ /g; s/"/'\''/g')"
LINE="$D,$U,$CPIP,$PUB_A,$PUB_AAAA,\"$CLEAN_ISSUER\",\"$CLEAN_NOT_AFTER\",$DAYS_LEFT,\"$FLAGS\""
echo "$LINE" >> "$CSV_ALL"
if [ -n "$FLAGS" ]; then
BAD=$((BAD+1))
echo "$LINE" >> "$CSV_BAD"
echo "ATTENTION: $D USER=$U IP=$CPIP A=$PUB_A AAAA=$PUB_AAAA DAYS_LEFT=$DAYS_LEFT FLAGS=$FLAGS"
else
OK=$((OK+1))
fi
done
echo
echo "===== GLOBAL AUTOSSL RECENT FAILURE SUMMARY ====="
if ls /var/cpanel/logs/autossl/* >/dev/null 2>&1; then
grep -RhiE "TOTAL_DCV_FAILURE|NO_SSL|Defective|failed|does not exist on this server|Network is unreachable|CAA|self signed|expired" /var/cpanel/logs/autossl 2>/dev/null | tail -150 || true
else
echo "NO_AUTOSSL_LOGS_FOUND"
fi
echo
echo "===== HTTPD / USERDATA REBUILD WARNING SUMMARY ====="
TMPREBUILD="/tmp/rsh-httpd-rebuild-$TS.log"
/scripts/updateuserdatacache --force > "$TMPREBUILD" 2>&1
/scripts/rebuildhttpdconf >> "$TMPREBUILD" 2>&1
egrep -i "missing|not found|error|failed|invalid|warning" "$TMPREBUILD" || echo "OK_NO_MAJOR_REBUILD_WARNINGS"
echo
echo "===== TOP ATTENTION FLAGS SUMMARY ====="
if [ -s "$CSV_BAD" ]; then
awk -F',' 'NR>1 {print $9}' "$CSV_BAD" | tr ';' '\n' | sed 's/"//g' | grep -v '^$' | sort | uniq -c | sort -rn
else
echo "NO_ATTENTION_DOMAINS_FOUND"
fi
echo
echo "===== ATTENTION DOMAINS REPORT ====="
if [ -s "$CSV_BAD" ]; then
column -s, -t "$CSV_BAD" 2>/dev/null | head -100 || cat "$CSV_BAD"
else
echo "NO_ATTENTION_DOMAINS_FOUND"
fi
echo
echo "===== FINAL REPORT PATHS ====="
echo "MAIN_LOG=$REPORT"
echo "ALL_DOMAINS_CSV=$CSV_ALL"
echo "ATTENTION_ONLY_CSV=$CSV_BAD"
echo
echo "To view only attention domains later, run:"
echo "cat $CSV_BAD"
echo
echo "===== REDSERVERHOST SERVER-WIDE SSL ATTENTION AUDIT END ====="
date
echo