#!/bin/bash # Configure Let's Encrypt SSL Certificate for explorer.d-bis.org in NPMplus # Uses credentials from .env file set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" ROOT_ENV="$(cd "$PROJECT_ROOT/.." && pwd)/.env" # Source .env files (try root first, then project) if [ -f "$ROOT_ENV" ]; then set +euo pipefail source "$ROOT_ENV" 2>/dev/null || true set -euo pipefail fi if [ -f "$PROJECT_ROOT/.env" ]; then set +euo pipefail source "$PROJECT_ROOT/.env" 2>/dev/null || true set -euo pipefail fi # NPMplus configuration NPM_URL="${NPM_URL:-https://192.168.11.167:81}" NPM_EMAIL="${NPM_EMAIL:-nsatoshi2007@hotmail.com}" # NPMplus uses hashed passwords - try hash from script if plain password doesn't work NPM_PASSWORD="${NPM_PASSWORD:-}" NPM_PASSWORD_HASH="${NPM_PASSWORD_HASH:-ce8219e321e1cd97bd590fb792d3caeb7e2e3b94ca7e20124acaf253f911ff72}" # Domain to configure DOMAIN="explorer.d-bis.org" EMAIL="${NPM_EMAIL}" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' echo "==========================================" echo "Configure Let's Encrypt Certificate" echo "==========================================" echo "" echo "Domain: $DOMAIN" echo "Email: $EMAIL" echo "NPMplus URL: $NPM_URL" echo "" # Check if password is set if [ -z "$NPM_PASSWORD" ]; then echo -e "${RED}❌ NPM_PASSWORD not found in .env${NC}" echo "" echo "Please set NPM_PASSWORD in $PROJECT_ROOT/.env" echo "Example: NPM_PASSWORD=your-password-hash" exit 1 fi # Step 1: Authenticate to NPMplus echo -e "${BLUE}Step 1: Authenticating to NPMplus...${NC}" # Try plain password first, then hash if that fails AUTH_SECRET="$NPM_PASSWORD" if [ -z "$AUTH_SECRET" ]; then AUTH_SECRET="$NPM_PASSWORD_HASH" fi # Get token from cookie header (NPMplus returns token in Set-Cookie header) TOKEN_RESPONSE=$(curl -s -k -i -X POST "$NPM_URL/api/tokens" \ -H "Content-Type: application/json" \ -d "{\"identity\":\"$NPM_EMAIL\",\"secret\":\"$AUTH_SECRET\"}" 2>/dev/null || echo "") TOKEN=$(echo "$TOKEN_RESPONSE" | grep -i "set-cookie:" | grep -o "token=[^;]*" | cut -d'=' -f2 || echo "") # If plain password failed, try hash if [ -z "$TOKEN" ]; then if [ "$AUTH_SECRET" != "$NPM_PASSWORD_HASH" ] && [ -n "$NPM_PASSWORD_HASH" ]; then echo -e "${YELLOW}Plain password failed, trying hash...${NC}" TOKEN_RESPONSE=$(curl -s -k -i -X POST "$NPM_URL/api/tokens" \ -H "Content-Type: application/json" \ -d "{\"identity\":\"$NPM_EMAIL\",\"secret\":\"$NPM_PASSWORD_HASH\"}" 2>/dev/null || echo "") TOKEN=$(echo "$TOKEN_RESPONSE" | grep -i "set-cookie:" | grep -o "token=[^;]*" | cut -d'=' -f2 || echo "") fi fi if [ -z "$TOKEN" ] || [ "$TOKEN" = "null" ]; then ERROR_MSG=$(echo "$TOKEN_RESPONSE" | jq -r '.error.message // "Unknown error"' 2>/dev/null || echo "$TOKEN_RESPONSE") echo -e "${RED}❌ Failed to authenticate: $ERROR_MSG${NC}" echo "" echo "Please verify:" echo " - NPM_EMAIL is correct: $NPM_EMAIL" echo " - NPM_PASSWORD is correct (tried both plain and hash)" echo " - NPMplus is accessible at: $NPM_URL" exit 1 fi echo -e "${GREEN}✅ Authenticated successfully${NC}" echo "" # Step 2: Get proxy host ID for explorer.d-bis.org echo -e "${BLUE}Step 2: Finding proxy host for $DOMAIN...${NC}" PROXY_HOSTS=$(curl -s -k -X GET "$NPM_URL/api/nginx/proxy-hosts" \ -H "Cookie: token=$TOKEN" 2>/dev/null || echo "[]") PROXY_HOST_ID=$(echo "$PROXY_HOSTS" | jq -r ".[] | select(.domain_names[]? == \"$DOMAIN\") | .id" 2>/dev/null | head -1) if [ -z "$PROXY_HOST_ID" ]; then echo -e "${RED}❌ Proxy host for $DOMAIN not found${NC}" echo "" echo "Available proxy hosts:" echo "$PROXY_HOSTS" | jq -r '.[] | " - \(.domain_names | join(", ")) (ID: \(.id))"' 2>/dev/null || echo " (none found)" exit 1 fi echo -e "${GREEN}✅ Found proxy host ID: $PROXY_HOST_ID${NC}" echo "" # Step 3: Check if certificate already exists echo -e "${BLUE}Step 3: Checking for existing certificate...${NC}" CERTIFICATES=$(curl -s -k -X GET "$NPM_URL/api/nginx/certificates" \ -H "Authorization: Bearer $TOKEN" 2>/dev/null || echo "[]") EXISTING_CERT=$(echo "$CERTIFICATES" | jq -r ".[] | select(.friendly_name == \"$DOMAIN\" or (.domains[]? == \"$DOMAIN\")) | .id" 2>/dev/null | head -1) if [ -n "$EXISTING_CERT" ]; then echo -e "${YELLOW}⚠️ Certificate already exists (ID: $EXISTING_CERT)${NC}" echo "Using existing certificate..." CERT_ID="$EXISTING_CERT" else # Step 4: Create Let's Encrypt certificate echo -e "${BLUE}Step 4: Creating Let's Encrypt certificate...${NC}" CERT_DATA=$(jq -n \ --arg domain "$DOMAIN" \ --arg email "$EMAIL" \ '{ "provider": "letsencrypt", "domain_names": [$domain], "meta": { "letsencrypt_agree": true, "letsencrypt_email": $email }, "friendly_name": $domain }') CERT_RESPONSE=$(curl -s -k -X POST "$NPM_URL/api/nginx/certificates" \ -H "Cookie: token=$TOKEN" \ -H "Content-Type: application/json" \ -d "$CERT_DATA" 2>/dev/null || echo "{}") CERT_ID=$(echo "$CERT_RESPONSE" | jq -r '.id // empty' 2>/dev/null || echo "") if [ -z "$CERT_ID" ] || [ "$CERT_ID" = "null" ]; then ERROR_MSG=$(echo "$CERT_RESPONSE" | jq -r '.error.message // "Unknown error"' 2>/dev/null || echo "$CERT_RESPONSE") echo -e "${RED}❌ Failed to create certificate: $ERROR_MSG${NC}" exit 1 fi echo -e "${GREEN}✅ Certificate created (ID: $CERT_ID)${NC}" echo "Waiting for certificate issuance (this may take 1-2 minutes)..." # Wait for certificate to be issued MAX_WAIT=120 WAITED=0 while [ $WAITED -lt $MAX_WAIT ]; do sleep 5 WAITED=$((WAITED + 5)) CERT_STATUS=$(curl -s -k -X GET "$NPM_URL/api/nginx/certificates/$CERT_ID" \ -H "Authorization: Bearer $TOKEN" 2>/dev/null | jq -r '.meta.letsencrypt_email // empty' 2>/dev/null || echo "") if [ -n "$CERT_STATUS" ]; then echo -e "${GREEN}✅ Certificate issued successfully${NC}" break fi echo -n "." done echo "" fi # Step 5: Assign certificate to proxy host echo -e "${BLUE}Step 5: Assigning certificate to proxy host...${NC}" # Get current proxy host configuration PROXY_HOST=$(curl -s -k -X GET "$NPM_URL/api/nginx/proxy-hosts/$PROXY_HOST_ID" \ -H "Cookie: token=$TOKEN" 2>/dev/null || echo "{}") # Update proxy host with certificate UPDATE_DATA=$(echo "$PROXY_HOST" | jq \ --arg cert_id "$CERT_ID" \ '{ "domain_names": .domain_names, "forward_scheme": .forward_scheme, "forward_host": .forward_host, "forward_port": .forward_port, "forward_path": .forward_path, "ssl_certificate_id": ($cert_id | tonumber), "ssl_forced": true, "http2_support": true, "hsts_enabled": true, "hsts_subdomains": false, "access_list_id": .access_list_id, "block_exploits": .block_exploits, "caching_enabled": .caching_enabled, "websockets_support": .websockets_support }') UPDATE_RESPONSE=$(curl -s -k -X PUT "$NPM_URL/api/nginx/proxy-hosts/$PROXY_HOST_ID" \ -H "Cookie: token=$TOKEN" \ -H "Content-Type: application/json" \ -d "$UPDATE_DATA" 2>/dev/null || echo "{}") if echo "$UPDATE_RESPONSE" | jq -e '.id' >/dev/null 2>&1; then echo -e "${GREEN}✅ Certificate assigned to proxy host${NC}" echo -e "${GREEN}✅ SSL forced enabled${NC}" echo -e "${GREEN}✅ HTTP/2 support enabled${NC}" echo -e "${GREEN}✅ HSTS enabled${NC}" else ERROR_MSG=$(echo "$UPDATE_RESPONSE" | jq -r '.error.message // "Unknown error"' 2>/dev/null || echo "$UPDATE_RESPONSE") echo -e "${RED}❌ Failed to assign certificate: $ERROR_MSG${NC}" exit 1 fi echo "" echo "==========================================" echo "Configuration Complete!" echo "==========================================" echo "" echo "Summary:" echo " - Domain: $DOMAIN" echo " - Certificate ID: $CERT_ID" echo " - Proxy Host ID: $PROXY_HOST_ID" echo " - SSL Forced: Enabled" echo " - HTTP/2: Enabled" echo " - HSTS: Enabled" echo "" echo "Test the configuration:" echo " curl -I https://$DOMAIN" echo ""