Files
Sankofa/scripts/verify-proxmox-certs.sh
defiQUG 33d50fb91e
Some checks failed
API CI / API Lint (push) Successful in 47s
API CI / API Type Check (push) Failing after 47s
API CI / API Test (push) Successful in 1m0s
API CI / API Build (push) Failing after 50s
API CI / Build Docker Image (push) Has been skipped
Build Crossplane Provider / build (push) Failing after 5m51s
CD Pipeline / Deploy to Staging (push) Failing after 29s
CI Pipeline / Lint and Type Check (push) Failing after 36s
CI Pipeline / Build (push) Has been skipped
CI Pipeline / Test Backend (push) Failing after 1m33s
CI Pipeline / Test Frontend (push) Failing after 30s
CI Pipeline / Security Scan (push) Failing after 1m16s
Crossplane Provider CI / Go Test (push) Failing after 3m23s
Crossplane Provider CI / Go Lint (push) Failing after 7m27s
Crossplane Provider CI / Go Build (push) Failing after 3m27s
Deploy to Staging / Deploy to Staging (push) Failing after 30s
Portal CI / Portal Lint (push) Failing after 21s
Portal CI / Portal Type Check (push) Failing after 21s
Portal CI / Portal Test (push) Failing after 21s
Portal CI / Portal Build (push) Failing after 22s
Test Suite / frontend-tests (push) Failing after 30s
Test Suite / api-tests (push) Failing after 49s
Test Suite / blockchain-tests (push) Failing after 30s
Type Check / type-check (map[directory:. name:root]) (push) Failing after 23s
Type Check / type-check (map[directory:api name:api]) (push) Failing after 21s
Type Check / type-check (map[directory:portal name:portal]) (push) Failing after 19s
Validate Configuration Files / validate (push) Failing after 1m52s
CD Pipeline / Deploy to Production (push) Has been skipped
chore: consolidate local WIP (repo cleanup 20260707)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 09:41:34 -07:00

255 lines
6.5 KiB
Bash
Executable File

