#!/bin/sh set -x ls -la pwd whoami # Define active DuckDNS variables DUCKDNS_DOMAIN="*.fbleagh.duckdns.org" DUCKDNS_BASE="fbleagh.duckdns.org" # CONSUL_URL is set externally by Nomad: ${attr.unique.network.ip-address} # --- ACME Setup (Switching BACK to Let's Encrypt) --- # Using a specific email to register a fresh account context /usr/local/bin/acme.sh --register-account --server letsencrypt -m "admin-${DUCKDNS_BASE}@mailinator.com" /usr/local/bin/acme.sh --set-default-ca --server letsencrypt sleep 10 # --- 🎯 Dynamic Service Discovery --- SERVICES="" CHALLENGE_ALIAS_ARGS="" for service in $(curl -s "http://$CONSUL_URL:8500/v1/catalog/services" | jq -r 'to_entries[] | select(.value | index("sslcert")) | .key'); do SERVICE_DOMAIN="${service}.service.dc1.fbleagh.duckdns.org" SERVICES="$SERVICES -d $SERVICE_DOMAIN" # Correct pipe syntax for service domain alias CHALLENGE_ALIAS_ARGS="$CHALLENGE_ALIAS_ARGS --challenge-alias $SERVICE_DOMAIN|$DUCKDNS_BASE" done # Build the complete domain list for logging/reference DOMAIN_ARGS="-d $DUCKDNS_DOMAIN $SERVICES" echo "Requesting certificate for: $DOMAIN_ARGS" echo "--- Starting 2-STEP ISSUANCE (Back to Let's Encrypt) ---" # ---------------------------------------------------------------------------------- ## ➡️ STEP 1: Issue Wildcard Domain # Note: We removed the explicit alias for the wildcard to simplify the request. # The dns_duckdns hook naturally handles the root domain for the wildcard. echo "--- STEP 1: Issuing Wildcard Domain ---" /usr/local/bin/acme.sh --insecure --issue --dns dns_duckdns \ -d "$DUCKDNS_DOMAIN" \ --ecc --force --dnssleep 60 ACME_STATUS_1=$? if [ $ACME_STATUS_1 -ne 0 ]; then echo "🚨 ERROR: acme.sh STEP 1 (Wildcard) failed with exit code $ACME_STATUS_1." # If step 1 fails on Let's Encrypt, we cannot proceed. exit $ACME_STATUS_1 fi echo "✅ STEP 1 (Wildcard) completed successfully." # ---------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------- ## ➡️ STEP 2: Issue Wildcard + Service Domains echo "--- STEP 2: Issuing Wildcard + Service Domains ---" /usr/local/bin/acme.sh --insecure --issue --dns dns_duckdns \ -d "$DUCKDNS_DOMAIN" \ $SERVICES \ $CHALLENGE_ALIAS_ARGS \ --ecc --force --dnssleep 60 ACME_STATUS_2=$? if [ $ACME_STATUS_2 -ne 0 ]; then echo "🚨 ERROR: acme.sh STEP 2 (Wildcard + Services) failed with exit code $ACME_STATUS_2." exit $ACME_STATUS_2 fi echo "✅ STEP 2 (Wildcard + Services) completed successfully. Proceeding to upload." # ---------------------------------------------------------------------------------- # --- Upload to Consul --- CERT_DIR="/acme.sh/${DUCKDNS_DOMAIN}_ecc" CONSUL_KV_PATH="/v1/kv/letsconsul/${DUCKDNS_DOMAIN}" upload_to_consul () { FILE_PATH="$1" KV_KEY="$2" CURL_RESPONSE=$(curl -XPUT --data-binary "@$FILE_PATH" "http://$CONSUL_URL:8500$KV_KEY" 2>&1) if echo "$CURL_RESPONSE" | grep -q "^true$"; then echo "✅ Consul upload SUCCESS: $KV_KEY" else echo "❌ Consul upload FAILED: $KV_KEY" echo "--- Full CURL Output ---" echo "$CURL_RESPONSE" exit 1 fi } echo "Starting Consul Uploads for ${DUCKDNS_DOMAIN}..." upload_to_consul "$CERT_DIR/${DUCKDNS_DOMAIN}.key" "${CONSUL_KV_PATH}/${DUCKDNS_DOMAIN}.key" upload_to_consul "$CERT_DIR/fullchain.cer" "${CONSUL_KV_PATH}/fullchain.cer" upload_to_consul "$CERT_DIR/${DUCKDNS_DOMAIN}.cer" "${CONSUL_KV_PATH}/${DUCKDNS_DOMAIN}.cer" upload_to_consul "$CERT_DIR/ca.cer" "${CONSUL_KV_PATH}/ca.cer" # --- Verification --- echo "--- Starting Certificate and Consul Verification ---" echo "1. Checking SANs in local fullchain.cer..." if [ -f "$CERT_DIR/fullchain.cer" ]; then openssl x509 -in "$CERT_DIR/fullchain.cer" -text -noout | grep -A1 "X509v3 Subject Alternative Name" echo "✅ Local SAN check complete." else echo "❌ ERROR: fullchain.cer not found." exit 1 fi CONSUL_CHECK_KEY="${CONSUL_KV_PATH}/fullchain.cer" echo "2. Checking existence of ${CONSUL_CHECK_KEY} in Consul..." CONSUL_METADATA=$(curl -s "http://$CONSUL_URL:8500${CONSUL_CHECK_KEY}?stale&keys&index=1") CERT_VALUE_LENGTH=$(echo "$CONSUL_METADATA" | jq -r '.[0].Value' | wc -c) if [ "$CERT_VALUE_LENGTH" -gt 100 ]; then echo "✅ Consul upload verification SUCCESS." else echo "❌ Consul upload verification FAILED." exit 1 fi exit 0