Files
proxmox/scripts/obtain-all-ssl-certificates.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

182 lines
7.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Obtain Let's Encrypt SSL certificates for all domains
# Runs certbot on VMID 105 (Nginx) for all configured domains
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
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
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"; }
PROXMOX_HOST="${PROXMOX_HOST:-192.168.11.11}"
VMID_NGINX=105
EMAIL="${SSL_EMAIL:-nsatoshi2007@hotmail.com}"
# Cloudflare credentials for DNS-01: token OR email+key (Certbot uses one method per file)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
if [ -f "$PROJECT_ROOT/.env" ]; then
set +euo pipefail
source "$PROJECT_ROOT/.env" 2>/dev/null || true
set -euo pipefail
fi
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🔒 SSL Certificate Acquisition"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
log_info "Proxmox Host: $PROXMOX_HOST"
log_info "Nginx VMID: $VMID_NGINX"
log_info "Email: $EMAIL"
echo ""
# Check if certbot is installed
log_info "Checking certbot installation..."
certbot_check=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
"pct exec $VMID_NGINX -- which certbot 2>/dev/null || echo 'not found'")
if [ "$certbot_check" = "not found" ]; then
log_warn "Certbot not found, installing..."
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
"pct exec $VMID_NGINX -- apt update && apt install -y certbot python3-certbot-nginx python3-certbot-dns-cloudflare"
else
# Ensure DNS plugin is installed
log_info "Ensuring certbot DNS plugin is installed..."
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
"pct exec $VMID_NGINX -- apt install -y python3-certbot-dns-cloudflare 2>/dev/null || true"
fi
# Setup Cloudflare credentials for DNS-01 (Certbot uses ONE method per file: token OR email+key)
if [ -z "${CLOUDFLARE_API_TOKEN:-}" ] && { [ -z "${CLOUDFLARE_EMAIL:-}" ] || [ -z "${CLOUDFLARE_API_KEY:-}" ]; }; then
log_error "Set CLOUDFLARE_API_TOKEN or (CLOUDFLARE_EMAIL + CLOUDFLARE_API_KEY) in .env"
log_info "See: docs/04-configuration/CLOUDFLARE_CREDENTIALS_BOTH_METHODS.md"
exit 1
fi
log_info "Setting up Cloudflare DNS credentials..."
if [ -n "${CLOUDFLARE_API_TOKEN:-}" ]; then
CRED_FILE=$(mktemp)
echo "dns_cloudflare_api_token = $CLOUDFLARE_API_TOKEN" > "$CRED_FILE"
elif [ -n "${CLOUDFLARE_EMAIL:-}" ] && [ -n "${CLOUDFLARE_API_KEY:-}" ]; then
CRED_FILE=$(mktemp)
echo "dns_cloudflare_email = $CLOUDFLARE_EMAIL" > "$CRED_FILE"
echo "dns_cloudflare_api_key = $CLOUDFLARE_API_KEY" >> "$CRED_FILE"
fi
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
"pct exec $VMID_NGINX -- bash -c 'mkdir -p /etc/cloudflare && cat > /etc/cloudflare/credentials.ini'" < "$CRED_FILE"
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
"pct exec $VMID_NGINX -- chmod 600 /etc/cloudflare/credentials.ini"
rm -f "$CRED_FILE"
log_success "Cloudflare credentials configured"
# Domains to obtain certificates for
DOMAINS=(
# RPC Services
"rpc.public-0138.defi-oracle.io"
"rpc-http-pub.d-bis.org"
"rpc-ws-pub.d-bis.org"
"rpc-http-prv.d-bis.org"
"rpc-ws-prv.d-bis.org"
# Explorer
"explorer.d-bis.org"
# DBIS Services
"dbis-admin.d-bis.org"
"dbis-api.d-bis.org"
"dbis-api-2.d-bis.org"
"secure.d-bis.org"
# MIM4U
"mim4u.org:www.mim4u.org"
"secure.mim4u.org"
"training.mim4u.org"
# Sankofa/Phoenix
"sankofa.nexus:www.sankofa.nexus"
"phoenix.sankofa.nexus:www.phoenix.sankofa.nexus"
"the-order.sankofa.nexus"
)
success_count=0
fail_count=0
for domain_entry in "${DOMAINS[@]}"; do
# Handle domains with multiple names (separated by :)
IFS=':' read -ra DOMAIN_ARRAY <<< "$domain_entry"
domain_list=""
primary_domain=""
for domain in "${DOMAIN_ARRAY[@]}"; do
if [ -z "$domain_list" ]; then
domain_list="$domain"
primary_domain="$domain"
else
domain_list="$domain_list -d $domain"
fi
done
log_info "Obtaining certificate for: $primary_domain"
# Try HTTP-01 first (faster if it works)
log_info " Trying HTTP-01 challenge..."
result=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
"pct exec $VMID_NGINX -- certbot --nginx -d $domain_list --non-interactive --agree-tos --email $EMAIL 2>&1" || echo "FAILED")
# If HTTP-01 fails, try DNS-01 with longer propagation time
if echo "$result" | grep -q "NXDOMAIN\|DNS problem\|Failed to authenticate\|no valid A records"; then
log_warn " HTTP-01 failed, trying DNS-01 challenge..."
result=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
"pct exec $VMID_NGINX -- certbot certonly --dns-cloudflare \
--dns-cloudflare-credentials /etc/cloudflare/credentials.ini \
--dns-cloudflare-propagation-seconds 120 \
-d $domain_list \
--non-interactive --agree-tos --email $EMAIL 2>&1" || echo "FAILED")
# If DNS-01 succeeds, update nginx config manually
if echo "$result" | grep -q "Congratulations\|Successfully"; then
log_info " Updating Nginx configuration..."
ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
"pct exec $VMID_NGINX -- certbot --nginx -d $domain_list --non-interactive --cert-name $primary_domain 2>&1" || true
fi
fi
if echo "$result" | grep -q "Congratulations\|Successfully"; then
log_success "Certificate obtained: $primary_domain"
((success_count++))
elif echo "$result" | grep -q "already exists"; then
log_warn "Certificate already exists: $primary_domain"
((success_count++))
else
log_error "Failed to obtain certificate: $primary_domain"
echo "$result" | grep -i "error\|failed" | head -3
((fail_count++))
fi
echo ""
done
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
log_info "Summary: $success_count succeeded, $fail_count failed"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
if [ $fail_count -gt 0 ]; then
log_warn "Some certificates failed - check that:"
echo " 1. DNS records point to $PUBLIC_IP"
echo " 2. ER605 NAT rule is configured"
echo " 3. Nginx is listening on port 80"
echo " 4. Port 80 is accessible from internet"
exit 1
fi