Files
proxmox/scripts/list-npmplus-certificates-status.sh
defiQUG fbda1b4beb
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
docs: Ledger Live integration, contract deploy learnings, NEXT_STEPS updates
- ADD_CHAIN138_TO_LEDGER_LIVE: Ledger form done; public code review repo bis-innovations/LedgerLive; init/push commands
- CONTRACT_DEPLOYMENT_RUNBOOK: Chain 138 gas price 1 gwei, 36-addr check, TransactionMirror workaround
- CONTRACT_*: AddressMapper, MirrorManager deployed 2026-02-12; 36-address on-chain check
- NEXT_STEPS_FOR_YOU: Ledger done; steps completable now (no LAN); run-completable-tasks-from-anywhere
- MASTER_INDEX, OPERATOR_OPTIONAL, SMART_CONTRACTS_INVENTORY_SIMPLE: updates
- LEDGER_BLOCKCHAIN_INTEGRATION_COMPLETE: bis-innovations/LedgerLive reference

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 15:46:57 -08:00

201 lines
8.0 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# List all NPMplus TLS certificates with status: which should be RENEWED (expiring soon or in use with unknown expiry),
# which should be KEPT (in use, not expiring soon), and which should be REMOVED (not assigned to any proxy host).
# Uses NPM API only. Optional: set PROXMOX_HOST and NPMPLUS_VMID to fetch expiry from container cert files.
# Uses .env for NPM_URL, NPM_EMAIL, NPM_PASSWORD. See docs/04-configuration/NPMPLUS_TLS_CLEANUP.md
set -euo pipefail
# Load IP configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
# Preserve NPM credentials from environment
_orig_npm_url="${NPM_URL:-}"
_orig_npm_email="${NPM_EMAIL:-}"
_orig_npm_password="${NPM_PASSWORD:-}"
if [ -f "$PROJECT_ROOT/.env" ]; then
set +u
set -a
# shellcheck source=/dev/null
source "$PROJECT_ROOT/.env" 2>/dev/null || true
set +a
set -u
[ -n "$_orig_npm_url" ] && NPM_URL="$_orig_npm_url"
[ -n "$_orig_npm_email" ] && NPM_EMAIL="$_orig_npm_email"
[ -n "$_orig_npm_password" ] && NPM_PASSWORD="$_orig_npm_password"
fi
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; }
log_error() { echo -e "${RED}[✗]${NC} $1"; }
RENEW_DAYS="${RENEW_DAYS:-30}"
NPM_URL="${NPM_URL:-https://${IP_NPMPLUS}:81}"
NPM_EMAIL="${NPM_EMAIL:-admin@example.org}"
NPM_PASSWORD="${NPM_PASSWORD:-}"
PROXMOX_HOST="${PROXMOX_HOST:-}"
NPMPLUS_VMID="${NPMPLUS_VMID:-${NPM_VMID:-10233}}"
if [ -z "$NPM_PASSWORD" ]; then
log_error "NPM_PASSWORD is required. Set it in .env or export NPM_PASSWORD=..."
exit 1
fi
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🔒 NPMplus TLS Certificates Renew vs Remove"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# Authenticate
log_info "Authenticating to NPMplus..."
AUTH_JSON=$(jq -n --arg identity "$NPM_EMAIL" --arg secret "$NPM_PASSWORD" '{identity:$identity,secret:$secret}')
TOKEN_RESPONSE=$(curl -s -k -X POST "$NPM_URL/api/tokens" -H "Content-Type: application/json" -d "$AUTH_JSON")
TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.token // empty' 2>/dev/null || echo "")
if [ -z "$TOKEN" ] || [ "$TOKEN" = "null" ]; then
log_error "Authentication failed. Check NPM_URL, NPM_EMAIL, NPM_PASSWORD."
exit 1
fi
log_success "Authenticated"
echo ""
# Get proxy hosts certificate_id in use
log_info "Fetching proxy hosts..."
PROXY_JSON=$(curl -s -k -X GET "$NPM_URL/api/nginx/proxy-hosts" -H "Authorization: Bearer $TOKEN")
IN_USE_IDS=$(echo "$PROXY_JSON" | jq -r '[.[] | select(.certificate_id != null and .certificate_id > 0) | .certificate_id] | unique[]' 2>/dev/null || true)
echo "$IN_USE_IDS" | grep -q . || IN_USE_IDS=""
log_info "Certificate IDs in use: $(echo $IN_USE_IDS | tr '\n' ' ')"
echo ""
# Get all certificates
log_info "Fetching certificates..."
CERTS_JSON=$(curl -s -k -X GET "$NPM_URL/api/nginx/certificates" -H "Authorization: Bearer $TOKEN")
CERT_COUNT=$(echo "$CERTS_JSON" | jq 'length' 2>/dev/null || echo "0")
log_info "Total certificates: $CERT_COUNT"
echo ""
# Optional: fetch expiry from container cert files (openssl x509 -enddate)
get_expiry_from_container() {
local cert_id="$1"
if [ -z "$PROXMOX_HOST" ] || [ -z "$NPMPLUS_VMID" ]; then
echo ""
return
fi
ssh -o ConnectTimeout=3 -o StrictHostKeyChecking=accept-new root@"$PROXMOX_HOST" \
"pct exec $NPMPLUS_VMID -- openssl x509 -in /data/tls/certbot/live/npm-${cert_id}/fullchain.pem -noout -enddate 2>/dev/null | cut -d= -f2" 2>/dev/null || echo ""
}
# Table header
printf "${CYAN}%-6s %-45s %-8s %-12s %-22s %-6s${NC}\n" "ID" "Domains" "In use" "Expires" "Days left" "Action"
printf "%.0s─" $(seq 1 100)
echo ""
TO_RENEW=0
TO_KEEP=0
TO_REMOVE=0
while IFS= read -r cert; do
[ -z "$cert" ] && continue
cid=$(echo "$cert" | jq -r '.id' 2>/dev/null)
[ -z "$cid" ] || [ "$cid" = "null" ] && continue
domains=$(echo "$cert" | jq -r '.domain_names // [] | if type == "array" then join(", ") else . end' 2>/dev/null || echo "")
[ -z "$domains" ] || [ "$domains" = "null" ] && domains="(no domains)"
if [ "${#domains}" -gt 44 ]; then
domains="${domains:0:42}.."
fi
in_use="no"
echo "$IN_USE_IDS" | grep -q "^${cid}$" && in_use="yes"
# Expiry: try API first (expires_on, expiry_date, valid_to often in ms or ISO)
expiry_raw=$(echo "$cert" | jq -r '.expires_on // .expiry_date // .valid_to // empty' 2>/dev/null || echo "")
expiry_str=""
days_left=""
if [ -n "$expiry_raw" ] && [ "$expiry_raw" != "null" ]; then
if echo "$expiry_raw" | grep -qE '^[0-9]+$'; then
expiry_str=$(date -d "@$((expiry_raw / 1000))" +%Y-%m-%d 2>/dev/null) || expiry_str="$expiry_raw"
else
expiry_str=$(echo "$expiry_raw" | cut -d'T' -f1 2>/dev/null) || expiry_str="$expiry_raw"
fi
fi
if [ -z "$expiry_str" ] && [ -n "$PROXMOX_HOST" ]; then
expiry_from_file=$(get_expiry_from_container "$cid")
if [ -n "$expiry_from_file" ]; then
expiry_str=$(date -d "$expiry_from_file" +%Y-%m-%d 2>/dev/null) || expiry_str="$expiry_from_file"
fi
fi
if [ -n "$expiry_str" ]; then
expiry_ts=$(date -d "$expiry_str" +%s 2>/dev/null || echo "")
if [ -n "$expiry_ts" ]; then
now_ts=$(date +%s)
days_left=$(( (expiry_ts - now_ts) / 86400 ))
fi
fi
days_display="—"
[ -n "$days_left" ] && days_display="${days_left}"
# Action: REMOVE if not in use; RENEW if in use and (expired or < RENEW_DAYS or unknown expiry); KEEP otherwise
action="KEEP"
if [ "$in_use" = "no" ]; then
action="REMOVE"
TO_REMOVE=$((TO_REMOVE + 1))
elif [ -n "$days_left" ]; then
if [ "$days_left" -lt 0 ]; then
action="RENEW"
TO_RENEW=$((TO_RENEW + 1))
elif [ "$days_left" -lt "$RENEW_DAYS" ]; then
action="RENEW"
TO_RENEW=$((TO_RENEW + 1))
else
TO_KEEP=$((TO_KEEP + 1))
fi
else
action="RENEW?"
TO_RENEW=$((TO_RENEW + 1))
fi
printf "%-6s %-45s %-8s %-12s %-22s " "$cid" "$domains" "$in_use" "${expiry_str:---}" "$days_display"
case "$action" in
RENEW|RENEW?) echo -e "${YELLOW}$action${NC}"; ;;
REMOVE) echo -e "${RED}$action${NC}"; ;;
*) echo -e "${GREEN}$action${NC}"; ;;
esac
done < <(echo "$CERTS_JSON" | jq -c '.[]' 2>/dev/null || true)
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Summary (RENEW_DAYS=$RENEW_DAYS):"
echo " RENEW: In use and (expired / expiring within ${RENEW_DAYS} days / unknown expiry)"
echo " KEEP: In use and not expiring soon"
echo " REMOVE: Not assigned to any proxy host (inactive)"
echo ""
printf " ${YELLOW}RENEW:${NC} %s\n" "$TO_RENEW"
printf " ${GREEN}KEEP:${NC} %s\n" "$TO_KEEP"
printf " ${RED}REMOVE:${NC} %s\n" "$TO_REMOVE"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
log_info "To remove inactive certs: ./scripts/cleanup-npmplus-inactive-certificates.sh true (dry run)"
log_info " ./scripts/cleanup-npmplus-inactive-certificates.sh false (delete)"
log_info "To request/renew certs: ./scripts/request-npmplus-certificates.sh (only for hosts without a cert)"
log_info " Or request renewal in NPMplus UI per proxy host (SSL tab)."
echo ""