#!/bin/bash
set -euo pipefail
# Proxmox Certificate Verification Script
# Verifies ACME certificate installation and validity on Proxmox nodes
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
NODES=(
"ml110-01.sankofa.nexus:192.168.11.10"
"r630-01.sankofa.nexus:192.168.11.11"
)
PORT=8006
WARN_DAYS=30 # Warn if certificate expires in less than 30 days
log() {
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $*" >&2
}
info() {
echo -e "${GREEN}${NC} $*"
}
warn() {
echo -e "${YELLOW}${NC} $*" >&2
}
error() {
echo -e "${RED}${NC} $*" >&2
}
# Check if openssl is available
check_openssl() {
if ! command -v openssl &> /dev/null; then
error "openssl is not installed. Please install openssl to use this script."
exit 1
fi
}
# Get certificate expiration date
get_cert_expiry() {
local hostname=$1
local ip=$2
local port=$3
# Connect and extract expiration date
local expiry=$(echo | openssl s_client -connect "${ip}:${port}" -servername "${hostname}" 2>/dev/null | \
openssl x509 -noout -enddate 2>/dev/null | \
cut -d= -f2)
if [ -z "${expiry}" ]; then
return 1
fi
echo "${expiry}"
}
# Calculate days until expiration
days_until_expiry() {
local expiry_date=$1
# Convert expiry date to epoch timestamp
# Try Linux date format first, then macOS format
local expiry_epoch
if expiry_epoch=$(date -d "${expiry_date}" +%s 2>/dev/null); then
:
elif expiry_epoch=$(date -j -f "%b %d %H:%M:%S %Y %Z" "${expiry_date}" +%s 2>/dev/null); then
:
else
return 1
fi
local now_epoch=$(date +%s)
local diff=$((expiry_epoch - now_epoch))
local days=$((diff / 86400))
echo "${days}"
}
# Get certificate issuer
get_cert_issuer() {
local hostname=$1
local ip=$2
local port=$3
local issuer=$(echo | openssl s_client -connect "${ip}:${port}" -servername "${hostname}" 2>/dev/null | \
openssl x509 -noout -issuer 2>/dev/null | \
sed 's/issuer=//')
echo "${issuer}"
}
# Get certificate subject
get_cert_subject() {
local hostname=$1
local ip=$2
local port=$3
local subject=$(echo | openssl s_client -connect "${ip}:${port}" -servername "${hostname}" 2>/dev/null | \
openssl x509 -noout -subject 2>/dev/null | \
sed 's/subject=//')
echo "${subject}"
}
# Get certificate SANs (Subject Alternative Names)
get_cert_sans() {
local hostname=$1
local ip=$2
local port=$3
local sans=$(echo | openssl s_client -connect "${ip}:${port}" -servername "${hostname}" 2>/dev/null | \
openssl x509 -noout -text 2>/dev/null | \
grep -A1 "Subject Alternative Name" | \
sed 's/.*DNS://g' | \
tr ',' '\n' | \
sed 's/^ *//' | \
grep -v "^$")
echo "${sans}"
}
# Test SSL connection
test_ssl_connection() {
local hostname=$1
local ip=$2
local port=$3
# Test connection and get certificate
local output=$(echo | openssl s_client -connect "${ip}:${port}" -servername "${hostname}" 2>&1)
if echo "${output}" | grep -q "Verify return code: 0"; then
return 0
else
return 1
fi
}
# Verify certificate for a node
verify_node_cert() {
local node_info=$1
local hostname=$(echo "${node_info}" | cut -d: -f1)
local ip=$(echo "${node_info}" | cut -d: -f2)
log "Checking certificate for ${hostname} (${ip}:${PORT})..."
# Test SSL connection
if ! test_ssl_connection "${hostname}" "${ip}" "${PORT}"; then
error "SSL connection failed for ${hostname}"
return 1
fi
info "SSL connection successful"
# Get certificate details
local issuer=$(get_cert_issuer "${hostname}" "${ip}" "${PORT}")
local subject=$(get_cert_subject "${hostname}" "${ip}" "${PORT}")
local expiry=$(get_cert_expiry "${hostname}" "${ip}" "${PORT}")
if [ -z "${expiry}" ]; then
error "Could not retrieve certificate expiration for ${hostname}"
return 1
fi
# Check if certificate is from Let's Encrypt
if echo "${issuer}" | grep -qi "lets encrypt\|let's encrypt\|letsencrypt"; then
info "Certificate issuer: Let's Encrypt"
else
warn "Certificate issuer: ${issuer}"
warn "Certificate may not be from Let's Encrypt"
fi
# Display certificate subject
info "Certificate subject: ${subject}"
# Check expiration
local days=$(days_until_expiry "${expiry}")
if [ "${days}" -lt 0 ]; then
error "Certificate expired ${days#-} days ago!"
error "Expiration date: ${expiry}"
return 1
elif [ "${days}" -lt "${WARN_DAYS}" ]; then
warn "Certificate expires in ${days} days (${expiry})"
warn "Renewal should occur automatically, but please monitor"
else
info "Certificate expires in ${days} days (${expiry})"
fi
# Get and display SANs
local sans=$(get_cert_sans "${hostname}" "${ip}" "${PORT}")
if [ -n "${sans}" ]; then
info "Certificate SANs:"
echo "${sans}" | while read -r san; do
echo " - ${san}"
done
fi
# Verify hostname matches
if echo "${subject}" | grep -qi "${hostname}" || echo "${sans}" | grep -qi "${hostname}"; then
info "Hostname ${hostname} matches certificate"
else
warn "Hostname ${hostname} may not match certificate"
warn "Subject: ${subject}"
fi
echo ""
return 0
}
# Main verification function
main() {
log "Proxmox Certificate Verification Script"
log "========================================"
echo ""
check_openssl
local total_nodes=${#NODES[@]}
local passed=0
local failed=0
for node_info in "${NODES[@]}"; do
if verify_node_cert "${node_info}"; then
((passed++))
else
((failed++))
fi
done
echo ""
log "========================================"
log "Verification Summary"
log "========================================"
info "Total nodes checked: ${total_nodes}"
info "Passed: ${passed}"
if [ "${failed}" -gt 0 ]; then
error "Failed: ${failed}"
exit 1
else
info "All certificates are valid"
exit 0
fi
}
# Run main function
main "$@"