#!/bin/bash # Add vault.katykhin.ru → 192.168.1.103:8280 via NPM API + Access List (LAN + VPN only) # Usage: NPM_EMAIL=... NPM_PASSWORD=... ./npm-add-proxy-vault.sh # NPM credentials: Vaultwarden, объект NPM_ADMIN (username=email, password) # Run from host that can reach NPM, or: ssh root@192.168.1.150 "pct exec 100 -- bash -s" < scripts/npm-add-proxy-vault.sh # (then set NPM_URL=http://127.0.0.1:81 and NPM_EMAIL/NPM_PASSWORD in env) set -e NPM_URL="${NPM_URL:-http://192.168.1.100:81}" API="$NPM_URL/api" if [ -z "$NPM_EMAIL" ] || [ -z "$NPM_PASSWORD" ]; then echo "Set NPM_EMAIL and NPM_PASSWORD (from Vaultwarden, объект NPM_ADMIN)" exit 1 fi echo "1. Getting token..." TOKEN=$(curl -s -X POST "$API/tokens" \ -H "Content-Type: application/json" \ -d "{\"identity\":\"$NPM_EMAIL\",\"secret\":\"$NPM_PASSWORD\"}" \ | jq -r '.token // empty') if [ -z "$TOKEN" ]; then echo "Failed to get token" exit 1 fi ACCESS_LIST_ID="" echo "2. Creating access list (LAN + VPN only)..." # NPM backend may expect 0/1 for booleans; try minimal payload if 500 AL_PAYLOAD=$(jq -n \ --arg name "Vaultwarden LAN+VPN" \ '{ name: $name, satisfy_any: 0, pass_auth: 0 }') AL_RESP=$(curl -s -w "\n%{http_code}" -X POST "$API/nginx/access-lists" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d "$AL_PAYLOAD") AL_HTTP=$(echo "$AL_RESP" | tail -1) AL_BODY=$(echo "$AL_RESP" | sed '$d') if [ "$AL_HTTP" = "201" ] || [ "$AL_HTTP" = "200" ]; then ACCESS_LIST_ID=$(echo "$AL_BODY" | jq -r '.id') echo " Access list ID: $ACCESS_LIST_ID" else echo " Access list creation failed (HTTP $AL_HTTP): $AL_BODY" echo " Creating proxy without access list; add list in NPM UI and attach to this proxy." echo " In UI: Access Lists -> create 'Vaultwarden LAN+VPN', add Allow 192.168.1.0/24 and 10.10.99.0/24, then set it on vault.katykhin.ru proxy." fi # NPM API may not expose adding IP allow items via API; add 192.168.1.0/24 and 10.10.99.0/24 in UI. echo "3. Finding certificate for vault.katykhin.ru..." CERT_ID=$(curl -s -H "Authorization: Bearer $TOKEN" "$API/nginx/certificates" \ | jq -r '.[] | select(.domain_names[]? == "vault.katykhin.ru") | .id' | head -1) if [ -z "$CERT_ID" ] || [ "$CERT_ID" = "null" ]; then echo " Certificate not found in NPM. Adding from custom_ssl/npm-18..." CERT_DIR="/opt/docker/nginx-proxy/data/custom_ssl/npm-18" if [ -f "$CERT_DIR/fullchain.pem" ] && [ -f "$CERT_DIR/privkey.pem" ]; then CERT_ESC=$(jq -Rs . < "$CERT_DIR/fullchain.pem") KEY_ESC=$(jq -Rs . < "$CERT_DIR/privkey.pem") CERT_RESP=$(curl -s -w "\n%{http_code}" -X POST "$API/nginx/certificates" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d "{\"provider\":\"other\",\"domain_names\":[\"vault.katykhin.ru\"],\"nice_name\":\"vault.katykhin.ru\",\"meta\":{\"certificate\":$CERT_ESC,\"certificate_key\":$KEY_ESC}}") CERT_HTTP=$(echo "$CERT_RESP" | tail -1) CERT_BODY=$(echo "$CERT_RESP" | sed '$d') if [ "$CERT_HTTP" = "201" ]; then CERT_ID=$(echo "$CERT_BODY" | jq -r '.id') echo " Certificate added, ID: $CERT_ID" else echo " Failed to add certificate (HTTP $CERT_HTTP): $CERT_BODY" CERT_ID="" fi else echo " Skip: no cert files in $CERT_DIR (run from inside CT 100)" fi fi echo "4. Creating proxy host vault.katykhin.ru -> 192.168.1.103:8280..." PROXY_PAYLOAD=$(jq -n \ --arg cert "$CERT_ID" \ --arg alid "$ACCESS_LIST_ID" \ '{ domain_names: ["vault.katykhin.ru"], forward_host: "192.168.1.103", forward_port: "8280", forward_scheme: "http", enabled: true, allow_websocket_upgrade: true, http2_support: true, block_exploits: true, certificate_id: (if $cert != "" and $cert != "null" then ($cert | tonumber) else null end), ssl_forced: ($cert != "" and $cert != "null"), access_list_id: (if $alid != "" and $alid != "null" then ($alid | tonumber) else 0 end) }') RESP=$(curl -s -w "\n%{http_code}" -X POST "$API/nginx/proxy-hosts" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d "$PROXY_PAYLOAD") HTTP_CODE=$(echo "$RESP" | tail -1) BODY=$(echo "$RESP" | sed '$d') if [ "$HTTP_CODE" = "201" ]; then echo "Proxy host created: https://vault.katykhin.ru -> 192.168.1.103:8280 (Access List: LAN + VPN)" echo "$BODY" | jq . else echo "Failed (HTTP $HTTP_CODE):" echo "$BODY" | jq . 2>/dev/null || echo "$BODY" exit 1 fi