#!/usr/bin/env bash # Add NPMplus proxy hosts for Alltra/HYBX services # NPMplus Alltra/HYBX: 192.168.11.169:81 (VMID 10235) # Usage: NPM_URL=https://192.168.11.169:81 NPM_PASSWORD=xxx bash scripts/nginx-proxy-manager/update-npmplus-alltra-hybx-proxy-hosts.sh # See: docs/04-configuration/NPMPLUS_ALLTRA_HYBX_MASTER_PLAN.md set -euo pipefail 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 [ -f "$PROJECT_ROOT/.env" ] && set +u && source "$PROJECT_ROOT/.env" 2>/dev/null || true && set -u # Alltra/HYBX NPMplus: always use 192.168.11.169 (don't let .env NPM_URL override) NPMPLUS_ALLTRA_IP="${IP_NPMPLUS_ALLTRA_HYBX:-192.168.11.169}" NPM_URL="https://${NPMPLUS_ALLTRA_IP}:81" NPM_EMAIL="${NPM_EMAIL:-admin@example.org}" NPM_PASSWORD="${NPM_PASSWORD:-}" if [ -z "$NPM_PASSWORD" ]; then echo "Set NPM_PASSWORD. Get from: ssh root@192.168.11.11 'pct exec 10235 -- cat /opt/.npm_pwd 2>/dev/null'" exit 1 fi echo "Adding proxy hosts to NPMplus Alltra/HYBX at $NPM_URL..." # Authenticate (some NPM 2 instances return only {expires} and set token in cookie) COOKIE_JAR="/tmp/npm_alltra_cookies_$$" cleanup_cookies() { rm -f "$COOKIE_JAR"; } trap cleanup_cookies EXIT 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" -c "$COOKIE_JAR") TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.token // .accessToken // .access_token // .data.token // empty' 2>/dev/null) # If no token in body but response has "expires", auth succeeded via cookie (NPM 2 style) USE_COOKIE_AUTH=0 if [ -z "$TOKEN" ] || [ "$TOKEN" = "null" ]; then if echo "$TOKEN_RESPONSE" | jq -e '.expires' >/dev/null 2>&1; then USE_COOKIE_AUTH=1 echo "Using cookie-based auth (NPM 2 style)." else echo "Authentication failed" MSG=$(echo "$TOKEN_RESPONSE" | jq -r '.message // .error // .error.message // empty' 2>/dev/null) [ -n "$MSG" ] && echo "API: $MSG" KEYS=$(echo "$TOKEN_RESPONSE" | jq -r 'keys | join(", ")' 2>/dev/null) [ -n "$KEYS" ] && echo "Response keys: $KEYS" exit 1 fi fi # Curl auth: Bearer token or cookie curl_auth() { if [ "$USE_COOKIE_AUTH" = "1" ]; then curl -s -k -b "$COOKIE_JAR" "$@" else curl -s -k -H "Authorization: Bearer $TOKEN" "$@" fi } add_proxy_host() { local domain=$1 local fwd_host=$2 local fwd_port=$3 local ws=${4:-false} local payload payload=$(jq -n \ --arg domain "$domain" \ --arg host "$fwd_host" \ --argjson port "$fwd_port" \ --argjson ws "$ws" \ '{ domain_names: [$domain], forward_scheme: "http", forward_host: $host, forward_port: $port, allow_websocket_upgrade: $ws, block_exploits: false, certificate_id: null, ssl_forced: false }') local resp resp=$(curl_auth -X POST "$NPM_URL/api/nginx/proxy-hosts" \ -H "Content-Type: application/json" \ -d "$payload") local id id=$(echo "$resp" | jq -r '.id // empty' 2>/dev/null) if [ -n "$id" ] && [ "$id" != "null" ]; then echo " Added: $domain -> $fwd_host:$fwd_port" return 0 else echo " Skip (may exist): $domain - $(echo "$resp" | jq -r '.message // .error // "unknown"' 2>/dev/null)" return 1 fi } # Update existing proxy host to set block_exploits: false (fixes 405 on JSON-RPC POST to /) # NPM 2 PUT accepts only specific fields; try minimal payload and blockCommonExploits (camelCase) update_block_exploits() { local domain=$1 local fwd_host=$2 local fwd_port=$3 local ws=${4:-false} local hosts_json hosts_json=$(curl_auth -X GET "$NPM_URL/api/nginx/proxy-hosts") local id id=$(echo "$hosts_json" | jq -r ".[] | select(.domain_names | type == \"array\") | select(.domain_names[] == \"$domain\") | .id" 2>/dev/null | head -n1) if [ -z "$id" ] || [ "$id" = "null" ]; then return 1; fi # Minimal payload (NPM 2 rejects "additional properties") local payload payload=$(jq -n \ --arg scheme "http" --arg host "$fwd_host" --argjson port "$fwd_port" --argjson ws "$ws" \ '{ forward_scheme: $scheme, forward_host: $host, forward_port: $port, allow_websocket_upgrade: $ws, block_exploits: false }') local resp resp=$(curl_auth -X PUT "$NPM_URL/api/nginx/proxy-hosts/$id" \ -H "Content-Type: application/json" \ -d "$payload") local out_id out_id=$(echo "$resp" | jq -r '.id // empty' 2>/dev/null) if [ -n "$out_id" ] && [ "$out_id" != "null" ]; then echo " Updated block_exploits=false: $domain" return 0 fi # NPM 2 may use camelCase: blockCommonExploits payload=$(jq -n \ --arg scheme "http" --arg host "$fwd_host" --argjson port "$fwd_port" --argjson ws "$ws" \ '{ forward_scheme: $scheme, forward_host: $host, forward_port: $port, allow_websocket_upgrade: $ws, blockCommonExploits: false }') resp=$(curl_auth -X PUT "$NPM_URL/api/nginx/proxy-hosts/$id" -H "Content-Type: application/json" -d "$payload") out_id=$(echo "$resp" | jq -r '.id // empty' 2>/dev/null) if [ -n "$out_id" ] && [ "$out_id" != "null" ]; then echo " Updated blockCommonExploits=false: $domain" return 0 fi echo " Warning: could not set block_exploits false via API for $domain. Turn off 'Block Common Exploits' in NPM UI (Advanced) for this proxy host." return 1 } # Add or fix Alltra/HYBX + Nathan core-2 proxy hosts (third NPMplus = 76.53.10.38 → 192.168.11.169) # RPC hosts must have block_exploits false or POST to / returns 405 add_proxy_host "rpc-core-2.d-bis.org" "192.168.11.212" 8545 true || true add_proxy_host "rpc-alltra.d-bis.org" "192.168.11.172" 8545 true || true add_proxy_host "rpc-alltra-2.d-bis.org" "192.168.11.173" 8545 true || true add_proxy_host "rpc-alltra-3.d-bis.org" "192.168.11.174" 8545 true || true add_proxy_host "rpc-hybx.d-bis.org" "192.168.11.246" 8545 true || true add_proxy_host "rpc-hybx-2.d-bis.org" "192.168.11.247" 8545 true || true add_proxy_host "rpc-hybx-3.d-bis.org" "192.168.11.248" 8545 true || true add_proxy_host "cacti-alltra.d-bis.org" "192.168.11.177" 80 false || true add_proxy_host "cacti-hybx.d-bis.org" "192.168.11.251" 80 false || true # Firefly (Alltra: 6202-6203 @ .175,.176; HYBX: 6204-6205 @ .249,.250) — port 80 typical for web UI add_proxy_host "firefly-alltra-1.d-bis.org" "192.168.11.175" 80 false || true add_proxy_host "firefly-alltra-2.d-bis.org" "192.168.11.176" 80 false || true add_proxy_host "firefly-hybx-1.d-bis.org" "192.168.11.249" 80 false || true add_proxy_host "firefly-hybx-2.d-bis.org" "192.168.11.250" 80 false || true # Fabric / Indy (Alltra: 6001,6401 @ .178,.179; HYBX: 6002,6402 @ .252,.253) — port 80 or adjust in NPM UI add_proxy_host "fabric-alltra.d-bis.org" "192.168.11.178" 80 false || true add_proxy_host "indy-alltra.d-bis.org" "192.168.11.179" 80 false || true add_proxy_host "fabric-hybx.d-bis.org" "192.168.11.252" 80 false || true add_proxy_host "indy-hybx.d-bis.org" "192.168.11.253" 80 false || true echo "Ensuring block_exploits=false for RPC hosts (fixes 405 on JSON-RPC POST)..." update_block_exploits "rpc-core-2.d-bis.org" "192.168.11.212" 8545 true || true update_block_exploits "rpc-alltra.d-bis.org" "192.168.11.172" 8545 true || true update_block_exploits "rpc-alltra-2.d-bis.org" "192.168.11.173" 8545 true || true update_block_exploits "rpc-alltra-3.d-bis.org" "192.168.11.174" 8545 true || true update_block_exploits "rpc-hybx.d-bis.org" "192.168.11.246" 8545 true || true update_block_exploits "rpc-hybx-2.d-bis.org" "192.168.11.247" 8545 true || true update_block_exploits "rpc-hybx-3.d-bis.org" "192.168.11.248" 8545 true || true echo "" echo "Done. Request Let's Encrypt certs in NPMplus UI for each domain."